1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Vadim Zeitlin
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #include "wx/control.h"
18 #include "wx/fontutil.h"
19 #include "wx/settings.h"
20 #include "wx/gtk/private.h"
22 //-----------------------------------------------------------------------------
24 //-----------------------------------------------------------------------------
26 IMPLEMENT_DYNAMIC_CLASS(wxControl
, wxWindow
)
28 wxControl
::wxControl()
33 bool wxControl
::Create( wxWindow
*parent
,
38 const wxValidator
& validator
,
39 const wxString
&name
)
41 bool ret
= wxWindow
::Create(parent
, id
, pos
, size
, style
, name
);
44 SetValidator(validator
);
50 wxSize wxControl
::DoGetBestSize() const
52 // Do not return any arbitrary default value...
53 wxASSERT_MSG( m_widget
, wxT("DoGetBestSize called before creation") );
58 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget
) )->size_request
)
61 wxSize
best(req
.width
, req
.height
);
67 void wxControl
::PostCreation(const wxSize
& size
)
69 wxWindow
::PostCreation();
71 // NB: GetBestSize needs to know the style, otherwise it will assume
72 // default font and if the user uses a different font, determined
73 // best size will be different (typically, smaller) than the desired
74 // size. This call ensure that a style is available at the time
75 // GetBestSize is called.
76 gtk_widget_ensure_style(m_widget
);
79 SetInitialBestSize(size
);
82 // ----------------------------------------------------------------------------
83 // wxControl dealing with labels
84 // ----------------------------------------------------------------------------
86 void wxControl
::SetLabel( const wxString
&label
)
88 // keep the original string internally to be able to return it later (for
89 // consistency with the other ports)
95 wxString wxControl
::GetLabel() const
100 void wxControl
::GTKSetLabelForLabel(GtkLabel
*w
, const wxString
& label
)
102 // don't call the virtual function which might call this one back again
103 wxControl
::SetLabel(label
);
105 const wxString labelGTK
= GTKConvertMnemonics(label
);
108 gtk_label_set_text_with_mnemonic(w
, wxGTK_CONV(labelGTK
));
110 gtk_label_set(w
, wxGTK_CONV(labelGTK
));
114 void wxControl
::GTKSetLabelForFrame(GtkFrame
*w
, const wxString
& label
)
116 wxControl
::SetLabel(label
);
118 // frames don't support mnemonics even under GTK+ 2
119 const wxString labelGTK
= GTKRemoveMnemonics(label
);
121 gtk_frame_set_label(w
, labelGTK
.empty() ?
(char *)NULL
122 : wxGTK_CONV(labelGTK
));
125 // worker function implementing both GTKConvert/RemoveMnemonics()
127 // notice that under GTK+ 1 we only really need to support MNEMONICS_REMOVE as
128 // it doesn't support mnemonics anyhow but this would make the code so ugly
129 // that we do the same thing for GKT+ 1 and 2
136 static wxString
GTKProcessMnemonics(const wxString
& label
, MnemonicsFlag flag
)
138 const size_t len
= label
.length();
140 labelGTK
.reserve(len
);
141 for ( size_t i
= 0; i
< len
; i
++ )
143 wxChar ch
= label
[i
];
150 // "&" at the end of string is an error
151 wxLogDebug(wxT("Invalid label \"%s\"."), label
.c_str());
155 ch
= label
[++i
]; // skip '&' itself
159 // special case: "&&" is not a mnemonic at all but just
161 labelGTK
+= wxT('&');
165 if ( flag
== MNEMONICS_CONVERT
)
167 // '_' can't be a GTK mnemonic apparently so
168 // replace it with something similar
169 labelGTK
+= wxT("_-");
175 if ( flag
== MNEMONICS_CONVERT
)
176 labelGTK
+= wxT('_');
182 if ( flag
== MNEMONICS_CONVERT
)
184 // escape any existing underlines in the string so that
185 // they don't become mnemonics accidentally
186 labelGTK
+= wxT("__");
200 wxString wxControl
::GTKRemoveMnemonics(const wxString
& label
)
202 return GTKProcessMnemonics(label
, MNEMONICS_REMOVE
);
206 wxString wxControl
::GTKConvertMnemonics(const wxString
& label
)
208 return GTKProcessMnemonics(label
, MNEMONICS_CONVERT
);
211 // ----------------------------------------------------------------------------
212 // wxControl styles (a.k.a. attributes)
213 // ----------------------------------------------------------------------------
215 wxVisualAttributes wxControl
::GetDefaultAttributes() const
217 return GetDefaultAttributesFromGTKWidget(m_widget
,
222 #define SHIFT (8*(sizeof(short int)-sizeof(char)))
226 wxControl
::GetDefaultAttributesFromGTKWidget(GtkWidget
* widget
,
231 wxVisualAttributes attr
;
233 style
= gtk_rc_get_style(widget
);
235 style
= gtk_widget_get_default_style();
239 return wxWindow
::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL
);
243 state
= GTK_STATE_NORMAL
;
245 // get the style's colours
246 attr
.colFg
= wxColour(style
->fg
[state
].red
>> SHIFT
,
247 style
->fg
[state
].green
>> SHIFT
,
248 style
->fg
[state
].blue
>> SHIFT
);
250 attr
.colBg
= wxColour(style
->base
[state
].red
>> SHIFT
,
251 style
->base
[state
].green
>> SHIFT
,
252 style
->base
[state
].blue
>> SHIFT
);
254 attr
.colBg
= wxColour(style
->bg
[state
].red
>> SHIFT
,
255 style
->bg
[state
].green
>> SHIFT
,
256 style
->bg
[state
].blue
>> SHIFT
);
258 // get the style's font
260 if ( !style
->font_desc
)
261 style
= gtk_widget_get_default_style();
262 if ( style
&& style
->font_desc
)
264 wxNativeFontInfo info
;
265 info
.description
= pango_font_description_copy(style
->font_desc
);
266 attr
.font
= wxFont(info
);
270 GtkSettings
*settings
= gtk_settings_get_default();
271 gchar
*font_name
= NULL
;
272 g_object_get ( settings
,
277 attr
.font
= wxSystemSettings
::GetFont( wxSYS_DEFAULT_GUI_FONT
);
279 attr
.font
= wxFont(wxString
::FromAscii(font_name
));
283 // TODO: isn't there a way to get a standard gtk 1.2 font?
284 attr
.font
= wxFont( 12, wxSWISS
, wxNORMAL
, wxNORMAL
);
293 wxControl
::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new
,
297 wxVisualAttributes attr
;
298 // NB: we need toplevel window so that GTK+ can find the right style
299 GtkWidget
*wnd
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
300 GtkWidget
* widget
= widget_new();
301 gtk_container_add(GTK_CONTAINER(wnd
), widget
);
302 attr
= GetDefaultAttributesFromGTKWidget(widget
, useBase
, state
);
303 gtk_widget_destroy(wnd
);
309 wxControl
::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new
,
313 wxVisualAttributes attr
;
314 // NB: we need toplevel window so that GTK+ can find the right style
315 GtkWidget
*wnd
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
316 GtkWidget
* widget
= widget_new("");
317 gtk_container_add(GTK_CONTAINER(wnd
), widget
);
318 attr
= GetDefaultAttributesFromGTKWidget(widget
, useBase
, state
);
319 gtk_widget_destroy(wnd
);
326 wxControl
::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new
,
330 wxVisualAttributes attr
;
331 // NB: we need toplevel window so that GTK+ can find the right style
332 GtkWidget
*wnd
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
333 GtkWidget
* widget
= widget_new(NULL
);
334 gtk_container_add(GTK_CONTAINER(wnd
), widget
);
335 attr
= GetDefaultAttributesFromGTKWidget(widget
, useBase
, state
);
336 gtk_widget_destroy(wnd
);
340 #endif // wxUSE_CONTROLS