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