added support for gcc precompiled headers
[wxWidgets.git] / src / gtk / settings.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: gtk/settings.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10
11 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
12 #pragma implementation "settings.h"
13 #endif
14
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
17
18 #include "wx/settings.h"
19 #include "wx/debug.h"
20 #include "wx/module.h"
21 #include "wx/cmndata.h"
22 #include "wx/fontutil.h"
23
24 #include <gdk/gdk.h>
25 #include <gdk/gdkprivate.h>
26 #include <gtk/gtk.h>
27
28 #define SHIFT (8*(sizeof(short int)-sizeof(char)))
29
30 //wxColour *g_systemWinColour = (wxColour *) NULL;
31 wxColour *g_systemBtnFaceColour = (wxColour *) NULL;
32 wxColour *g_systemBtnShadowColour = (wxColour *) NULL;
33 wxColour *g_systemBtnHighlightColour = (wxColour *) NULL;
34 wxColour *g_systemHighlightColour = (wxColour *) NULL;
35 wxColour *g_systemHighlightTextColour = (wxColour *) NULL;
36 wxColour *g_systemListBoxColour = (wxColour *) NULL;
37 wxColour *g_systemBtnTextColour = (wxColour *) NULL;
38
39 wxFont *g_systemFont = (wxFont *) NULL;
40
41 // ----------------------------------------------------------------------------
42 // wxSystemSettingsModule
43 // ----------------------------------------------------------------------------
44
45 class wxSystemSettingsModule : public wxModule
46 {
47 public:
48 bool OnInit() { return TRUE; }
49 void OnExit()
50 {
51 //delete g_systemWinColour;
52 delete g_systemBtnFaceColour;
53 delete g_systemBtnShadowColour;
54 delete g_systemBtnHighlightColour;
55 delete g_systemHighlightColour;
56 delete g_systemHighlightTextColour;
57 delete g_systemListBoxColour;
58 delete g_systemFont;
59 delete g_systemBtnTextColour;
60 }
61 DECLARE_DYNAMIC_CLASS(wxSystemSettingsModule)
62 };
63
64 IMPLEMENT_DYNAMIC_CLASS(wxSystemSettingsModule, wxModule)
65
66 // ----------------------------------------------------------------------------
67 // wxSystemSettings implementation
68 // ----------------------------------------------------------------------------
69
70 // kind of widget to use in GetColourFromGTKWidget
71 enum wxGtkWidgetType
72 {
73 wxGTK_BUTTON,
74 wxGTK_LIST
75 };
76
77 // the colour we need
78 enum wxGtkColourType
79 {
80 wxGTK_FG,
81 wxGTK_BG,
82 wxGTK_BASE
83 };
84
85 // wxSystemSettings::GetColour() helper: get the colours from a GTK+
86 // widget style, return true if we did get them, false to use defaults
87 static bool GetColourFromGTKWidget(int& red, int& green, int& blue,
88 wxGtkWidgetType type = wxGTK_BUTTON,
89 GtkStateType state = GTK_STATE_NORMAL,
90 wxGtkColourType colour = wxGTK_BG)
91 {
92 GtkWidget *widget;
93 switch ( type )
94 {
95 default:
96 wxFAIL_MSG( _T("unexpected GTK widget type") );
97 // fall through
98
99 case wxGTK_BUTTON:
100 widget = gtk_button_new();
101 break;
102
103 case wxGTK_LIST:
104 widget = gtk_list_new();
105 }
106
107 GtkStyle *def = gtk_rc_get_style( widget );
108 if ( !def )
109 def = gtk_widget_get_default_style();
110
111 bool ok;
112 if ( def )
113 {
114 GdkColor *col;
115 switch ( colour )
116 {
117 default:
118 wxFAIL_MSG( _T("unexpected GTK colour type") );
119 // fall through
120
121 case wxGTK_FG:
122 col = def->fg;
123 break;
124
125 case wxGTK_BG:
126 col = def->bg;
127 break;
128
129 case wxGTK_BASE:
130 col = def->base;
131 break;
132 }
133
134 red = col[state].red;
135 green = col[state].green;
136 blue = col[state].blue;
137
138 ok = TRUE;
139 }
140 else
141 {
142 ok = FALSE;
143 }
144
145 gtk_widget_destroy( widget );
146
147 return ok;
148 }
149
150 wxColour wxSystemSettingsNative::GetColour( wxSystemColour index )
151 {
152 switch (index)
153 {
154 case wxSYS_COLOUR_SCROLLBAR:
155 case wxSYS_COLOUR_BACKGROUND:
156 case wxSYS_COLOUR_ACTIVECAPTION:
157 case wxSYS_COLOUR_INACTIVECAPTION:
158 case wxSYS_COLOUR_MENU:
159 case wxSYS_COLOUR_WINDOWFRAME:
160 case wxSYS_COLOUR_ACTIVEBORDER:
161 case wxSYS_COLOUR_INACTIVEBORDER:
162 case wxSYS_COLOUR_BTNFACE:
163 case wxSYS_COLOUR_MENUBAR:
164 case wxSYS_COLOUR_3DLIGHT:
165 if (!g_systemBtnFaceColour)
166 {
167 int red, green, blue;
168 if ( !GetColourFromGTKWidget(red, green, blue) )
169 {
170 red =
171 green = 0;
172 blue = 0x9c40;
173 }
174
175 g_systemBtnFaceColour = new wxColour( red >> SHIFT,
176 green >> SHIFT,
177 blue >> SHIFT );
178 }
179 return *g_systemBtnFaceColour;
180
181 case wxSYS_COLOUR_WINDOW:
182 return *wxWHITE;
183
184 case wxSYS_COLOUR_3DDKSHADOW:
185 return *wxBLACK;
186
187 case wxSYS_COLOUR_GRAYTEXT:
188 case wxSYS_COLOUR_BTNSHADOW:
189 //case wxSYS_COLOUR_3DSHADOW:
190 if (!g_systemBtnShadowColour)
191 {
192 wxColour faceColour(GetColour(wxSYS_COLOUR_3DFACE));
193 g_systemBtnShadowColour =
194 new wxColour((unsigned char) (faceColour.Red() * 0.666),
195 (unsigned char) (faceColour.Green() * 0.666),
196 (unsigned char) (faceColour.Blue() * 0.666));
197 }
198
199 return *g_systemBtnShadowColour;
200
201 case wxSYS_COLOUR_3DHIGHLIGHT:
202 //case wxSYS_COLOUR_BTNHIGHLIGHT:
203 return * wxWHITE;
204 /* I think this should normally be white (JACS 8/2000)
205
206 Hmm, I'm quite sure it shouldn't ... (VZ 20.08.01)
207 if (!g_systemBtnHighlightColour)
208 {
209 g_systemBtnHighlightColour =
210 new wxColour( 0xea60 >> SHIFT,
211 0xea60 >> SHIFT,
212 0xea60 >> SHIFT );
213 }
214 return *g_systemBtnHighlightColour;
215 */
216
217 case wxSYS_COLOUR_HIGHLIGHT:
218 if (!g_systemHighlightColour)
219 {
220 int red, green, blue;
221 if ( !GetColourFromGTKWidget(red, green, blue,
222 wxGTK_BUTTON,
223 GTK_STATE_SELECTED) )
224 {
225 red =
226 green = 0;
227 blue = 0x9c40;
228 }
229
230 g_systemHighlightColour = new wxColour( red >> SHIFT,
231 green >> SHIFT,
232 blue >> SHIFT );
233 }
234 return *g_systemHighlightColour;
235
236 case wxSYS_COLOUR_LISTBOX:
237 if (!g_systemListBoxColour)
238 {
239 int red, green, blue;
240 if ( GetColourFromGTKWidget(red, green, blue,
241 wxGTK_LIST,
242 GTK_STATE_NORMAL,
243 wxGTK_BASE) )
244 {
245 g_systemListBoxColour = new wxColour( red >> SHIFT,
246 green >> SHIFT,
247 blue >> SHIFT );
248 }
249 else
250 {
251 g_systemListBoxColour = new wxColour(*wxWHITE);
252 }
253 }
254 return *g_systemListBoxColour;
255
256 case wxSYS_COLOUR_MENUTEXT:
257 case wxSYS_COLOUR_WINDOWTEXT:
258 case wxSYS_COLOUR_CAPTIONTEXT:
259 case wxSYS_COLOUR_INACTIVECAPTIONTEXT:
260 case wxSYS_COLOUR_BTNTEXT:
261 case wxSYS_COLOUR_INFOTEXT:
262 if (!g_systemBtnTextColour)
263 {
264 int red, green, blue;
265 if ( !GetColourFromGTKWidget(red, green, blue,
266 wxGTK_BUTTON,
267 GTK_STATE_NORMAL,
268 wxGTK_FG) )
269 {
270 red =
271 green =
272 blue = 0;
273 }
274
275 g_systemBtnTextColour = new wxColour( red >> SHIFT,
276 green >> SHIFT,
277 blue >> SHIFT );
278 }
279 return *g_systemBtnTextColour;
280
281 // this (as well as wxSYS_COLOUR_INFOTEXT above) is used for
282 // tooltip windows - Robert, please change this code to use the
283 // real GTK tooltips when/if you can (TODO)
284 case wxSYS_COLOUR_INFOBK:
285 return wxColour(255, 255, 225);
286
287 case wxSYS_COLOUR_HIGHLIGHTTEXT:
288 if (!g_systemHighlightTextColour)
289 {
290 wxColour hclr = GetColour(wxSYS_COLOUR_HIGHLIGHT);
291 if (hclr.Red() > 200 && hclr.Green() > 200 && hclr.Blue() > 200)
292 g_systemHighlightTextColour = new wxColour(*wxBLACK);
293 else
294 g_systemHighlightTextColour = new wxColour(*wxWHITE);
295 }
296 return *g_systemHighlightTextColour;
297
298 case wxSYS_COLOUR_APPWORKSPACE:
299 return *wxWHITE; // ?
300
301 case wxSYS_COLOUR_HOTLIGHT:
302 case wxSYS_COLOUR_GRADIENTACTIVECAPTION:
303 case wxSYS_COLOUR_GRADIENTINACTIVECAPTION:
304 case wxSYS_COLOUR_MENUHILIGHT:
305 // TODO
306 return *wxBLACK;
307
308 case wxSYS_COLOUR_MAX:
309 default:
310 wxFAIL_MSG( _T("unknown system colour index") );
311 }
312
313 return *wxWHITE;
314 }
315
316 wxFont wxSystemSettingsNative::GetFont( wxSystemFont index )
317 {
318 switch (index)
319 {
320 case wxSYS_OEM_FIXED_FONT:
321 case wxSYS_ANSI_FIXED_FONT:
322 case wxSYS_SYSTEM_FIXED_FONT:
323 {
324 return *wxNORMAL_FONT;
325 }
326 case wxSYS_ANSI_VAR_FONT:
327 case wxSYS_SYSTEM_FONT:
328 case wxSYS_DEVICE_DEFAULT_FONT:
329 case wxSYS_DEFAULT_GUI_FONT:
330 {
331 if (!g_systemFont)
332 {
333 #ifdef __WXGTK20__
334 GtkWidget *widget = gtk_button_new();
335 GtkStyle *def = gtk_rc_get_style( widget );
336 if ( !def || !def->font_desc )
337 def = gtk_widget_get_default_style();
338 if ( def && def->font_desc )
339 {
340 wxNativeFontInfo info;
341 info.description = def->font_desc;
342 g_systemFont = new wxFont(info);
343 }
344 else
345 {
346 const gchar *font_name =
347 _gtk_rc_context_get_default_font_name(gtk_settings_get_default());
348 g_systemFont = new wxFont(wxString::FromAscii(font_name));
349 }
350 gtk_widget_destroy( widget );
351 #else
352 g_systemFont = new wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
353 #endif
354 }
355 return *g_systemFont;
356 }
357
358 default:
359 return wxNullFont;
360 }
361 }
362
363 int wxSystemSettingsNative::GetMetric( wxSystemMetric index )
364 {
365 switch (index)
366 {
367 case wxSYS_SCREEN_X: return gdk_screen_width();
368 case wxSYS_SCREEN_Y: return gdk_screen_height();
369 case wxSYS_HSCROLL_Y: return 15;
370 case wxSYS_VSCROLL_X: return 15;
371
372 // VZ: is there any way to get the cursor size with GDK?
373 case wxSYS_CURSOR_X: return 16;
374 case wxSYS_CURSOR_Y: return 16;
375 // MBN: ditto for icons
376 case wxSYS_ICON_X: return 32;
377 case wxSYS_ICON_Y: return 32;
378 default:
379 wxFAIL_MSG( wxT("wxSystemSettings::GetMetric not fully implemented") );
380 return 0;
381 }
382 }
383
384 bool wxSystemSettingsNative::HasFeature(wxSystemFeature index)
385 {
386 switch (index)
387 {
388 case wxSYS_CAN_ICONIZE_FRAME:
389 return FALSE;
390 break;
391 case wxSYS_CAN_DRAW_FRAME_DECORATIONS:
392 return TRUE;
393 break;
394 default:
395 return FALSE;
396 }
397 }