]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: src/gtk/colour.cpp | |
3 | // Purpose: | |
4 | // Author: Robert Roebling | |
5 | // Id: $Id$ | |
6 | // Copyright: (c) 1998 Robert Roebling | |
7 | // Licence: wxWindows licence | |
8 | ///////////////////////////////////////////////////////////////////////////// | |
9 | ||
10 | // For compilers that support precompilation, includes "wx.h". | |
11 | #include "wx/wxprec.h" | |
12 | ||
13 | #include "wx/colour.h" | |
14 | ||
15 | #include <gdk/gdk.h> | |
16 | #include "wx/gtk/private.h" | |
17 | ||
18 | //----------------------------------------------------------------------------- | |
19 | // wxColour | |
20 | //----------------------------------------------------------------------------- | |
21 | ||
22 | class wxColourRefData : public wxGDIRefData | |
23 | { | |
24 | public: | |
25 | #ifdef __WXGTK3__ | |
26 | wxColourRefData(const GdkRGBA& gdkRGBA) | |
27 | : m_gdkRGBA(gdkRGBA) | |
28 | { | |
29 | m_gdkColor.red = guint16(gdkRGBA.red * 65535); | |
30 | m_gdkColor.green = guint16(gdkRGBA.green * 65535); | |
31 | m_gdkColor.blue = guint16(gdkRGBA.blue * 65535); | |
32 | m_alpha = wxByte(gdkRGBA.alpha * 255 + 0.5); | |
33 | } | |
34 | wxColourRefData(const GdkColor& gdkColor) | |
35 | : m_gdkColor(gdkColor) | |
36 | { | |
37 | m_gdkRGBA.red = gdkColor.red / 65535.0; | |
38 | m_gdkRGBA.green = gdkColor.green / 65535.0; | |
39 | m_gdkRGBA.blue = gdkColor.blue / 65535.0; | |
40 | m_gdkRGBA.alpha = 1; | |
41 | m_alpha = 255; | |
42 | } | |
43 | wxColourRefData(guchar red, guchar green, guchar blue, guchar alpha) | |
44 | { | |
45 | m_gdkRGBA.red = red / 255.0; | |
46 | m_gdkRGBA.green = green / 255.0; | |
47 | m_gdkRGBA.blue = blue / 255.0; | |
48 | m_gdkRGBA.alpha = alpha / 255.0; | |
49 | m_gdkColor.red = (guint16(red) << 8) + red; | |
50 | m_gdkColor.green = (guint16(green) << 8) + green; | |
51 | m_gdkColor.blue = (guint16(blue) << 8) + blue; | |
52 | m_alpha = alpha; | |
53 | } | |
54 | GdkRGBA m_gdkRGBA; | |
55 | GdkColor m_gdkColor; | |
56 | #else | |
57 | wxColourRefData(guint16 red, guint16 green, guint16 blue, wxByte alpha = 0xff) | |
58 | { | |
59 | m_color.red = | |
60 | m_red = red; | |
61 | m_color.green = | |
62 | m_green = green; | |
63 | m_color.blue = | |
64 | m_blue = blue; | |
65 | m_alpha = alpha; | |
66 | m_color.pixel = 0; | |
67 | m_colormap = NULL; | |
68 | } | |
69 | ||
70 | virtual ~wxColourRefData() | |
71 | { | |
72 | FreeColour(); | |
73 | } | |
74 | ||
75 | void FreeColour(); | |
76 | void AllocColour( GdkColormap* cmap ); | |
77 | ||
78 | GdkColor m_color; | |
79 | GdkColormap *m_colormap; | |
80 | // gdk_colormap_alloc_color may change the RGB values in m_color, so we need separate copies | |
81 | guint16 m_red; | |
82 | guint16 m_green; | |
83 | guint16 m_blue; | |
84 | #endif | |
85 | wxByte m_alpha; | |
86 | ||
87 | wxDECLARE_NO_COPY_CLASS(wxColourRefData); | |
88 | }; | |
89 | ||
90 | #ifndef __WXGTK3__ | |
91 | void wxColourRefData::FreeColour() | |
92 | { | |
93 | if (m_colormap) | |
94 | { | |
95 | gdk_colormap_free_colors(m_colormap, &m_color, 1); | |
96 | m_colormap = NULL; | |
97 | m_color.pixel = 0; | |
98 | } | |
99 | } | |
100 | ||
101 | void wxColourRefData::AllocColour( GdkColormap *cmap ) | |
102 | { | |
103 | if (m_colormap != cmap) | |
104 | { | |
105 | FreeColour(); | |
106 | ||
107 | m_color.red = m_red; | |
108 | m_color.green = m_green; | |
109 | m_color.blue = m_blue; | |
110 | if (gdk_colormap_alloc_color(cmap, &m_color, FALSE, TRUE)) | |
111 | { | |
112 | m_colormap = cmap; | |
113 | } | |
114 | } | |
115 | } | |
116 | #endif | |
117 | ||
118 | //----------------------------------------------------------------------------- | |
119 | ||
120 | #define M_COLDATA static_cast<wxColourRefData*>(m_refData) | |
121 | ||
122 | // GDK's values are in 0..65535 range, ours are in 0..255 | |
123 | #define SHIFT 8 | |
124 | ||
125 | #ifdef __WXGTK3__ | |
126 | wxColour::wxColour(const GdkRGBA& gdkRGBA) | |
127 | { | |
128 | m_refData = new wxColourRefData(gdkRGBA); | |
129 | } | |
130 | ||
131 | wxColour::wxColour(const GdkColor& gdkColor) | |
132 | { | |
133 | m_refData = new wxColourRefData(gdkColor); | |
134 | } | |
135 | #else | |
136 | wxColour::wxColour(const GdkColor& gdkColor) | |
137 | { | |
138 | m_refData = new wxColourRefData(gdkColor.red, gdkColor.green, gdkColor.blue); | |
139 | } | |
140 | #endif | |
141 | ||
142 | wxColour::~wxColour() | |
143 | { | |
144 | } | |
145 | ||
146 | bool wxColour::operator == ( const wxColour& col ) const | |
147 | { | |
148 | if (m_refData == col.m_refData) | |
149 | return true; | |
150 | ||
151 | if (!m_refData || !col.m_refData) | |
152 | return false; | |
153 | ||
154 | wxColourRefData* refData = M_COLDATA; | |
155 | wxColourRefData* that_refData = static_cast<wxColourRefData*>(col.m_refData); | |
156 | #ifdef __WXGTK3__ | |
157 | return refData->m_gdkColor.red == that_refData->m_gdkColor.red && | |
158 | refData->m_gdkColor.green == that_refData->m_gdkColor.green && | |
159 | refData->m_gdkColor.blue == that_refData->m_gdkColor.blue && | |
160 | #else | |
161 | return refData->m_red == that_refData->m_red && | |
162 | refData->m_green == that_refData->m_green && | |
163 | refData->m_blue == that_refData->m_blue && | |
164 | #endif | |
165 | refData->m_alpha == that_refData->m_alpha; | |
166 | } | |
167 | ||
168 | void wxColour::InitRGBA(unsigned char red, unsigned char green, unsigned char blue, | |
169 | unsigned char alpha) | |
170 | { | |
171 | UnRef(); | |
172 | ||
173 | #ifdef __WXGTK3__ | |
174 | m_refData = new wxColourRefData(red, green, blue, alpha); | |
175 | #else | |
176 | m_refData = new wxColourRefData( | |
177 | (guint16(red) << SHIFT) + red, | |
178 | (guint16(green) << SHIFT) + green, | |
179 | (guint16(blue) << SHIFT) + blue, | |
180 | alpha); | |
181 | #endif | |
182 | } | |
183 | ||
184 | unsigned char wxColour::Red() const | |
185 | { | |
186 | wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") ); | |
187 | ||
188 | #ifdef __WXGTK3__ | |
189 | return wxByte(M_COLDATA->m_gdkColor.red >> 8); | |
190 | #else | |
191 | return wxByte(M_COLDATA->m_red >> SHIFT); | |
192 | #endif | |
193 | } | |
194 | ||
195 | unsigned char wxColour::Green() const | |
196 | { | |
197 | wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") ); | |
198 | ||
199 | #ifdef __WXGTK3__ | |
200 | return wxByte(M_COLDATA->m_gdkColor.green >> 8); | |
201 | #else | |
202 | return wxByte(M_COLDATA->m_green >> SHIFT); | |
203 | #endif | |
204 | } | |
205 | ||
206 | unsigned char wxColour::Blue() const | |
207 | { | |
208 | wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") ); | |
209 | ||
210 | #ifdef __WXGTK3__ | |
211 | return wxByte(M_COLDATA->m_gdkColor.blue >> 8); | |
212 | #else | |
213 | return wxByte(M_COLDATA->m_blue >> SHIFT); | |
214 | #endif | |
215 | } | |
216 | ||
217 | unsigned char wxColour::Alpha() const | |
218 | { | |
219 | wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") ); | |
220 | ||
221 | return M_COLDATA->m_alpha; | |
222 | } | |
223 | ||
224 | #ifndef __WXGTK3__ | |
225 | void wxColour::CalcPixel( GdkColormap *cmap ) | |
226 | { | |
227 | if (!IsOk()) return; | |
228 | ||
229 | M_COLDATA->AllocColour( cmap ); | |
230 | } | |
231 | ||
232 | int wxColour::GetPixel() const | |
233 | { | |
234 | wxCHECK_MSG( IsOk(), 0, wxT("invalid colour") ); | |
235 | ||
236 | return M_COLDATA->m_color.pixel; | |
237 | } | |
238 | #endif | |
239 | ||
240 | const GdkColor *wxColour::GetColor() const | |
241 | { | |
242 | wxCHECK_MSG( IsOk(), NULL, wxT("invalid colour") ); | |
243 | ||
244 | #ifdef __WXGTK3__ | |
245 | return &M_COLDATA->m_gdkColor; | |
246 | #else | |
247 | return &M_COLDATA->m_color; | |
248 | #endif | |
249 | } | |
250 | ||
251 | #ifdef __WXGTK3__ | |
252 | wxColour::operator const GdkRGBA*() const | |
253 | { | |
254 | const GdkRGBA* c = NULL; | |
255 | if (IsOk()) | |
256 | c = &M_COLDATA->m_gdkRGBA; | |
257 | return c; | |
258 | } | |
259 | #endif | |
260 | ||
261 | bool wxColour::FromString(const wxString& str) | |
262 | { | |
263 | #ifdef __WXGTK3__ | |
264 | GdkRGBA gdkRGBA; | |
265 | if (gdk_rgba_parse(&gdkRGBA, wxGTK_CONV_SYS(str))) | |
266 | { | |
267 | *this = wxColour(gdkRGBA); | |
268 | return true; | |
269 | } | |
270 | #else | |
271 | GdkColor colGDK; | |
272 | if ( gdk_color_parse( wxGTK_CONV_SYS( str ), &colGDK ) ) | |
273 | { | |
274 | *this = wxColour(colGDK); | |
275 | return true; | |
276 | } | |
277 | #endif | |
278 | ||
279 | return wxColourBase::FromString(str); | |
280 | } |