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