]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/settings.cpp
Split some of the recent code out to make it more reusable.
[wxWidgets.git] / src / gtk1 / 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/cmndata.h"
21 #include "wx/fontutil.h"
22
23 #include <gdk/gdk.h>
24 #include <gdk/gdkprivate.h>
25 #include <gtk/gtk.h>
26
27 #define SHIFT (8*(sizeof(short int)-sizeof(char)))
28
29 // ----------------------------------------------------------------------------
30 // wxSystemObjects
31 // ----------------------------------------------------------------------------
32
33 struct wxSystemObjects
34 {
35 wxColour m_colBtnFace,
36 m_colBtnShadow,
37 m_colBtnHighlight,
38 m_colHighlight,
39 m_colHighlightText,
40 m_colListBox,
41 m_colBtnText,
42 m_colMenuItemHighlight;
43
44 wxFont m_fontSystem;
45 };
46
47 static wxSystemObjects gs_objects;
48
49 // ----------------------------------------------------------------------------
50 // wxSystemSettings implementation
51 // ----------------------------------------------------------------------------
52
53 // kind of widget to use in GetColourFromGTKWidget
54 enum wxGtkWidgetType
55 {
56 wxGTK_BUTTON,
57 wxGTK_LIST,
58 wxGTK_MENUITEM
59 };
60
61 // the colour we need
62 enum wxGtkColourType
63 {
64 wxGTK_FG,
65 wxGTK_BG,
66 wxGTK_BASE
67 };
68
69 // wxSystemSettings::GetColour() helper: get the colours from a GTK+
70 // widget style, return true if we did get them, false to use defaults
71 static bool GetColourFromGTKWidget(int& red, int& green, int& blue,
72 wxGtkWidgetType type = wxGTK_BUTTON,
73 GtkStateType state = GTK_STATE_NORMAL,
74 wxGtkColourType colour = wxGTK_BG)
75 {
76 GtkWidget *widget;
77 switch ( type )
78 {
79 default:
80 wxFAIL_MSG( _T("unexpected GTK widget type") );
81 // fall through
82
83 case wxGTK_BUTTON:
84 widget = gtk_button_new();
85 break;
86
87 case wxGTK_LIST:
88 widget = gtk_list_new();
89
90 case wxGTK_MENUITEM:
91 widget = gtk_menu_item_new();
92 }
93
94 GtkStyle *def = gtk_rc_get_style( widget );
95 if ( !def )
96 def = gtk_widget_get_default_style();
97
98 bool ok;
99 if ( def )
100 {
101 GdkColor *col;
102 switch ( colour )
103 {
104 default:
105 wxFAIL_MSG( _T("unexpected GTK colour type") );
106 // fall through
107
108 case wxGTK_FG:
109 col = def->fg;
110 break;
111
112 case wxGTK_BG:
113 col = def->bg;
114 break;
115
116 case wxGTK_BASE:
117 col = def->base;
118 break;
119 }
120
121 red = col[state].red;
122 green = col[state].green;
123 blue = col[state].blue;
124
125 ok = TRUE;
126 }
127 else
128 {
129 ok = FALSE;
130 }
131
132 gtk_widget_destroy( widget );
133
134 return ok;
135 }
136
137 wxColour wxSystemSettingsNative::GetColour( wxSystemColour index )
138 {
139 switch (index)
140 {
141 case wxSYS_COLOUR_SCROLLBAR:
142 case wxSYS_COLOUR_BACKGROUND:
143 case wxSYS_COLOUR_INACTIVECAPTION:
144 case wxSYS_COLOUR_MENU:
145 case wxSYS_COLOUR_WINDOWFRAME:
146 case wxSYS_COLOUR_ACTIVEBORDER:
147 case wxSYS_COLOUR_INACTIVEBORDER:
148 case wxSYS_COLOUR_BTNFACE:
149 case wxSYS_COLOUR_MENUBAR:
150 case wxSYS_COLOUR_3DLIGHT:
151 if (!gs_objects.m_colBtnFace.Ok())
152 {
153 int red, green, blue;
154 if ( !GetColourFromGTKWidget(red, green, blue) )
155 {
156 red =
157 green = 0;
158 blue = 0x9c40;
159 }
160
161 gs_objects.m_colBtnFace = wxColour( red >> SHIFT,
162 green >> SHIFT,
163 blue >> SHIFT );
164 }
165 return gs_objects.m_colBtnFace;
166
167 case wxSYS_COLOUR_WINDOW:
168 return *wxWHITE;
169
170 case wxSYS_COLOUR_3DDKSHADOW:
171 return *wxBLACK;
172
173 case wxSYS_COLOUR_GRAYTEXT:
174 case wxSYS_COLOUR_BTNSHADOW:
175 //case wxSYS_COLOUR_3DSHADOW:
176 if (!gs_objects.m_colBtnShadow.Ok())
177 {
178 wxColour faceColour(GetColour(wxSYS_COLOUR_3DFACE));
179 gs_objects.m_colBtnShadow =
180 wxColour((unsigned char) (faceColour.Red() * 0.666),
181 (unsigned char) (faceColour.Green() * 0.666),
182 (unsigned char) (faceColour.Blue() * 0.666));
183 }
184
185 return gs_objects.m_colBtnShadow;
186
187 case wxSYS_COLOUR_3DHIGHLIGHT:
188 //case wxSYS_COLOUR_BTNHIGHLIGHT:
189 return * wxWHITE;
190
191 case wxSYS_COLOUR_HIGHLIGHT:
192 if (!gs_objects.m_colHighlight.Ok())
193 {
194 int red, green, blue;
195 if ( !GetColourFromGTKWidget(red, green, blue,
196 wxGTK_BUTTON,
197 GTK_STATE_SELECTED) )
198 {
199 red =
200 green = 0;
201 blue = 0x9c40;
202 }
203
204 gs_objects.m_colHighlight = wxColour( red >> SHIFT,
205 green >> SHIFT,
206 blue >> SHIFT );
207 }
208 return gs_objects.m_colHighlight;
209
210 case wxSYS_COLOUR_LISTBOX:
211 if (!gs_objects.m_colListBox.Ok())
212 {
213 int red, green, blue;
214 if ( GetColourFromGTKWidget(red, green, blue,
215 wxGTK_LIST,
216 GTK_STATE_NORMAL,
217 wxGTK_BASE) )
218 {
219 gs_objects.m_colListBox = wxColour( red >> SHIFT,
220 green >> SHIFT,
221 blue >> SHIFT );
222 }
223 else
224 {
225 gs_objects.m_colListBox = wxColour(*wxWHITE);
226 }
227 }
228 return gs_objects.m_colListBox;
229
230 case wxSYS_COLOUR_MENUTEXT:
231 case wxSYS_COLOUR_WINDOWTEXT:
232 case wxSYS_COLOUR_CAPTIONTEXT:
233 case wxSYS_COLOUR_INACTIVECAPTIONTEXT:
234 case wxSYS_COLOUR_BTNTEXT:
235 case wxSYS_COLOUR_INFOTEXT:
236 if (!gs_objects.m_colBtnText.Ok())
237 {
238 int red, green, blue;
239 if ( !GetColourFromGTKWidget(red, green, blue,
240 wxGTK_BUTTON,
241 GTK_STATE_NORMAL,
242 wxGTK_FG) )
243 {
244 red =
245 green =
246 blue = 0;
247 }
248
249 gs_objects.m_colBtnText = wxColour( red >> SHIFT,
250 green >> SHIFT,
251 blue >> SHIFT );
252 }
253 return gs_objects.m_colBtnText;
254
255 // this (as well as wxSYS_COLOUR_INFOTEXT above) is used for
256 // tooltip windows - Robert, please change this code to use the
257 // real GTK tooltips when/if you can (TODO)
258 case wxSYS_COLOUR_INFOBK:
259 return wxColour(255, 255, 225);
260
261 case wxSYS_COLOUR_HIGHLIGHTTEXT:
262 if (!gs_objects.m_colHighlightText.Ok())
263 {
264 wxColour hclr = GetColour(wxSYS_COLOUR_HIGHLIGHT);
265 if (hclr.Red() > 200 && hclr.Green() > 200 && hclr.Blue() > 200)
266 gs_objects.m_colHighlightText = wxColour(*wxBLACK);
267 else
268 gs_objects.m_colHighlightText = wxColour(*wxWHITE);
269 }
270 return gs_objects.m_colHighlightText;
271
272 case wxSYS_COLOUR_APPWORKSPACE:
273 return *wxWHITE; // ?
274
275 case wxSYS_COLOUR_ACTIVECAPTION:
276 case wxSYS_COLOUR_MENUHILIGHT:
277 if (!gs_objects.m_colMenuItemHighlight.Ok())
278 {
279 int red, green, blue;
280 if ( !GetColourFromGTKWidget(red, green, blue,
281 wxGTK_MENUITEM,
282 GTK_STATE_SELECTED,
283 wxGTK_BG) )
284 {
285 red =
286 green =
287 blue = 0;
288 }
289
290 gs_objects.m_colMenuItemHighlight = wxColour( red >> SHIFT,
291 green >> SHIFT,
292 blue >> SHIFT );
293 }
294 return gs_objects.m_colMenuItemHighlight;
295
296 case wxSYS_COLOUR_HOTLIGHT:
297 case wxSYS_COLOUR_GRADIENTACTIVECAPTION:
298 case wxSYS_COLOUR_GRADIENTINACTIVECAPTION:
299 // TODO
300 return *wxBLACK;
301
302 case wxSYS_COLOUR_MAX:
303 default:
304 wxFAIL_MSG( _T("unknown system colour index") );
305 }
306
307 return *wxWHITE;
308 }
309
310 wxFont wxSystemSettingsNative::GetFont( wxSystemFont index )
311 {
312 switch (index)
313 {
314 case wxSYS_OEM_FIXED_FONT:
315 case wxSYS_ANSI_FIXED_FONT:
316 case wxSYS_SYSTEM_FIXED_FONT:
317 {
318 return *wxNORMAL_FONT;
319 }
320 case wxSYS_ANSI_VAR_FONT:
321 case wxSYS_SYSTEM_FONT:
322 case wxSYS_DEVICE_DEFAULT_FONT:
323 case wxSYS_DEFAULT_GUI_FONT:
324 {
325 if (!gs_objects.m_fontSystem.Ok())
326 {
327 #ifdef __WXGTK20__
328 GtkWidget *widget = gtk_button_new();
329 GtkStyle *def = gtk_rc_get_style( widget );
330 if ( !def || !def->font_desc )
331 def = gtk_widget_get_default_style();
332 if ( def && def->font_desc )
333 {
334 wxNativeFontInfo info;
335 info.description =
336 pango_font_description_copy(def->font_desc);
337 gs_objects.m_fontSystem = wxFont(info);
338 }
339 else
340 {
341 GtkSettings *settings = gtk_settings_get_default();
342 gchar *font_name = NULL;
343 g_object_get ( settings,
344 "gtk-font-name",
345 &font_name,
346 NULL);
347 if (!font_name)
348 gs_objects.m_fontSystem = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
349 else
350 gs_objects.m_fontSystem = wxFont(wxString::FromAscii(font_name));
351 g_free (font_name);
352 }
353 gtk_widget_destroy( widget );
354 #else
355 gs_objects.m_fontSystem = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
356 #endif
357 }
358 return gs_objects.m_fontSystem;
359 }
360
361 default:
362 return wxNullFont;
363 }
364 }
365
366 int wxSystemSettingsNative::GetMetric( wxSystemMetric index )
367 {
368 switch (index)
369 {
370 case wxSYS_SCREEN_X: return gdk_screen_width();
371 case wxSYS_SCREEN_Y: return gdk_screen_height();
372 case wxSYS_HSCROLL_Y: return 15;
373 case wxSYS_VSCROLL_X: return 15;
374
375 #if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 4, 0)
376 case wxSYS_DCLICK_X:
377 case wxSYS_DCLICK_Y:
378 gint dclick_distance;
379 g_object_get(gtk_settings_get_default(), "gtk-double-click-distance", &dclick_distance, NULL);
380 return dclick_distance * 2;
381 #endif
382
383 #if defined(__WXGTK20__)
384 case wxSYS_DRAG_X:
385 case wxSYS_DRAG_Y:
386 gint drag_threshold;
387 g_object_get(gtk_settings_get_default(), "gtk-dnd-drag-threshold", &drag_threshold, NULL);
388 return drag_threshold * 2;
389 #endif
390
391 // VZ: is there any way to get the cursor size with GDK?
392 // Mart Raudsepp: Yes, there is a way to get the default cursor size for a display ever since GDK 2.4
393 #if defined(__WXGTK20__) && GTK_CHECK_VERSION(2, 4, 0)
394 case wxSYS_CURSOR_X:
395 case wxSYS_CURSOR_Y:
396 return gdk_display_get_default_cursor_size(gdk_display_get_default());
397 #else
398 case wxSYS_CURSOR_X: return 16;
399 case wxSYS_CURSOR_Y: return 16;
400 #endif
401 // MBN: ditto for icons
402 case wxSYS_ICON_X: return 32;
403 case wxSYS_ICON_Y: return 32;
404 default:
405 return -1; // metric is unknown
406 }
407 }
408
409 bool wxSystemSettingsNative::HasFeature(wxSystemFeature index)
410 {
411 switch (index)
412 {
413 case wxSYS_CAN_ICONIZE_FRAME:
414 return FALSE;
415 break;
416 case wxSYS_CAN_DRAW_FRAME_DECORATIONS:
417 return TRUE;
418 break;
419 default:
420 return FALSE;
421 }
422 }