1
/////////////////////////////////////////////////////////////////////////////
2
// Name: src/gtk/checkbox.cpp
4
// Author: Robert Roebling
5
// Copyright: (c) 1998 Robert Roebling
6
// Licence: wxWindows licence
7
/////////////////////////////////////////////////////////////////////////////
9
// For compilers that support precompilation, includes "wx.h".
10
#include "wx/wxprec.h"
14
#include "wx/checkbox.h"
17
#include "wx/gtk/private/gtk2-compat.h"
19
//-----------------------------------------------------------------------------
21
//-----------------------------------------------------------------------------
23
extern bool g_blockEventsOnDrag;
25
//-----------------------------------------------------------------------------
27
//-----------------------------------------------------------------------------
30
static void gtk_checkbox_toggled_callback(GtkWidget *widget, wxCheckBox *cb)
32
if (g_blockEventsOnDrag) return;
34
// Transitions for 3state checkbox must be done manually, GTK's checkbox
35
// is 2state with additional "undetermined state" flag which isn't
36
// changed automatically:
39
GtkToggleButton *toggle = GTK_TOGGLE_BUTTON(widget);
41
if (cb->Is3rdStateAllowedForUser())
43
// The 3 states cycle like this when clicked:
44
// checked -> undetermined -> unchecked -> checked -> ...
45
bool active = gtk_toggle_button_get_active(toggle) != 0;
46
bool inconsistent = gtk_toggle_button_get_inconsistent(toggle) != 0;
48
cb->GTKDisableEvents();
50
if (!active && !inconsistent)
52
// checked -> undetermined
53
gtk_toggle_button_set_active(toggle, true);
54
gtk_toggle_button_set_inconsistent(toggle, true);
56
else if (!active && inconsistent)
58
// undetermined -> unchecked
59
gtk_toggle_button_set_inconsistent(toggle, false);
61
else if (active && !inconsistent)
63
// unchecked -> checked
68
wxFAIL_MSG(wxT("3state wxCheckBox in unexpected state!"));
71
cb->GTKEnableEvents();
75
// user's action unsets undetermined state:
76
gtk_toggle_button_set_inconsistent(toggle, false);
80
wxCommandEvent event(wxEVT_CHECKBOX, cb->GetId());
81
event.SetInt(cb->Get3StateValue());
82
event.SetEventObject(cb);
83
cb->HandleWindowEvent(event);
87
//-----------------------------------------------------------------------------
89
//-----------------------------------------------------------------------------
91
wxCheckBox::wxCheckBox()
93
m_widgetCheckbox = NULL;
96
wxCheckBox::~wxCheckBox()
98
if (m_widgetCheckbox && m_widgetCheckbox != m_widget)
99
GTKDisconnect(m_widgetCheckbox);
102
bool wxCheckBox::Create(wxWindow *parent,
104
const wxString &label,
108
const wxValidator& validator,
109
const wxString &name )
111
WXValidateStyle( &style );
112
if (!PreCreation( parent, pos, size ) ||
113
!CreateBase( parent, id, pos, size, style, validator, name ))
115
wxFAIL_MSG( wxT("wxCheckBox creation failed") );
119
if ( style & wxALIGN_RIGHT )
121
// VZ: as I don't know a way to create a right aligned checkbox with
122
// GTK we will create a checkbox without label and a label at the
124
m_widgetCheckbox = gtk_check_button_new();
126
m_widgetLabel = gtk_label_new("");
127
gtk_misc_set_alignment(GTK_MISC(m_widgetLabel), 0.0, 0.5);
129
m_widget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
130
gtk_box_pack_start(GTK_BOX(m_widget), m_widgetLabel, FALSE, FALSE, 3);
131
gtk_box_pack_start(GTK_BOX(m_widget), m_widgetCheckbox, FALSE, FALSE, 3);
133
gtk_widget_show( m_widgetLabel );
134
gtk_widget_show( m_widgetCheckbox );
138
m_widgetCheckbox = gtk_check_button_new_with_label("");
139
m_widgetLabel = gtk_bin_get_child(GTK_BIN(m_widgetCheckbox));
140
m_widget = m_widgetCheckbox;
142
g_object_ref(m_widget);
145
g_signal_connect (m_widgetCheckbox, "toggled",
146
G_CALLBACK (gtk_checkbox_toggled_callback), this);
148
m_parent->DoAddChild( this );
155
void wxCheckBox::GTKDisableEvents()
157
g_signal_handlers_block_by_func(m_widgetCheckbox,
158
(gpointer) gtk_checkbox_toggled_callback, this);
161
void wxCheckBox::GTKEnableEvents()
163
g_signal_handlers_unblock_by_func(m_widgetCheckbox,
164
(gpointer) gtk_checkbox_toggled_callback, this);
167
void wxCheckBox::SetValue( bool state )
169
wxCHECK_RET( m_widgetCheckbox != NULL, wxT("invalid checkbox") );
171
if (state == GetValue())
176
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(m_widgetCheckbox), state );
181
bool wxCheckBox::GetValue() const
183
wxCHECK_MSG( m_widgetCheckbox != NULL, false, wxT("invalid checkbox") );
185
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widgetCheckbox)) != 0;
188
void wxCheckBox::DoSet3StateValue(wxCheckBoxState state)
190
SetValue(state != wxCHK_UNCHECKED);
191
gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(m_widgetCheckbox),
192
state == wxCHK_UNDETERMINED);
195
wxCheckBoxState wxCheckBox::DoGet3StateValue() const
197
if (gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON(m_widgetCheckbox)))
199
return wxCHK_UNDETERMINED;
203
return GetValue() ? wxCHK_CHECKED : wxCHK_UNCHECKED;
207
void wxCheckBox::SetLabel( const wxString& label )
209
wxCHECK_RET( m_widgetLabel != NULL, wxT("invalid checkbox") );
211
// save the label inside m_label in case user calls GetLabel() later
212
wxControl::SetLabel(label);
214
GTKSetLabelForLabel(GTK_LABEL(m_widgetLabel), label);
217
bool wxCheckBox::Enable( bool enable )
219
if (!base_type::Enable(enable))
222
gtk_widget_set_sensitive( m_widgetLabel, enable );
230
void wxCheckBox::DoApplyWidgetStyle(GtkRcStyle *style)
232
GTKApplyStyle(m_widgetCheckbox, style);
233
GTKApplyStyle(m_widgetLabel, style);
236
GdkWindow *wxCheckBox::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
238
return gtk_button_get_event_window(GTK_BUTTON(m_widgetCheckbox));
243
wxCheckBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
245
return GetDefaultAttributesFromGTKWidget(gtk_check_button_new());