]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/control.cpp
Allow wx parents a chance to handle events fired by non-wx children. (i.e. wxActiveX...
[wxWidgets.git] / src / gtk / control.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: control.cpp
3// Purpose:
4// Author: Robert Roebling
dbf858b5 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart and Vadim Zeitlin
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
14f355c2
VS
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
1e6feb95
VZ
13#include "wx/defs.h"
14
15#if wxUSE_CONTROLS
16
c801d85f 17#include "wx/control.h"
9d522606
RD
18#include "wx/fontutil.h"
19#include "wx/settings.h"
b2ff89d6 20#include "wx/gtk/private.h"
034be888 21
c801d85f
KB
22//-----------------------------------------------------------------------------
23// wxControl
24//-----------------------------------------------------------------------------
25
9abe166a 26IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
c801d85f 27
31528cd3 28wxControl::wxControl()
c801d85f 29{
b292e2f5 30 m_needParent = TRUE;
6de97a3b 31}
c801d85f 32
04165bec 33bool wxControl::Create( wxWindow *parent,
31528cd3
VZ
34 wxWindowID id,
35 const wxPoint &pos,
36 const wxSize &size,
37 long style,
8d772832 38 const wxValidator& validator,
04165bec 39 const wxString &name )
8d772832 40{
04165bec 41 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
b2ff89d6 42
04165bec 43#if wxUSE_VALIDATORS
8d772832 44 SetValidator(validator);
8d772832
RD
45#endif
46
04165bec
RR
47 return ret;
48}
49
f68586e5
VZ
50wxSize wxControl::DoGetBestSize() const
51{
0279e844
RR
52 // Do not return any arbitrary default value...
53 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
54
f68586e5 55 GtkRequisition req;
33720b2d
RR
56 req.width = 2;
57 req.height = 2;
2afa14f2 58 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
f68586e5
VZ
59 (m_widget, &req );
60
9f884528
RD
61 wxSize best(req.width, req.height);
62 CacheBestSize(best);
63 return best;
f68586e5
VZ
64}
65
abdeb9e7
RD
66
67void wxControl::PostCreation(const wxSize& size)
68{
69 wxWindow::PostCreation();
f40fdaa3
VS
70
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);
b2ff89d6 77
abdeb9e7
RD
78 ApplyWidgetStyle();
79 SetInitialBestSize(size);
80}
81
b2ff89d6
VZ
82// ----------------------------------------------------------------------------
83// wxControl dealing with labels
84// ----------------------------------------------------------------------------
85
86void wxControl::SetLabel( const wxString &label )
87{
88 // keep the original string internally to be able to return it later (for
89 // consistency with the other ports)
90 m_label = label;
91
92 InvalidateBestSize();
93}
94
95wxString wxControl::GetLabel() const
96{
97 return m_label;
98}
99
100void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
101{
102 // don't call the virtual function which might call this one back again
103 wxControl::SetLabel(label);
104
105 const wxString labelGTK = GTKConvertMnemonics(label);
abdeb9e7 106
393cbb8f 107#ifdef __WXGTK20__
b2ff89d6
VZ
108 gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
109#else
110 gtk_label_set(w, wxGTK_CONV(labelGTK));
111#endif
112}
113
114void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
115{
116 wxControl::SetLabel(label);
117
118 // frames don't support mnemonics even under GTK+ 2
119 const wxString labelGTK = GTKRemoveMnemonics(label);
120
121 gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
122 : wxGTK_CONV(labelGTK));
123}
124
125// worker function implementing both GTKConvert/RemoveMnemonics()
126//
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
130enum MnemonicsFlag
eaafd2f8 131{
b2ff89d6
VZ
132 MNEMONICS_REMOVE,
133 MNEMONICS_CONVERT
134};
135
136static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
137{
138 const size_t len = label.length();
139 wxString labelGTK;
140 labelGTK.reserve(len);
141 for ( size_t i = 0; i < len; i++ )
eaafd2f8 142 {
b2ff89d6
VZ
143 wxChar ch = label[i];
144
145 switch ( ch )
eaafd2f8 146 {
b2ff89d6
VZ
147 case wxT('&'):
148 if ( i == len - 1 )
149 {
150 // "&" at the end of string is an error
151 wxLogDebug(wxT("Invalid label \"%s\"."), label.c_str());
152 break;
153 }
154
155 ch = label[++i]; // skip '&' itself
156 switch ( ch )
157 {
158 case wxT('&'):
159 // special case: "&&" is not a mnemonic at all but just
160 // an escaped "&"
161 labelGTK += wxT('&');
162 break;
163
164 case wxT('_'):
165 if ( flag == MNEMONICS_CONVERT )
166 {
167 // '_' can't be a GTK mnemonic apparently so
168 // replace it with something similar
169 labelGTK += wxT("_-");
170 break;
171 }
172 //else: fall through
173
174 default:
175 if ( flag == MNEMONICS_CONVERT )
176 labelGTK += wxT('_');
177 labelGTK += ch;
178 }
179 break;
180
181 case wxT('_'):
182 if ( flag == MNEMONICS_CONVERT )
183 {
184 // escape any existing underlines in the string so that
185 // they don't become mnemonics accidentally
186 labelGTK += wxT("__");
187 break;
188 }
189 //else: fall through
190
191 default:
192 labelGTK += ch;
eaafd2f8
VS
193 }
194 }
b2ff89d6
VZ
195
196 return labelGTK;
197}
198
199/* static */
200wxString wxControl::GTKRemoveMnemonics(const wxString& label)
201{
202 return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
203}
204
205/* static */
206wxString wxControl::GTKConvertMnemonics(const wxString& label)
207{
208 return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
eaafd2f8
VS
209}
210
b2ff89d6
VZ
211// ----------------------------------------------------------------------------
212// wxControl styles (a.k.a. attributes)
213// ----------------------------------------------------------------------------
9d522606
RD
214
215wxVisualAttributes wxControl::GetDefaultAttributes() const
216{
217 return GetDefaultAttributesFromGTKWidget(m_widget,
218 UseGTKStyleBase());
219}
220
221
222#define SHIFT (8*(sizeof(short int)-sizeof(char)))
223
224// static
225wxVisualAttributes
226wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
227 bool useBase,
228 int state)
229{
230 GtkStyle* style;
231 wxVisualAttributes attr;
232
233 style = gtk_rc_get_style(widget);
234 if (!style)
235 style = gtk_widget_get_default_style();
236
237 if (!style)
238 {
239 return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL);
240 }
241
242 if (state == -1)
243 state = GTK_STATE_NORMAL;
b2ff89d6 244
9d522606
RD
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);
249 if (useBase)
250 attr.colBg = wxColour(style->base[state].red >> SHIFT,
251 style->base[state].green >> SHIFT,
252 style->base[state].blue >> SHIFT);
253 else
254 attr.colBg = wxColour(style->bg[state].red >> SHIFT,
255 style->bg[state].green >> SHIFT,
256 style->bg[state].blue >> SHIFT);
257
258 // get the style's font
259#ifdef __WXGTK20__
260 if ( !style->font_desc )
b2ff89d6 261 style = gtk_widget_get_default_style();
9d522606 262 if ( style && style->font_desc )
b2ff89d6
VZ
263 {
264 wxNativeFontInfo info;
fdf7514a 265 info.description = pango_font_description_copy(style->font_desc);
b2ff89d6
VZ
266 attr.font = wxFont(info);
267 }
268 else
269 {
9d522606
RD
270 GtkSettings *settings = gtk_settings_get_default();
271 gchar *font_name = NULL;
272 g_object_get ( settings,
b2ff89d6 273 "gtk-font-name",
9d522606
RD
274 &font_name,
275 NULL);
276 if (!font_name)
277 attr.font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
278 else
279 attr.font = wxFont(wxString::FromAscii(font_name));
280 g_free (font_name);
b2ff89d6 281 }
9d522606
RD
282#else
283 // TODO: isn't there a way to get a standard gtk 1.2 font?
284 attr.font = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
285#endif
b2ff89d6 286
9d522606
RD
287 return attr;
288}
289
290
291//static
292wxVisualAttributes
865bb325 293wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
9d522606
RD
294 bool useBase,
295 int state)
296{
297 wxVisualAttributes attr;
66d8fe77
VS
298 // NB: we need toplevel window so that GTK+ can find the right style
299 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 300 GtkWidget* widget = widget_new();
66d8fe77 301 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 302 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 303 gtk_widget_destroy(wnd);
9d522606
RD
304 return attr;
305}
306
307//static
308wxVisualAttributes
865bb325 309wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
9d522606
RD
310 bool useBase,
311 int state)
312{
313 wxVisualAttributes attr;
66d8fe77
VS
314 // NB: we need toplevel window so that GTK+ can find the right style
315 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 316 GtkWidget* widget = widget_new("");
66d8fe77 317 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 318 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 319 gtk_widget_destroy(wnd);
9d522606
RD
320 return attr;
321}
322
323
324//static
325wxVisualAttributes
865bb325 326wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
9d522606
RD
327 bool useBase,
328 int state)
329{
330 wxVisualAttributes attr;
66d8fe77
VS
331 // NB: we need toplevel window so that GTK+ can find the right style
332 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 333 GtkWidget* widget = widget_new(NULL);
66d8fe77 334 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 335 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 336 gtk_widget_destroy(wnd);
9d522606
RD
337 return attr;
338}
339
1e6feb95
VZ
340#endif // wxUSE_CONTROLS
341