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