]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/control.cpp
Swap client data pointers in wxRearrangeList too.
[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/gtk/private.h"
24#include "wx/utils.h"
25#include "wx/sysopt.h"
26
27#include "wx/gtk/private/mnemonics.h"
28
29// ============================================================================
30// wxControl implementation
31// ============================================================================
32
33// ----------------------------------------------------------------------------
34// wxControl creation
35// ----------------------------------------------------------------------------
36
37IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
38
39wxControl::wxControl()
40{
41}
42
43bool wxControl::Create( wxWindow *parent,
44 wxWindowID id,
45 const wxPoint &pos,
46 const wxSize &size,
47 long style,
48 const wxValidator& validator,
49 const wxString &name )
50{
51 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
52
53#if wxUSE_VALIDATORS
54 SetValidator(validator);
55#endif
56
57 return ret;
58}
59
60wxSize wxControl::DoGetBestSize() const
61{
62 // Do not return any arbitrary default value...
63 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
64
65 wxSize best;
66 if (m_wxwindow)
67 {
68 // this is not a native control, size_request is likely to be (0,0)
69 best = wxControlBase::DoGetBestSize();
70 }
71 else
72 {
73 GtkRequisition req;
74 GTK_WIDGET_GET_CLASS(m_widget)->size_request(m_widget, &req);
75 best.Set(req.width, req.height);
76 }
77 CacheBestSize(best);
78 return best;
79}
80
81void wxControl::PostCreation(const wxSize& size)
82{
83 wxWindow::PostCreation();
84
85 // NB: GetBestSize needs to know the style, otherwise it will assume
86 // default font and if the user uses a different font, determined
87 // best size will be different (typically, smaller) than the desired
88 // size. This call ensure that a style is available at the time
89 // GetBestSize is called.
90 gtk_widget_ensure_style(m_widget);
91
92 GTKApplyWidgetStyle();
93 SetInitialSize(size);
94}
95
96// ----------------------------------------------------------------------------
97// Work around a GTK+ bug whereby button is insensitive after being
98// enabled
99// ----------------------------------------------------------------------------
100
101// Fix sensitivity due to bug in GTK+ < 2.14
102void wxControl::GTKFixSensitivity(bool onlyIfUnderMouse)
103{
104 if (gtk_check_version(2,14,0)
105#if wxUSE_SYSTEM_OPTIONS
106 && (wxSystemOptions::GetOptionInt(wxT("gtk.control.disable-sensitivity-fix")) != 1)
107#endif
108 )
109 {
110 wxPoint pt = wxGetMousePosition();
111 wxRect rect(ClientToScreen(wxPoint(0, 0)), GetSize());
112 if (!onlyIfUnderMouse || rect.Contains(pt))
113 {
114 Hide();
115 Show();
116 }
117 }
118}
119
120// ----------------------------------------------------------------------------
121// wxControl dealing with labels
122// ----------------------------------------------------------------------------
123
124void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
125{
126 // save the original label
127 wxControlBase::SetLabel(label);
128
129 const wxString labelGTK = GTKConvertMnemonics(label);
130 gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
131}
132
133void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label)
134{
135 const wxString labelGTK = GTKConvertMnemonicsWithMarkup(label);
136 gtk_label_set_markup_with_mnemonic(w, wxGTK_CONV(labelGTK));
137}
138
139
140// ----------------------------------------------------------------------------
141// GtkFrame helpers
142//
143// GtkFrames do in fact support mnemonics in GTK2+ but not through
144// gtk_frame_set_label, rather you need to use a custom label widget
145// instead (idea gleaned from the native gtk font dialog code in GTK)
146// ----------------------------------------------------------------------------
147
148GtkWidget* wxControl::GTKCreateFrame(const wxString& label)
149{
150 const wxString labelGTK = GTKConvertMnemonics(label);
151 GtkWidget* labelwidget = gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK));
152 gtk_widget_show(labelwidget); // without this it won't show...
153
154 GtkWidget* framewidget = gtk_frame_new(NULL);
155 gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
156
157 return framewidget; // note that the label is already set so you'll
158 // only need to call wxControl::SetLabel afterwards
159}
160
161void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
162{
163 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
164 GTKSetLabelForLabel(labelwidget, label);
165}
166
167void wxControl::GTKFrameApplyWidgetStyle(GtkFrame* w, GtkRcStyle* style)
168{
169 gtk_widget_modify_style(GTK_WIDGET(w), style);
170 gtk_widget_modify_style(gtk_frame_get_label_widget (w), style);
171}
172
173void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
174{
175 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
176
177 gtk_label_set_mnemonic_widget(labelwidget, widget);
178}
179
180// ----------------------------------------------------------------------------
181// worker function implementing GTK*Mnemonics() functions
182// ----------------------------------------------------------------------------
183
184/* static */
185wxString wxControl::GTKRemoveMnemonics(const wxString& label)
186{
187 return wxGTKRemoveMnemonics(label);
188}
189
190/* static */
191wxString wxControl::GTKConvertMnemonics(const wxString& label)
192{
193 return wxConvertMnemonicsToGTK(label);
194}
195
196/* static */
197wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
198{
199 return wxConvertMnemonicsToGTKMarkup(label);
200}
201
202// ----------------------------------------------------------------------------
203// wxControl styles (a.k.a. attributes)
204// ----------------------------------------------------------------------------
205
206wxVisualAttributes wxControl::GetDefaultAttributes() const
207{
208 return GetDefaultAttributesFromGTKWidget(m_widget,
209 UseGTKStyleBase());
210}
211
212// static
213wxVisualAttributes
214wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
215 bool useBase,
216 int state)
217{
218 GtkStyle* style;
219 wxVisualAttributes attr;
220
221 style = gtk_rc_get_style(widget);
222 if (!style)
223 style = gtk_widget_get_default_style();
224
225 if (!style)
226 {
227 return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL);
228 }
229
230 if (state == -1)
231 state = GTK_STATE_NORMAL;
232
233 // get the style's colours
234 attr.colFg = wxColour(style->fg[state]);
235 if (useBase)
236 attr.colBg = wxColour(style->base[state]);
237 else
238 attr.colBg = wxColour(style->bg[state]);
239
240 // get the style's font
241 if ( !style->font_desc )
242 style = gtk_widget_get_default_style();
243 if ( style && style->font_desc )
244 {
245 wxNativeFontInfo info;
246 info.description = pango_font_description_copy(style->font_desc);
247 attr.font = wxFont(info);
248 }
249 else
250 {
251 GtkSettings *settings = gtk_settings_get_default();
252 gchar *font_name = NULL;
253 g_object_get ( settings,
254 "gtk-font-name",
255 &font_name,
256 NULL);
257 if (!font_name)
258 attr.font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
259 else
260 attr.font = wxFont(wxString::FromAscii(font_name));
261 g_free (font_name);
262 }
263
264 return attr;
265}
266
267
268//static
269wxVisualAttributes
270wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
271 bool useBase,
272 int state)
273{
274 wxVisualAttributes attr;
275 // NB: we need toplevel window so that GTK+ can find the right style
276 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
277 GtkWidget* widget = widget_new();
278 gtk_container_add(GTK_CONTAINER(wnd), widget);
279 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
280 gtk_widget_destroy(wnd);
281 return attr;
282}
283
284//static
285wxVisualAttributes
286wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
287 bool useBase,
288 int state)
289{
290 wxVisualAttributes attr;
291 // NB: we need toplevel window so that GTK+ can find the right style
292 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
293 GtkWidget* widget = widget_new("");
294 gtk_container_add(GTK_CONTAINER(wnd), widget);
295 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
296 gtk_widget_destroy(wnd);
297 return attr;
298}
299
300
301//static
302wxVisualAttributes
303wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
304 bool useBase,
305 int state)
306{
307 wxVisualAttributes attr;
308 // NB: we need toplevel window so that GTK+ can find the right style
309 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
310 GtkWidget* widget = widget_new(NULL);
311 gtk_container_add(GTK_CONTAINER(wnd), widget);
312 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
313 gtk_widget_destroy(wnd);
314 return attr;
315}
316
317// ----------------------------------------------------------------------------
318// idle handling
319// ----------------------------------------------------------------------------
320
321void wxControl::OnInternalIdle()
322{
323 if ( GTKShowFromOnIdle() )
324 return;
325
326 if ( wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen() )
327 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
328}
329
330#endif // wxUSE_CONTROLS