]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/control.cpp
Fix deprecating warning introduced in r72446.
[wxWidgets.git] / src / gtk / control.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk/control.cpp
3// Purpose: wxControl implementation for wxGTK
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling, Julian Smart and Vadim Zeitlin
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#if wxUSE_CONTROLS
14
15#include "wx/control.h"
16
17#ifndef WX_PRECOMP
18 #include "wx/log.h"
19 #include "wx/settings.h"
20#endif
21
22#include "wx/fontutil.h"
23#include "wx/utils.h"
24#include "wx/sysopt.h"
25
26#include <gtk/gtk.h>
27#include "wx/gtk/private.h"
28#include "wx/gtk/private/mnemonics.h"
29
30// ============================================================================
31// wxControl implementation
32// ============================================================================
33
34// ----------------------------------------------------------------------------
35// wxControl creation
36// ----------------------------------------------------------------------------
37
38IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
39
40wxControl::wxControl()
41{
42}
43
44bool wxControl::Create( wxWindow *parent,
45 wxWindowID id,
46 const wxPoint &pos,
47 const wxSize &size,
48 long style,
49 const wxValidator& validator,
50 const wxString &name )
51{
52 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
53
54#if wxUSE_VALIDATORS
55 SetValidator(validator);
56#endif
57
58 return ret;
59}
60
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
76wxSize wxControl::DoGetBestSize() const
77{
78 // Do not return any arbitrary default value...
79 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
80
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;
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
102 GTK_WIDGET_GET_CLASS(m_widget)->size_request(m_widget, &req);
103#endif
104 best.Set(req.width, req.height);
105 }
106 CacheBestSize(best);
107 return best;
108}
109
110void wxControl::PostCreation(const wxSize& size)
111{
112 wxWindow::PostCreation();
113
114#ifndef __WXGTK3__
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);
121#endif
122
123 GTKApplyWidgetStyle();
124 SetInitialSize(size);
125}
126
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
133void wxControl::GTKFixSensitivity(bool WXUNUSED_IN_GTK3(onlyIfUnderMouse))
134{
135#ifndef __WXGTK3__
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 }
150#endif
151}
152
153// ----------------------------------------------------------------------------
154// wxControl dealing with labels
155// ----------------------------------------------------------------------------
156
157void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
158{
159 const wxString labelGTK = GTKConvertMnemonics(label);
160 gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
161}
162
163#if wxUSE_MARKUP
164
165void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label)
166{
167 const wxString labelGTK = GTKConvertMnemonicsWithMarkup(label);
168 gtk_label_set_markup_with_mnemonic(w, wxGTK_CONV(labelGTK));
169}
170
171#endif // wxUSE_MARKUP
172
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
190 return framewidget; // note that the label is already set so you'll
191 // only need to call wxControl::SetLabel afterwards
192}
193
194void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
195{
196 wxControlBase::SetLabel(label);
197
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{
204 GTKApplyStyle(GTK_WIDGET(w), style);
205 GTKApplyStyle(gtk_frame_get_label_widget(w), style);
206}
207
208void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
209{
210 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
211
212 gtk_label_set_mnemonic_widget(labelwidget, widget);
213}
214
215// ----------------------------------------------------------------------------
216// worker function implementing GTK*Mnemonics() functions
217// ----------------------------------------------------------------------------
218
219/* static */
220wxString wxControl::GTKRemoveMnemonics(const wxString& label)
221{
222 return wxGTKRemoveMnemonics(label);
223}
224
225/* static */
226wxString wxControl::GTKConvertMnemonics(const wxString& label)
227{
228 return wxConvertMnemonicsToGTK(label);
229}
230
231/* static */
232wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
233{
234 return wxConvertMnemonicsToGTKMarkup(label);
235}
236
237// ----------------------------------------------------------------------------
238// wxControl styles (a.k.a. attributes)
239// ----------------------------------------------------------------------------
240
241wxVisualAttributes wxControl::GetDefaultAttributes() const
242{
243 return GetDefaultAttributesFromGTKWidget(m_widget,
244 UseGTKStyleBase());
245}
246
247// static
248wxVisualAttributes
249wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
250 bool WXUNUSED_IN_GTK3(useBase),
251 int state)
252{
253 wxVisualAttributes attr;
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;
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
283 // get the style's colours
284 attr.colFg = wxColour(style->fg[state]);
285 if (useBase)
286 attr.colBg = wxColour(style->base[state]);
287 else
288 attr.colBg = wxColour(style->bg[state]);
289
290 // get the style's font
291 if ( !style->font_desc )
292 style = gtk_widget_get_default_style();
293 if ( style && style->font_desc )
294 {
295 wxNativeFontInfo info;
296 info.description = style->font_desc;
297 attr.font = wxFont(info);
298 info.description = NULL;
299 }
300#endif
301 if (!attr.font.IsOk())
302 {
303 GtkSettings *settings = gtk_settings_get_default();
304 gchar *font_name = NULL;
305 g_object_get ( settings,
306 "gtk-font-name",
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);
314 }
315
316 return attr;
317}
318
319
320//static
321wxVisualAttributes
322wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
323 bool useBase,
324 int state)
325{
326 wxVisualAttributes attr;
327 // NB: we need toplevel window so that GTK+ can find the right style
328 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
329 GtkWidget* widget = widget_new();
330 gtk_container_add(GTK_CONTAINER(wnd), widget);
331 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
332 gtk_widget_destroy(wnd);
333 return attr;
334}
335
336//static
337wxVisualAttributes
338wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
339 bool useBase,
340 int state)
341{
342 wxVisualAttributes attr;
343 // NB: we need toplevel window so that GTK+ can find the right style
344 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
345 GtkWidget* widget = widget_new("");
346 gtk_container_add(GTK_CONTAINER(wnd), widget);
347 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
348 gtk_widget_destroy(wnd);
349 return attr;
350}
351
352
353//static
354wxVisualAttributes
355wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
356 bool useBase,
357 int state)
358{
359 wxVisualAttributes attr;
360 // NB: we need toplevel window so that GTK+ can find the right style
361 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
362 GtkWidget* widget = widget_new(NULL);
363 gtk_container_add(GTK_CONTAINER(wnd), widget);
364 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
365 gtk_widget_destroy(wnd);
366 return attr;
367}
368
369#endif // wxUSE_CONTROLS