]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/tglbtn.cpp
make sure we are feeding coordinates of HIView instances, not wx-dimensions back...
[wxWidgets.git] / src / gtk1 / tglbtn.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk1/tglbtn.cpp
3// Purpose: Definition of the wxToggleButton class, which implements a
4// toggle button under wxGTK.
5// Author: John Norris, minor changes by Axel Schlueter
6// Modified by:
7// Created: 08.02.01
8// RCS-ID: $Id$
9// Copyright: (c) 2000 Johnny C. Norris II
10// License: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
15
16#if wxUSE_TOGGLEBTN
17
18#include "wx/tglbtn.h"
19
20#ifndef WX_PRECOMP
21 #include "wx/button.h"
22#endif
23
24#include "wx/gtk1/private.h"
25
26extern void wxapp_install_idle_handler();
27extern bool g_isIdle;
28extern bool g_blockEventsOnDrag;
29extern wxCursor g_globalCursor;
30
31extern "C" {
32static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
33{
34 if (g_isIdle)
35 wxapp_install_idle_handler();
36
37 if (!cb->m_hasVMT || g_blockEventsOnDrag)
38 return;
39
40 if (cb->m_blockEvent) return;
41
42 // Generate a wx event.
43 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, cb->GetId());
44 event.SetInt(cb->GetValue());
45 event.SetEventObject(cb);
46 cb->GetEventHandler()->ProcessEvent(event);
47}
48}
49
50DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
51
52// ------------------------------------------------------------------------
53// wxToggleBitmapButton
54// ------------------------------------------------------------------------
55
56IMPLEMENT_DYNAMIC_CLASS(wxToggleBitmapButton, wxControl)
57
58bool wxToggleBitmapButton::Create(wxWindow *parent, wxWindowID id,
59 const wxBitmap &label, const wxPoint &pos,
60 const wxSize &size, long style,
61 const wxValidator& validator,
62 const wxString &name)
63{
64 m_needParent = true;
65 m_acceptsFocus = true;
66
67 m_blockEvent = false;
68
69 if (!PreCreation(parent, pos, size) ||
70 !CreateBase(parent, id, pos, size, style, validator, name ))
71 {
72 wxFAIL_MSG(wxT("wxToggleBitmapButton creation failed"));
73 return false;
74 }
75
76 m_bitmap = label;
77
78 // Create the gtk widget.
79 m_widget = gtk_toggle_button_new();
80
81 if (style & wxNO_BORDER)
82 gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
83
84 if (m_bitmap.Ok())
85 {
86 OnSetBitmap();
87 }
88
89 gtk_signal_connect(GTK_OBJECT(m_widget), "clicked",
90 GTK_SIGNAL_FUNC(gtk_togglebutton_clicked_callback),
91 (gpointer *)this);
92
93 m_parent->DoAddChild(this);
94
95 PostCreation(size);
96
97 return true;
98}
99
100// void SetValue(bool state)
101// Set the value of the toggle button.
102void wxToggleBitmapButton::SetValue(bool state)
103{
104 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
105
106 if (state == GetValue())
107 return;
108
109 m_blockEvent = true;
110
111 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
112
113 m_blockEvent = false;
114}
115
116// bool GetValue() const
117// Get the value of the toggle button.
118bool wxToggleBitmapButton::GetValue() const
119{
120 wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
121
122 return GTK_TOGGLE_BUTTON(m_widget)->active;
123}
124
125void wxToggleBitmapButton::SetLabel(const wxBitmap& label)
126{
127 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
128
129 m_bitmap = label;
130 InvalidateBestSize();
131
132 OnSetBitmap();
133}
134
135void wxToggleBitmapButton::OnSetBitmap()
136{
137 if (!m_bitmap.Ok()) return;
138
139 GdkBitmap *mask = (GdkBitmap *) NULL;
140 if (m_bitmap.GetMask()) mask = m_bitmap.GetMask()->GetBitmap();
141
142 GtkWidget *child = BUTTON_CHILD(m_widget);
143 if (child == NULL)
144 {
145 // initial bitmap
146 GtkWidget *pixmap = gtk_pixmap_new(m_bitmap.GetPixmap(), mask);
147 gtk_widget_show(pixmap);
148 gtk_container_add(GTK_CONTAINER(m_widget), pixmap);
149 }
150 else
151 { // subsequent bitmaps
152 GtkPixmap *g_pixmap = GTK_PIXMAP(child);
153 gtk_pixmap_set(g_pixmap, m_bitmap.GetPixmap(), mask);
154 }
155}
156
157bool wxToggleBitmapButton::Enable(bool enable /*=true*/)
158{
159 if (!wxControl::Enable(enable))
160 return false;
161
162 gtk_widget_set_sensitive(BUTTON_CHILD(m_widget), enable);
163
164 return true;
165}
166
167void wxToggleBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style)
168{
169 gtk_widget_modify_style(m_widget, style);
170 gtk_widget_modify_style(BUTTON_CHILD(m_widget), style);
171}
172
173bool wxToggleBitmapButton::IsOwnGtkWindow(GdkWindow *window)
174{
175 return window == TOGGLE_BUTTON_EVENT_WIN(m_widget);
176}
177
178void wxToggleBitmapButton::OnInternalIdle()
179{
180 wxCursor cursor = m_cursor;
181
182 if (g_globalCursor.Ok())
183 cursor = g_globalCursor;
184
185 GdkWindow *win = TOGGLE_BUTTON_EVENT_WIN(m_widget);
186 if ( win && cursor.Ok() )
187 {
188 /* I now set the cursor the anew in every OnInternalIdle call
189 as setting the cursor in a parent window also effects the
190 windows above so that checking for the current cursor is
191 not possible. */
192
193 gdk_window_set_cursor(win, cursor.GetCursor());
194 }
195
196 if (wxUpdateUIEvent::CanUpdate(this))
197 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
198}
199
200
201// Get the "best" size for this control.
202wxSize wxToggleBitmapButton::DoGetBestSize() const
203{
204 wxSize best;
205
206 if (m_bitmap.Ok())
207 {
208 int border = HasFlag(wxNO_BORDER) ? 4 : 10;
209 best.x = m_bitmap.GetWidth()+border;
210 best.y = m_bitmap.GetHeight()+border;
211 }
212 CacheBestSize(best);
213 return best;
214}
215
216
217// static
218wxVisualAttributes
219wxToggleBitmapButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
220{
221 return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
222}
223
224
225// ------------------------------------------------------------------------
226// wxToggleButton
227// ------------------------------------------------------------------------
228
229IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
230
231bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
232 const wxString &label, const wxPoint &pos,
233 const wxSize &size, long style,
234 const wxValidator& validator,
235 const wxString &name)
236{
237 m_needParent = true;
238 m_acceptsFocus = true;
239
240 m_blockEvent = false;
241
242 if (!PreCreation(parent, pos, size) ||
243 !CreateBase(parent, id, pos, size, style, validator, name )) {
244 wxFAIL_MSG(wxT("wxToggleButton creation failed"));
245 return false;
246 }
247
248 wxControl::SetLabel(label);
249
250 // Create the gtk widget.
251 m_widget = gtk_toggle_button_new_with_label( wxGTK_CONV( m_label ) );
252
253 gtk_signal_connect(GTK_OBJECT(m_widget), "clicked",
254 GTK_SIGNAL_FUNC(gtk_togglebutton_clicked_callback),
255 (gpointer *)this);
256
257 m_parent->DoAddChild(this);
258
259 PostCreation(size);
260
261 return true;
262}
263
264// void SetValue(bool state)
265// Set the value of the toggle button.
266void wxToggleButton::SetValue(bool state)
267{
268 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
269
270 if (state == GetValue())
271 return;
272
273 m_blockEvent = true;
274
275 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
276
277 m_blockEvent = false;
278}
279
280// bool GetValue() const
281// Get the value of the toggle button.
282bool wxToggleButton::GetValue() const
283{
284 wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
285
286 return GTK_TOGGLE_BUTTON(m_widget)->active;
287}
288
289void wxToggleButton::SetLabel(const wxString& label)
290{
291 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
292
293 wxControl::SetLabel(label);
294
295 gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), wxGTK_CONV( GetLabel() ) );
296}
297
298bool wxToggleButton::Enable(bool enable /*=true*/)
299{
300 if (!wxControl::Enable(enable))
301 return false;
302
303 gtk_widget_set_sensitive(BUTTON_CHILD(m_widget), enable);
304
305 return true;
306}
307
308void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
309{
310 gtk_widget_modify_style(m_widget, style);
311 gtk_widget_modify_style(BUTTON_CHILD(m_widget), style);
312}
313
314bool wxToggleButton::IsOwnGtkWindow(GdkWindow *window)
315{
316 return window == TOGGLE_BUTTON_EVENT_WIN(m_widget);
317}
318
319void wxToggleButton::OnInternalIdle()
320{
321 wxCursor cursor = m_cursor;
322
323 if (g_globalCursor.Ok())
324 cursor = g_globalCursor;
325
326 GdkWindow *win = TOGGLE_BUTTON_EVENT_WIN(m_widget);
327 if ( win && cursor.Ok() )
328 {
329 /* I now set the cursor the anew in every OnInternalIdle call
330 as setting the cursor in a parent window also effects the
331 windows above so that checking for the current cursor is
332 not possible. */
333
334 gdk_window_set_cursor(win, cursor.GetCursor());
335 }
336
337 if (wxUpdateUIEvent::CanUpdate(this))
338 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
339}
340
341
342// Get the "best" size for this control.
343wxSize wxToggleButton::DoGetBestSize() const
344{
345 wxSize ret(wxControl::DoGetBestSize());
346
347 if (!HasFlag(wxBU_EXACTFIT))
348 {
349 if (ret.x < 80) ret.x = 80;
350 }
351
352 CacheBestSize(ret);
353 return ret;
354}
355
356// static
357wxVisualAttributes
358wxToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
359{
360 return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
361}
362
363#endif // wxUSE_TOGGLEBTN