]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/control.cpp
No changes, just add a couple of #if wxUSE_COMMANDLINKBUTTON tests.
[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"
b2ff89d6 23#include "wx/gtk/private.h"
ad60f9e7
JS
24#include "wx/utils.h"
25#include "wx/sysopt.h"
034be888 26
b1f17bf0 27#include "wx/gtk/private/mnemonics.h"
39bc0347 28
634fb750
VZ
29// ============================================================================
30// wxControl implementation
31// ============================================================================
32
33// ----------------------------------------------------------------------------
34// wxControl creation
35// ----------------------------------------------------------------------------
c801d85f 36
9abe166a 37IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
c801d85f 38
31528cd3 39wxControl::wxControl()
c801d85f 40{
6de97a3b 41}
c801d85f 42
04165bec 43bool wxControl::Create( wxWindow *parent,
31528cd3
VZ
44 wxWindowID id,
45 const wxPoint &pos,
46 const wxSize &size,
47 long style,
8d772832 48 const wxValidator& validator,
04165bec 49 const wxString &name )
8d772832 50{
04165bec 51 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
b2ff89d6 52
04165bec 53#if wxUSE_VALIDATORS
8d772832 54 SetValidator(validator);
8d772832
RD
55#endif
56
04165bec
RR
57 return ret;
58}
59
f68586e5
VZ
60wxSize wxControl::DoGetBestSize() const
61{
0279e844
RR
62 // Do not return any arbitrary default value...
63 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
64
50bedb7b
PC
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 }
9f884528
RD
77 CacheBestSize(best);
78 return best;
f68586e5
VZ
79}
80
abdeb9e7
RD
81void wxControl::PostCreation(const wxSize& size)
82{
83 wxWindow::PostCreation();
f40fdaa3
VS
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);
b2ff89d6 91
496e7ec6 92 GTKApplyWidgetStyle();
170acdc9 93 SetInitialSize(size);
abdeb9e7
RD
94}
95
ad60f9e7
JS
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
b2ff89d6
VZ
120// ----------------------------------------------------------------------------
121// wxControl dealing with labels
122// ----------------------------------------------------------------------------
123
39bc0347 124void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
b2ff89d6 125{
39bc0347
VZ
126 const wxString labelGTK = GTKConvertMnemonics(label);
127 gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
b2ff89d6
VZ
128}
129
39bc0347 130void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel *w, const wxString& label)
b2ff89d6 131{
39bc0347
VZ
132 const wxString labelGTK = GTKConvertMnemonicsWithMarkup(label);
133 gtk_label_set_markup_with_mnemonic(w, wxGTK_CONV(labelGTK));
b2ff89d6
VZ
134}
135
b2ff89d6 136
2e1f5012
VZ
137// ----------------------------------------------------------------------------
138// GtkFrame helpers
139//
140// GtkFrames do in fact support mnemonics in GTK2+ but not through
141// gtk_frame_set_label, rather you need to use a custom label widget
142// instead (idea gleaned from the native gtk font dialog code in GTK)
143// ----------------------------------------------------------------------------
144
145GtkWidget* wxControl::GTKCreateFrame(const wxString& label)
146{
147 const wxString labelGTK = GTKConvertMnemonics(label);
148 GtkWidget* labelwidget = gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK));
149 gtk_widget_show(labelwidget); // without this it won't show...
150
151 GtkWidget* framewidget = gtk_frame_new(NULL);
152 gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
153
39bc0347
VZ
154 return framewidget; // note that the label is already set so you'll
155 // only need to call wxControl::SetLabel afterwards
2e1f5012
VZ
156}
157
b2ff89d6
VZ
158void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
159{
6ea2bc50
VZ
160 wxControlBase::SetLabel(label);
161
2e1f5012
VZ
162 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
163 GTKSetLabelForLabel(labelwidget, label);
164}
165
166void wxControl::GTKFrameApplyWidgetStyle(GtkFrame* w, GtkRcStyle* style)
167{
168 gtk_widget_modify_style(GTK_WIDGET(w), style);
169 gtk_widget_modify_style(gtk_frame_get_label_widget (w), style);
170}
b2ff89d6 171
2e1f5012
VZ
172void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
173{
174 GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
b2ff89d6 175
2e1f5012 176 gtk_label_set_mnemonic_widget(labelwidget, widget);
b2ff89d6
VZ
177}
178
2e1f5012 179// ----------------------------------------------------------------------------
39bc0347 180// worker function implementing GTK*Mnemonics() functions
2e1f5012
VZ
181// ----------------------------------------------------------------------------
182
b2ff89d6
VZ
183/* static */
184wxString wxControl::GTKRemoveMnemonics(const wxString& label)
185{
b1f17bf0 186 return wxGTKRemoveMnemonics(label);
b2ff89d6
VZ
187}
188
189/* static */
190wxString wxControl::GTKConvertMnemonics(const wxString& label)
191{
b1f17bf0 192 return wxConvertMnemonicsToGTK(label);
eaafd2f8
VS
193}
194
39bc0347
VZ
195/* static */
196wxString wxControl::GTKConvertMnemonicsWithMarkup(const wxString& label)
197{
b1f17bf0 198 return wxConvertMnemonicsToGTKMarkup(label);
39bc0347
VZ
199}
200
b2ff89d6
VZ
201// ----------------------------------------------------------------------------
202// wxControl styles (a.k.a. attributes)
203// ----------------------------------------------------------------------------
9d522606
RD
204
205wxVisualAttributes wxControl::GetDefaultAttributes() const
206{
207 return GetDefaultAttributesFromGTKWidget(m_widget,
208 UseGTKStyleBase());
209}
210
9d522606
RD
211// static
212wxVisualAttributes
213wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
214 bool useBase,
215 int state)
216{
217 GtkStyle* style;
218 wxVisualAttributes attr;
219
220 style = gtk_rc_get_style(widget);
221 if (!style)
222 style = gtk_widget_get_default_style();
223
224 if (!style)
225 {
226 return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL);
227 }
228
229 if (state == -1)
230 state = GTK_STATE_NORMAL;
b2ff89d6 231
9d522606 232 // get the style's colours
cdf068a4 233 attr.colFg = wxColour(style->fg[state]);
9d522606 234 if (useBase)
cdf068a4 235 attr.colBg = wxColour(style->base[state]);
9d522606 236 else
cdf068a4 237 attr.colBg = wxColour(style->bg[state]);
9d522606
RD
238
239 // get the style's font
9d522606 240 if ( !style->font_desc )
b2ff89d6 241 style = gtk_widget_get_default_style();
9d522606 242 if ( style && style->font_desc )
b2ff89d6
VZ
243 {
244 wxNativeFontInfo info;
fdf7514a 245 info.description = pango_font_description_copy(style->font_desc);
b2ff89d6
VZ
246 attr.font = wxFont(info);
247 }
248 else
249 {
9d522606
RD
250 GtkSettings *settings = gtk_settings_get_default();
251 gchar *font_name = NULL;
252 g_object_get ( settings,
b2ff89d6 253 "gtk-font-name",
9d522606
RD
254 &font_name,
255 NULL);
256 if (!font_name)
257 attr.font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
258 else
259 attr.font = wxFont(wxString::FromAscii(font_name));
260 g_free (font_name);
b2ff89d6 261 }
b2ff89d6 262
9d522606
RD
263 return attr;
264}
265
266
267//static
268wxVisualAttributes
865bb325 269wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
9d522606
RD
270 bool useBase,
271 int state)
272{
273 wxVisualAttributes attr;
66d8fe77
VS
274 // NB: we need toplevel window so that GTK+ can find the right style
275 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 276 GtkWidget* widget = widget_new();
66d8fe77 277 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 278 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 279 gtk_widget_destroy(wnd);
9d522606
RD
280 return attr;
281}
282
283//static
284wxVisualAttributes
865bb325 285wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
9d522606
RD
286 bool useBase,
287 int state)
288{
289 wxVisualAttributes attr;
66d8fe77
VS
290 // NB: we need toplevel window so that GTK+ can find the right style
291 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 292 GtkWidget* widget = widget_new("");
66d8fe77 293 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 294 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 295 gtk_widget_destroy(wnd);
9d522606
RD
296 return attr;
297}
298
299
300//static
301wxVisualAttributes
865bb325 302wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
9d522606
RD
303 bool useBase,
304 int state)
305{
306 wxVisualAttributes attr;
66d8fe77
VS
307 // NB: we need toplevel window so that GTK+ can find the right style
308 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 309 GtkWidget* widget = widget_new(NULL);
66d8fe77 310 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 311 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 312 gtk_widget_destroy(wnd);
9d522606
RD
313 return attr;
314}
315
1e6feb95 316#endif // wxUSE_CONTROLS