]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/tglbtn.cpp
fixing pattern phase bugs
[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
9e691f46 24#include "wx/gtk/private.h"
1db8dc4a 25
1db8dc4a 26extern bool g_blockEventsOnDrag;
1db8dc4a 27
865bb325 28extern "C" {
9864c56d 29static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
1db8dc4a 30{
91af0895
WS
31 if (g_isIdle)
32 wxapp_install_idle_handler();
33
34 if (!cb->m_hasVMT || g_blockEventsOnDrag)
35 return;
36
37 if (cb->m_blockEvent) return;
38
39 // Generate a wx event.
40 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, cb->GetId());
41 event.SetInt(cb->GetValue());
42 event.SetEventObject(cb);
43 cb->GetEventHandler()->ProcessEvent(event);
1db8dc4a 44}
865bb325 45}
1db8dc4a 46
1db8dc4a
VZ
47DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
48
4f856067
RR
49// ------------------------------------------------------------------------
50// wxToggleBitmapButton
51// ------------------------------------------------------------------------
52
53IMPLEMENT_DYNAMIC_CLASS(wxToggleBitmapButton, wxControl)
54
55bool wxToggleBitmapButton::Create(wxWindow *parent, wxWindowID id,
56 const wxBitmap &label, const wxPoint &pos,
57 const wxSize &size, long style,
58 const wxValidator& validator,
59 const wxString &name)
60{
91af0895
WS
61 m_needParent = true;
62 m_acceptsFocus = true;
63
64 m_blockEvent = false;
4f856067
RR
65
66 if (!PreCreation(parent, pos, size) ||
67 !CreateBase(parent, id, pos, size, style, validator, name ))
68 {
69 wxFAIL_MSG(wxT("wxToggleBitmapButton creation failed"));
91af0895 70 return false;
4f856067 71 }
91af0895 72
4f856067
RR
73 // Create the gtk widget.
74 m_widget = gtk_toggle_button_new();
75
76 if (style & wxNO_BORDER)
e338053c 77 gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
4f856067 78
e338053c
PC
79 m_bitmap = label;
80 OnSetBitmap();
4f856067 81
9fa72bd2
MR
82 g_signal_connect (m_widget, "clicked",
83 G_CALLBACK (gtk_togglebutton_clicked_callback),
84 this);
4f856067
RR
85
86 m_parent->DoAddChild(this);
87
abdeb9e7 88 PostCreation(size);
4f856067 89
91af0895 90 return true;
4f856067
RR
91}
92
93// void SetValue(bool state)
94// Set the value of the toggle button.
95void wxToggleBitmapButton::SetValue(bool state)
96{
91af0895 97 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
4f856067 98
91af0895
WS
99 if (state == GetValue())
100 return;
4f856067 101
91af0895 102 m_blockEvent = true;
4f856067 103
91af0895 104 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
4f856067 105
91af0895 106 m_blockEvent = false;
4f856067
RR
107}
108
109// bool GetValue() const
110// Get the value of the toggle button.
111bool wxToggleBitmapButton::GetValue() const
112{
91af0895 113 wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
4f856067 114
e338053c 115 return gtk_toggle_button_get_active((GtkToggleButton*)m_widget);
4f856067
RR
116}
117
118void wxToggleBitmapButton::SetLabel(const wxBitmap& label)
119{
120 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
121
122 m_bitmap = label;
9f884528 123 InvalidateBestSize();
91af0895 124
4f856067
RR
125 OnSetBitmap();
126}
127
128void wxToggleBitmapButton::OnSetBitmap()
129{
130 if (!m_bitmap.Ok()) return;
131
e338053c
PC
132 GtkWidget* image = ((GtkBin*)m_widget)->child;
133 if (image == NULL)
4f856067
RR
134 {
135 // initial bitmap
e338053c
PC
136 image = gtk_image_new_from_pixbuf(m_bitmap.GetPixbuf());
137 gtk_widget_show(image);
138 gtk_container_add((GtkContainer*)m_widget, image);
4f856067
RR
139 }
140 else
141 { // subsequent bitmaps
e338053c 142 gtk_image_set_from_pixbuf((GtkImage*)image, m_bitmap.GetPixbuf());
4f856067
RR
143 }
144}
145
91af0895 146bool wxToggleBitmapButton::Enable(bool enable /*=true*/)
4f856067
RR
147{
148 if (!wxControl::Enable(enable))
91af0895 149 return false;
4f856067 150
afa7bd1e 151 gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);
4f856067 152
91af0895 153 return true;
4f856067
RR
154}
155
f40fdaa3 156void wxToggleBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style)
4f856067 157{
f40fdaa3 158 gtk_widget_modify_style(m_widget, style);
afa7bd1e 159 gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
4f856067
RR
160}
161
ef5c70f9
VZ
162GdkWindow *
163wxToggleBitmapButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
4f856067 164{
ef5c70f9 165 return GTK_BUTTON(m_widget)->event_window;
4f856067
RR
166}
167
4f856067
RR
168// Get the "best" size for this control.
169wxSize wxToggleBitmapButton::DoGetBestSize() const
170{
abdeb9e7 171 wxSize best;
91af0895 172
abdeb9e7 173 if (m_bitmap.Ok())
4f856067 174 {
abdeb9e7
RD
175 int border = HasFlag(wxNO_BORDER) ? 4 : 10;
176 best.x = m_bitmap.GetWidth()+border;
177 best.y = m_bitmap.GetHeight()+border;
4f856067 178 }
9f884528 179 CacheBestSize(best);
abdeb9e7 180 return best;
4f856067 181}
9d522606
RD
182
183
184// static
185wxVisualAttributes
186wxToggleBitmapButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
187{
188 return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
189}
190
191
4f856067
RR
192// ------------------------------------------------------------------------
193// wxToggleButton
194// ------------------------------------------------------------------------
195
196IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
197
1db8dc4a
VZ
198bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
199 const wxString &label, const wxPoint &pos,
200 const wxSize &size, long style,
201 const wxValidator& validator,
202 const wxString &name)
203{
91af0895
WS
204 m_needParent = true;
205 m_acceptsFocus = true;
1db8dc4a 206
91af0895 207 m_blockEvent = false;
1db8dc4a 208
91af0895 209 if (!PreCreation(parent, pos, size) ||
e338053c
PC
210 !CreateBase(parent, id, pos, size, style, validator, name ))
211 {
91af0895
WS
212 wxFAIL_MSG(wxT("wxToggleButton creation failed"));
213 return false;
214 }
1db8dc4a 215
91af0895 216 // Create the gtk widget.
ecf3b4a5
RR
217 m_widget = gtk_toggle_button_new_with_mnemonic("");
218
219 SetLabel(label);
1db8dc4a 220
9fa72bd2
MR
221 g_signal_connect (m_widget, "clicked",
222 G_CALLBACK (gtk_togglebutton_clicked_callback),
223 this);
1db8dc4a 224
91af0895 225 m_parent->DoAddChild(this);
1db8dc4a 226
91af0895
WS
227 PostCreation(size);
228
229 return true;
1db8dc4a
VZ
230}
231
232// void SetValue(bool state)
233// Set the value of the toggle button.
234void wxToggleButton::SetValue(bool state)
235{
91af0895 236 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
1db8dc4a 237
91af0895
WS
238 if (state == GetValue())
239 return;
1db8dc4a 240
91af0895 241 m_blockEvent = true;
1db8dc4a 242
91af0895 243 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
1db8dc4a 244
91af0895 245 m_blockEvent = false;
1db8dc4a
VZ
246}
247
248// bool GetValue() const
249// Get the value of the toggle button.
250bool wxToggleButton::GetValue() const
251{
91af0895 252 wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
1db8dc4a 253
91af0895 254 return GTK_TOGGLE_BUTTON(m_widget)->active;
1db8dc4a
VZ
255}
256
1db8dc4a
VZ
257void wxToggleButton::SetLabel(const wxString& label)
258{
8ab696e0 259 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
1db8dc4a 260
8ab696e0 261 wxControl::SetLabel(label);
1db8dc4a 262
ecf3b4a5
RR
263 const wxString labelGTK = GTKConvertMnemonics(label);
264
265 gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
266
267 ApplyWidgetStyle( false );
1db8dc4a
VZ
268}
269
91af0895 270bool wxToggleButton::Enable(bool enable /*=true*/)
1db8dc4a 271{
8ab696e0 272 if (!wxControl::Enable(enable))
91af0895 273 return false;
1db8dc4a 274
afa7bd1e 275 gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);
1db8dc4a 276
91af0895 277 return true;
1db8dc4a
VZ
278}
279
f40fdaa3 280void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
1db8dc4a 281{
f40fdaa3 282 gtk_widget_modify_style(m_widget, style);
afa7bd1e 283 gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
1db8dc4a
VZ
284}
285
ef5c70f9
VZ
286GdkWindow *
287wxToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
1db8dc4a 288{
ef5c70f9 289 return GTK_BUTTON(m_widget)->event_window;
1db8dc4a
VZ
290}
291
1db8dc4a
VZ
292// Get the "best" size for this control.
293wxSize wxToggleButton::DoGetBestSize() const
294{
8ab696e0 295 wxSize ret(wxControl::DoGetBestSize());
91af0895 296
8ab696e0
RR
297 if (!HasFlag(wxBU_EXACTFIT))
298 {
299 if (ret.x < 80) ret.x = 80;
300 }
91af0895 301
9f884528
RD
302 CacheBestSize(ret);
303 return ret;
1db8dc4a
VZ
304}
305
9d522606
RD
306// static
307wxVisualAttributes
308wxToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
309{
310 return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
311}
312
1db8dc4a 313#endif // wxUSE_TOGGLEBTN