]>
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 | |
3c778901 | 42 | wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent ) |
1db8dc4a | 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 | 148 | { |
ad60f9e7 JS |
149 | bool isEnabled = IsEnabled(); |
150 | ||
4f856067 | 151 | if (!wxControl::Enable(enable)) |
91af0895 | 152 | return false; |
4f856067 | 153 | |
afa7bd1e | 154 | gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable); |
4f856067 | 155 | |
ad60f9e7 JS |
156 | if (!isEnabled && enable) |
157 | { | |
158 | GTKFixSensitivity(); | |
159 | } | |
160 | ||
91af0895 | 161 | return true; |
4f856067 RR |
162 | } |
163 | ||
10ff9c61 | 164 | void wxBitmapToggleButton::DoApplyWidgetStyle(GtkRcStyle *style) |
4f856067 | 165 | { |
f40fdaa3 | 166 | gtk_widget_modify_style(m_widget, style); |
afa7bd1e | 167 | gtk_widget_modify_style(GTK_BIN(m_widget)->child, style); |
4f856067 RR |
168 | } |
169 | ||
ef5c70f9 | 170 | GdkWindow * |
10ff9c61 | 171 | wxBitmapToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const |
4f856067 | 172 | { |
ef5c70f9 | 173 | return GTK_BUTTON(m_widget)->event_window; |
4f856067 RR |
174 | } |
175 | ||
4f856067 | 176 | // Get the "best" size for this control. |
10ff9c61 | 177 | wxSize wxBitmapToggleButton::DoGetBestSize() const |
4f856067 | 178 | { |
abdeb9e7 | 179 | wxSize best; |
91af0895 | 180 | |
abdeb9e7 | 181 | if (m_bitmap.Ok()) |
4f856067 | 182 | { |
abdeb9e7 RD |
183 | int border = HasFlag(wxNO_BORDER) ? 4 : 10; |
184 | best.x = m_bitmap.GetWidth()+border; | |
185 | best.y = m_bitmap.GetHeight()+border; | |
4f856067 | 186 | } |
9f884528 | 187 | CacheBestSize(best); |
abdeb9e7 | 188 | return best; |
4f856067 | 189 | } |
9d522606 RD |
190 | |
191 | ||
192 | // static | |
193 | wxVisualAttributes | |
10ff9c61 | 194 | wxBitmapToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) |
9d522606 RD |
195 | { |
196 | return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new); | |
197 | } | |
198 | ||
199 | ||
4f856067 RR |
200 | // ------------------------------------------------------------------------ |
201 | // wxToggleButton | |
202 | // ------------------------------------------------------------------------ | |
203 | ||
204 | IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl) | |
205 | ||
1db8dc4a VZ |
206 | bool wxToggleButton::Create(wxWindow *parent, wxWindowID id, |
207 | const wxString &label, const wxPoint &pos, | |
208 | const wxSize &size, long style, | |
209 | const wxValidator& validator, | |
210 | const wxString &name) | |
211 | { | |
91af0895 | 212 | if (!PreCreation(parent, pos, size) || |
e338053c PC |
213 | !CreateBase(parent, id, pos, size, style, validator, name )) |
214 | { | |
91af0895 WS |
215 | wxFAIL_MSG(wxT("wxToggleButton creation failed")); |
216 | return false; | |
217 | } | |
1db8dc4a | 218 | |
91af0895 | 219 | // Create the gtk widget. |
ecf3b4a5 | 220 | m_widget = gtk_toggle_button_new_with_mnemonic(""); |
9ff9d30c | 221 | g_object_ref(m_widget); |
ecf3b4a5 RR |
222 | |
223 | SetLabel(label); | |
1db8dc4a | 224 | |
9fa72bd2 MR |
225 | g_signal_connect (m_widget, "clicked", |
226 | G_CALLBACK (gtk_togglebutton_clicked_callback), | |
227 | this); | |
1db8dc4a | 228 | |
91af0895 | 229 | m_parent->DoAddChild(this); |
1db8dc4a | 230 | |
91af0895 WS |
231 | PostCreation(size); |
232 | ||
233 | return true; | |
1db8dc4a VZ |
234 | } |
235 | ||
c71ab7c1 RR |
236 | void wxToggleButton::GTKDisableEvents() |
237 | { | |
238 | g_signal_handlers_block_by_func(m_widget, | |
239 | (gpointer) gtk_togglebutton_clicked_callback, this); | |
240 | } | |
241 | ||
242 | void wxToggleButton::GTKEnableEvents() | |
243 | { | |
244 | g_signal_handlers_unblock_by_func(m_widget, | |
245 | (gpointer) gtk_togglebutton_clicked_callback, this); | |
246 | } | |
247 | ||
1db8dc4a VZ |
248 | // void SetValue(bool state) |
249 | // Set the value of the toggle button. | |
250 | void wxToggleButton::SetValue(bool state) | |
251 | { | |
91af0895 | 252 | wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button")); |
1db8dc4a | 253 | |
91af0895 WS |
254 | if (state == GetValue()) |
255 | return; | |
1db8dc4a | 256 | |
5e53c1c2 | 257 | GTKDisableEvents(); |
1db8dc4a | 258 | |
91af0895 | 259 | gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state); |
1db8dc4a | 260 | |
5e53c1c2 | 261 | GTKEnableEvents(); |
1db8dc4a VZ |
262 | } |
263 | ||
264 | // bool GetValue() const | |
265 | // Get the value of the toggle button. | |
266 | bool wxToggleButton::GetValue() const | |
267 | { | |
91af0895 | 268 | wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button")); |
1db8dc4a | 269 | |
91af0895 | 270 | return GTK_TOGGLE_BUTTON(m_widget)->active; |
1db8dc4a VZ |
271 | } |
272 | ||
1db8dc4a VZ |
273 | void wxToggleButton::SetLabel(const wxString& label) |
274 | { | |
8ab696e0 | 275 | wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button")); |
1db8dc4a | 276 | |
8ab696e0 | 277 | wxControl::SetLabel(label); |
1db8dc4a | 278 | |
ecf3b4a5 RR |
279 | const wxString labelGTK = GTKConvertMnemonics(label); |
280 | ||
281 | gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK)); | |
282 | ||
283 | ApplyWidgetStyle( false ); | |
1db8dc4a VZ |
284 | } |
285 | ||
91af0895 | 286 | bool wxToggleButton::Enable(bool enable /*=true*/) |
1db8dc4a | 287 | { |
ad60f9e7 JS |
288 | bool isEnabled = IsEnabled(); |
289 | ||
8ab696e0 | 290 | if (!wxControl::Enable(enable)) |
91af0895 | 291 | return false; |
1db8dc4a | 292 | |
afa7bd1e | 293 | gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable); |
1db8dc4a | 294 | |
ad60f9e7 JS |
295 | if (!isEnabled && enable) |
296 | { | |
297 | GTKFixSensitivity(); | |
298 | } | |
299 | ||
91af0895 | 300 | return true; |
1db8dc4a VZ |
301 | } |
302 | ||
f40fdaa3 | 303 | void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style) |
1db8dc4a | 304 | { |
f40fdaa3 | 305 | gtk_widget_modify_style(m_widget, style); |
afa7bd1e | 306 | gtk_widget_modify_style(GTK_BIN(m_widget)->child, style); |
1db8dc4a VZ |
307 | } |
308 | ||
ef5c70f9 VZ |
309 | GdkWindow * |
310 | wxToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const | |
1db8dc4a | 311 | { |
ef5c70f9 | 312 | return GTK_BUTTON(m_widget)->event_window; |
1db8dc4a VZ |
313 | } |
314 | ||
1db8dc4a VZ |
315 | // Get the "best" size for this control. |
316 | wxSize wxToggleButton::DoGetBestSize() const | |
317 | { | |
8ab696e0 | 318 | wxSize ret(wxControl::DoGetBestSize()); |
91af0895 | 319 | |
8ab696e0 RR |
320 | if (!HasFlag(wxBU_EXACTFIT)) |
321 | { | |
322 | if (ret.x < 80) ret.x = 80; | |
323 | } | |
91af0895 | 324 | |
9f884528 RD |
325 | CacheBestSize(ret); |
326 | return ret; | |
1db8dc4a VZ |
327 | } |
328 | ||
9d522606 RD |
329 | // static |
330 | wxVisualAttributes | |
331 | wxToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) | |
332 | { | |
333 | return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new); | |
334 | } | |
335 | ||
1db8dc4a | 336 | #endif // wxUSE_TOGGLEBTN |