]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/tglbtn.cpp
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / gtk / tglbtn.cpp
... / ...
CommitLineData
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
27extern bool g_blockEventsOnDrag;
28
29extern "C" {
30static 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
43wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent );
44
45// ------------------------------------------------------------------------
46// wxBitmapToggleButton
47// ------------------------------------------------------------------------
48
49IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxToggleButton)
50
51bool 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
78IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
79
80bool 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
127void wxToggleButton::GTKDisableEvents()
128{
129 g_signal_handlers_block_by_func(m_widget,
130 (gpointer) gtk_togglebutton_clicked_callback, this);
131}
132
133void 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.
141void 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.
157bool 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
164void 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
186bool 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
208GtkLabel *wxToggleButton::GTKGetLabel() const
209{
210 GtkWidget* child = gtk_bin_get_child(GTK_BIN(m_widget));
211 return GTK_LABEL(child);
212}
213
214void 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.
221wxSize 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
235wxVisualAttributes
236wxToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
237{
238 return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
239}
240
241#endif // wxUSE_TOGGLEBTN