]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/control.cpp
Remove wxT from prototype
[wxWidgets.git] / src / gtk / control.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
634fb750
VZ
2// Name: src/gtk/control.cpp
3// Purpose: wxControl implementation for wxGTK
c801d85f 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#if wxUSE_CONTROLS
14
c801d85f 15#include "wx/control.h"
e4db172a
WS
16
17#ifndef WX_PRECOMP
18 #include "wx/log.h"
9eddec69 19 #include "wx/settings.h"
e4db172a
WS
20#endif
21
9d522606 22#include "wx/fontutil.h"
ad60f9e7
JS
23#include "wx/utils.h"
24#include "wx/sysopt.h"
034be888 25
9dc44eff
PC
26#include <gtk/gtk.h>
27#include "wx/gtk/private.h"
b1f17bf0 28#include "wx/gtk/private/mnemonics.h"
39bc0347 29
634fb750
VZ
30// ============================================================================
31// wxControl implementation
32// ============================================================================
33
34// ----------------------------------------------------------------------------
35// wxControl creation
36// ----------------------------------------------------------------------------
c801d85f 37
9abe166a 38IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
c801d85f 39
31528cd3 40wxControl::wxControl()
c801d85f 41{
6de97a3b 42}
c801d85f 43
04165bec 44bool wxControl::Create( wxWindow *parent,
31528cd3
VZ
45 wxWindowID id,
46 const wxPoint &pos,
47 const wxSize &size,
48 long style,
8d772832 49 const wxValidator& validator,
04165bec 50 const wxString &name )
8d772832 51{
04165bec 52 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
b2ff89d6 53
04165bec 54#if wxUSE_VALIDATORS
8d772832 55 SetValidator(validator);
8d772832
RD
56#endif
57
04165bec
RR
58 return ret;
59}
60
9dc44eff
PC
61#ifdef __WXGTK3__
62bool wxControl::SetFont(const wxFont& font)
63{
64 const bool changed = base_type::SetFont(font);
65 if (changed && !gtk_widget_get_realized(m_widget))
66 {
67 // GTK defers sending "style-updated" until widget is realized, but
68 // GetBestSize() won't compute correct result until the signal is sent,
69 // so we have to do it now
70 g_signal_emit_by_name(m_widget, "style-updated");
71 }
72 return changed;
73}
74#endif
75
f68586e5
VZ
76wxSize wxControl::DoGetBestSize() const
77{
0279e844
RR
78 // Do not return any arbitrary default value...
79 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
80
50bedb7b
PC
81 wxSize best;
82 if (m_wxwindow)
83 {
84 // this is not a native control, size_request is likely to be (0,0)
85 best = wxControlBase::DoGetBestSize();
86 }
87 else
88 {
89 GtkRequisition req;
9dc44eff
PC
90#ifdef __WXGTK3__
91 if (gtk_widget_get_request_mode(m_widget) != GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
92 {
93 gtk_widget_get_preferred_height(m_widget, NULL, &req.height);
94 gtk_widget_get_preferred_width_for_height(m_widget, req.height, NULL, &req.width);
95 }
96 else
97 {
98 gtk_widget_get_preferred_width(m_widget, NULL, &req.width);
99 gtk_widget_get_preferred_height_for_width(m_widget, req.width, NULL, &req.height);
100 }
101#else
50bedb7b 102 GTK_WIDGET_GET_CLASS(m_widget)->size_request(m_widget, &req);
9dc44eff 103#endif
50bedb7b
PC
104 best.Set(req.width, req.height);
105 }
9f884528
RD
106 CacheBestSize(best);
107 return best;
f68586e5
VZ
108}
109
abdeb9e7
RD
110void wxControl::PostCreation(const wxSize& size)
111{
112 wxWindow::PostCreation();
f40fdaa3 113
9dc44eff 114#ifndef __WXGTK3__
f40fdaa3
VS
115 // NB: GetBestSize needs to know the style, otherwise it will assume
116 // default font and if the user uses a different font, determined
117 // best size will be different (typically, smaller) than the desired
118 // size. This call ensure that a style is available at the time
119 // GetBestSize is called.
120 gtk_widget_ensure_style(m_widget);
9dc44eff 121#endif
b2ff89d6 122
496e7ec6 123 GTKApplyWidgetStyle();
170acdc9 124 SetInitialSize(size);
abdeb9e7
RD
125}
126
ad60f9e7
JS
127// ----------------------------------------------------------------------------
128// Work around a GTK+ bug whereby button is insensitive after being
129// enabled
130// ----------------------------------------------------------------------------
131
132// Fix sensitivity due to bug in GTK+ < 2.14
9dc44eff 133void wxControl::GTKFixSensitivity(bool WXUNUSED_IN_GTK3(onlyIfUnderMouse))
ad60f9e7 134{
9dc44eff 135#ifndef __WXGTK3__
ad60f9e7
JS
136 if (gtk_check_version(2,14,0)
137#if wxUSE_SYSTEM_OPTIONS
138 && (wxSystemOptions::GetOptionInt(wxT("gtk.control.disable-sensitivity-fix")) != 1)
139#endif
140 )
141 {
142 wxPoint pt = wxGetMousePosition();
143 wxRect rect(ClientToScreen(wxPoint(0, 0)), GetSize());
144 if (!onlyIfUnderMouse || rect.Contains(pt))
145 {
146 Hide();
147 Show();
148 }
149 }
9dc44eff 150#endif
ad60f9e7
JS
151}
152
b2ff89d6
VZ
153// ----------------------------------------------------------------------------
154// wxControl dealing with labels
155// ----------------------------------------------------------------------------
156
39bc0347 157void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
b2ff89d6 158{
39bc0347
VZ
159 const wxString labelGTK = GTKConvertMnemonics(label);
160 gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
b2ff89d6
VZ
161}
162
f5bdfc69
VZ
163#if wxUSE_MARKUP
164
39bc0347 165void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label)
b2ff89d6 166{
39bc0347
VZ
167 const wxString labelGTK = GTKConvertMnemonicsWithMarkup(label);
168 gtk_label_set_markup_with_mnemonic(w, wxGTK_CONV(labelGTK));
b2ff89d6
VZ
169}
170
f5bdfc69 171#endif // wxUSE_MARKUP
b2ff89d6 172
2e1f5012
VZ
173// ----------------------------------------------------------------------------
174// GtkFrame helpers
175//
176// GtkFrames do in fact support mnemonics in GTK2+ but not through
177// gtk_frame_set_label, rather you need to use a custom label widget
178// instead (idea gleaned from the native gtk font dialog code in GTK)
179// ----------------------------------------------------------------------------
180
181GtkWidget* wxControl::GTKCreateFrame(const wxString& label)
182{
183 const wxString labelGTK = GTKConvertMnemonics(label);
184 GtkWidget* labelwidget = gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK));
185 gtk_widget_show(labelwidget); // without this it won't show...
186
187 GtkWidget* framewidget = gtk_frame_new(NULL);
188 gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
189
39bc0347
VZ
190 return framewidget; // note that the label is already set so you'll
191 // only need to call wxControl::SetLabel afterwards
2e1f5012
VZ
192}
193
b2ff89d6
VZ
194void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
195{
6ea2bc50
VZ
196 wxControlBase::SetLabel(label);
197
2e1f5012
VZ
198 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
199 GTKSetLabelForLabel(labelwidget, label);
200}
201
202void wxControl::GTKFrameApplyWidgetStyle(GtkFrame* w, GtkRcStyle* style)
203{
9dc44eff
PC
204 GTKApplyStyle(GTK_WIDGET(w), style);
205 GTKApplyStyle(gtk_frame_get_label_widget(w), style);
2e1f5012 206}
b2ff89d6 207
2e1f5012
VZ
208void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
209{
210 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
b2ff89d6 211
2e1f5012 212 gtk_label_set_mnemonic_widget(labelwidget, widget);
b2ff89d6
VZ
213}
214
2e1f5012 215// ----------------------------------------------------------------------------
39bc0347 216// worker function implementing GTK*Mnemonics() functions
2e1f5012
VZ
217// ----------------------------------------------------------------------------
218
b2ff89d6
VZ
219/* static */
220wxString wxControl::GTKRemoveMnemonics(const wxString& label)
221{
b1f17bf0 222 return wxGTKRemoveMnemonics(label);
b2ff89d6
VZ
223}
224
225/* static */
226wxString wxControl::GTKConvertMnemonics(const wxString& label)
227{
b1f17bf0 228 return wxConvertMnemonicsToGTK(label);
eaafd2f8
VS
229}
230
39bc0347
VZ
231/* static */
232wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
233{
b1f17bf0 234 return wxConvertMnemonicsToGTKMarkup(label);
39bc0347
VZ
235}
236
b2ff89d6
VZ
237// ----------------------------------------------------------------------------
238// wxControl styles (a.k.a. attributes)
239// ----------------------------------------------------------------------------
9d522606
RD
240
241wxVisualAttributes wxControl::GetDefaultAttributes() const
242{
243 return GetDefaultAttributesFromGTKWidget(m_widget,
244 UseGTKStyleBase());
245}
246
9d522606
RD
247// static
248wxVisualAttributes
249wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
9dc44eff 250 bool WXUNUSED_IN_GTK3(useBase),
9d522606
RD
251 int state)
252{
9d522606 253 wxVisualAttributes attr;
9dc44eff
PC
254#ifdef __WXGTK3__
255 GtkStateFlags stateFlag = GTK_STATE_FLAG_NORMAL;
256 if (state)
257 {
258 wxASSERT(state == GTK_STATE_ACTIVE);
259 stateFlag = GTK_STATE_FLAG_ACTIVE;
260 }
261 GtkStyleContext* sc = gtk_widget_get_style_context(widget);
262 GdkRGBA c;
263 gtk_style_context_get_color(sc, stateFlag, &c);
264 attr.colFg = wxColour(c);
265 gtk_style_context_get_background_color(sc, stateFlag, &c);
266 attr.colBg = wxColour(c);
267 wxNativeFontInfo info;
268 info.description = const_cast<PangoFontDescription*>(gtk_style_context_get_font(sc, stateFlag));
269 attr.font = wxFont(info);
270 info.description = NULL;
271#else
272 GtkStyle* style;
9d522606
RD
273
274 style = gtk_rc_get_style(widget);
275 if (!style)
276 style = gtk_widget_get_default_style();
277
278 if (!style)
279 {
280 return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL);
281 }
282
9d522606 283 // get the style's colours
cdf068a4 284 attr.colFg = wxColour(style->fg[state]);
9d522606 285 if (useBase)
cdf068a4 286 attr.colBg = wxColour(style->base[state]);
9d522606 287 else
cdf068a4 288 attr.colBg = wxColour(style->bg[state]);
9d522606
RD
289
290 // get the style's font
9d522606 291 if ( !style->font_desc )
b2ff89d6 292 style = gtk_widget_get_default_style();
9d522606 293 if ( style && style->font_desc )
b2ff89d6
VZ
294 {
295 wxNativeFontInfo info;
622226dc 296 info.description = style->font_desc;
b2ff89d6 297 attr.font = wxFont(info);
622226dc 298 info.description = NULL;
b2ff89d6 299 }
9dc44eff
PC
300#endif
301 if (!attr.font.IsOk())
b2ff89d6 302 {
9d522606
RD
303 GtkSettings *settings = gtk_settings_get_default();
304 gchar *font_name = NULL;
305 g_object_get ( settings,
b2ff89d6 306 "gtk-font-name",
9d522606
RD
307 &font_name,
308 NULL);
309 if (!font_name)
310 attr.font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
311 else
312 attr.font = wxFont(wxString::FromAscii(font_name));
313 g_free (font_name);
b2ff89d6 314 }
b2ff89d6 315
9d522606
RD
316 return attr;
317}
318
319
320//static
321wxVisualAttributes
865bb325 322wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
9d522606
RD
323 bool useBase,
324 int state)
325{
326 wxVisualAttributes attr;
66d8fe77
VS
327 // NB: we need toplevel window so that GTK+ can find the right style
328 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 329 GtkWidget* widget = widget_new();
66d8fe77 330 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 331 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 332 gtk_widget_destroy(wnd);
9d522606
RD
333 return attr;
334}
335
336//static
337wxVisualAttributes
865bb325 338wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
9d522606
RD
339 bool useBase,
340 int state)
341{
342 wxVisualAttributes attr;
66d8fe77
VS
343 // NB: we need toplevel window so that GTK+ can find the right style
344 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 345 GtkWidget* widget = widget_new("");
66d8fe77 346 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 347 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 348 gtk_widget_destroy(wnd);
9d522606
RD
349 return attr;
350}
351
352
353//static
354wxVisualAttributes
865bb325 355wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
9d522606
RD
356 bool useBase,
357 int state)
358{
359 wxVisualAttributes attr;
66d8fe77
VS
360 // NB: we need toplevel window so that GTK+ can find the right style
361 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 362 GtkWidget* widget = widget_new(NULL);
66d8fe77 363 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 364 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 365 gtk_widget_destroy(wnd);
9d522606
RD
366 return attr;
367}
368
1e6feb95 369#endif // wxUSE_CONTROLS