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