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