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