]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/tglbtn.cpp
Cache HDC used for painting for the entire duration of WM_PAINT processing.
[wxWidgets.git] / src / gtk / tglbtn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/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 // Licence: 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 <gtk/gtk.h>
25 #include "wx/gtk/private.h"
26
27 extern bool g_blockEventsOnDrag;
28
29 extern "C" {
30 static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
31 {
32 if (g_blockEventsOnDrag)
33 return;
34
35 // Generate a wx event.
36 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, cb->GetId());
37 event.SetInt(cb->GetValue());
38 event.SetEventObject(cb);
39 cb->HandleWindowEvent(event);
40 }
41 }
42
43 wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent );
44
45 // ------------------------------------------------------------------------
46 // wxBitmapToggleButton
47 // ------------------------------------------------------------------------
48
49 IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxToggleButton)
50
51 bool wxBitmapToggleButton::Create(wxWindow *parent, wxWindowID id,
52 const wxBitmap &bitmap, const wxPoint &pos,
53 const wxSize &size, long style,
54 const wxValidator& validator,
55 const wxString &name)
56 {
57 if ( !wxToggleButton::Create(parent, id, wxEmptyString, pos, size, style | wxBU_NOTEXT | wxBU_EXACTFIT,
58 validator, name) )
59 return false;
60
61 if ( bitmap.IsOk() )
62 {
63 SetBitmapLabel(bitmap);
64
65 // we need to adjust the size after setting the bitmap as it may be too
66 // big for the default button size
67 SetInitialSize(size);
68 }
69
70 return true;
71 }
72
73
74 // ------------------------------------------------------------------------
75 // wxToggleButton
76 // ------------------------------------------------------------------------
77
78 IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
79
80 bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
81 const wxString &label, const wxPoint &pos,
82 const wxSize &size, long style,
83 const wxValidator& validator,
84 const wxString &name)
85 {
86 if (!PreCreation(parent, pos, size) ||
87 !CreateBase(parent, id, pos, size, style, validator, name ))
88 {
89 wxFAIL_MSG(wxT("wxToggleButton creation failed"));
90 return false;
91 }
92
93 // create either a standard toggle button with text label (which may still contain
94 // an image under GTK+ 2.6+) or a bitmap-only toggle button if we don't have any
95 // label
96 const bool
97 useLabel = !(style & wxBU_NOTEXT) && !label.empty();
98 if ( useLabel )
99 {
100 m_widget = gtk_toggle_button_new_with_mnemonic("");
101 }
102 else // no label, suppose we will have a bitmap
103 {
104 m_widget = gtk_toggle_button_new();
105
106 GtkWidget *image = gtk_image_new();
107 gtk_widget_show(image);
108 gtk_container_add(GTK_CONTAINER(m_widget), image);
109 }
110
111 g_object_ref(m_widget);
112
113 if ( useLabel )
114 SetLabel(label);
115
116 g_signal_connect (m_widget, "clicked",
117 G_CALLBACK (gtk_togglebutton_clicked_callback),
118 this);
119
120 m_parent->DoAddChild(this);
121
122 PostCreation(size);
123
124 return true;
125 }
126
127 void wxToggleButton::GTKDisableEvents()
128 {
129 g_signal_handlers_block_by_func(m_widget,
130 (gpointer) gtk_togglebutton_clicked_callback, this);
131 }
132
133 void wxToggleButton::GTKEnableEvents()
134 {
135 g_signal_handlers_unblock_by_func(m_widget,
136 (gpointer) gtk_togglebutton_clicked_callback, this);
137 }
138
139 // void SetValue(bool state)
140 // Set the value of the toggle button.
141 void wxToggleButton::SetValue(bool state)
142 {
143 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
144
145 if (state == GetValue())
146 return;
147
148 GTKDisableEvents();
149
150 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
151
152 GTKEnableEvents();
153 }
154
155 // bool GetValue() const
156 // Get the value of the toggle button.
157 bool wxToggleButton::GetValue() const
158 {
159 wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
160
161 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widget)) != 0;
162 }
163
164 void wxToggleButton::SetLabel(const wxString& label)
165 {
166 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
167
168 wxAnyButton::SetLabel(label);
169
170 if ( HasFlag(wxBU_NOTEXT) )
171 {
172 // Don't try to update the label for a button not showing it, this is
173 // unnecessary and can also actually replace the image we show with the
174 // label entirely breaking the button code, see #13693.
175 return;
176 }
177
178 const wxString labelGTK = GTKConvertMnemonics(label);
179
180 gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
181
182 GTKApplyWidgetStyle( false );
183 }
184
185 #if wxUSE_MARKUP
186 bool wxToggleButton::DoSetLabelMarkup(const wxString& markup)
187 {
188 wxCHECK_MSG( m_widget != NULL, false, "invalid toggle button" );
189
190 const wxString stripped = RemoveMarkup(markup);
191 if ( stripped.empty() && !markup.empty() )
192 return false;
193
194 wxControl::SetLabel(stripped);
195
196 if ( !HasFlag(wxBU_NOTEXT) )
197 {
198 GtkLabel * const label = GTKGetLabel();
199 wxCHECK_MSG( label, false, "no label in this toggle button?" );
200
201 GTKSetLabelWithMarkupForLabel(label, markup);
202 }
203
204 return true;
205 }
206 #endif // wxUSE_MARKUP
207
208 GtkLabel *wxToggleButton::GTKGetLabel() const
209 {
210 GtkWidget* child = gtk_bin_get_child(GTK_BIN(m_widget));
211 return GTK_LABEL(child);
212 }
213
214 void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
215 {
216 GTKApplyStyle(m_widget, style);
217 GTKApplyStyle(gtk_bin_get_child(GTK_BIN(m_widget)), style);
218 }
219
220 // Get the "best" size for this control.
221 wxSize wxToggleButton::DoGetBestSize() const
222 {
223 wxSize ret(wxAnyButton::DoGetBestSize());
224
225 if (!HasFlag(wxBU_EXACTFIT))
226 {
227 if (ret.x < 80) ret.x = 80;
228 }
229
230 CacheBestSize(ret);
231 return ret;
232 }
233
234 // static
235 wxVisualAttributes
236 wxToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
237 {
238 return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
239 }
240
241 #endif // wxUSE_TOGGLEBTN