1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/radiobut.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Copyright: (c) 1998 Robert Roebling
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
11
12 #if wxUSE_RADIOBTN
13
14 #include "wx/radiobut.h"
15
16 #include "wx/gtk/private.h"
17
18 //-----------------------------------------------------------------------------
19 // data
20 //-----------------------------------------------------------------------------
21
22 extern bool g_blockEventsOnDrag;
23
24 //-----------------------------------------------------------------------------
25 // "clicked"
26 //-----------------------------------------------------------------------------
27
28 extern "C" {
29 static
gtk_radiobutton_clicked_callback(GtkToggleButton * button,wxRadioButton * rb)30 void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *rb )
31 {
32 if (g_blockEventsOnDrag) return;
33
34 if (!gtk_toggle_button_get_active(button)) return;
35
36 wxCommandEvent event( wxEVT_RADIOBUTTON, rb->GetId());
37 event.SetInt( rb->GetValue() );
38 event.SetEventObject( rb );
39 rb->HandleWindowEvent( event );
40 }
41 }
42
43 //-----------------------------------------------------------------------------
44 // wxRadioButton
45 //-----------------------------------------------------------------------------
46
Create(wxWindow * parent,wxWindowID id,const wxString & label,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)47 bool wxRadioButton::Create( wxWindow *parent,
48 wxWindowID id,
49 const wxString& label,
50 const wxPoint& pos,
51 const wxSize& size,
52 long style,
53 const wxValidator& validator,
54 const wxString& name )
55 {
56 if (!PreCreation( parent, pos, size ) ||
57 !CreateBase( parent, id, pos, size, style, validator, name ))
58 {
59 wxFAIL_MSG( wxT("wxRadioButton creation failed") );
60 return false;
61 }
62
63 // Check if this radio button should be put into an existing group. This
64 // shouldn't be done if it's given a style to explicitly start a new group
65 // or if it's not meant to be a part of a group at all.
66 GSList* radioButtonGroup = NULL;
67 if (!HasFlag(wxRB_GROUP) && !HasFlag(wxRB_SINGLE))
68 {
69 // search backward for last group start
70 wxWindowList::compatibility_iterator node = parent->GetChildren().GetLast();
71 for (; node; node = node->GetPrevious())
72 {
73 wxWindow *child = node->GetData();
74
75 // We stop at the first previous radio button in any case as it
76 // wouldn't make sense to put this button in a group with another
77 // one if there is a radio button that is not part of the same
78 // group between them.
79 if (wxIsKindOf(child, wxRadioButton))
80 {
81 // Any preceding radio button can be used to get its group, not
82 // necessarily one with wxRB_GROUP style, but exclude
83 // wxRB_SINGLE ones as their group should never be shared.
84 if (!child->HasFlag(wxRB_SINGLE))
85 {
86 radioButtonGroup = gtk_radio_button_get_group(
87 GTK_RADIO_BUTTON(child->m_widget));
88 }
89
90 break;
91 }
92 }
93 }
94
95 m_widget = gtk_radio_button_new_with_label( radioButtonGroup, wxGTK_CONV( label ) );
96 g_object_ref(m_widget);
97
98 SetLabel(label);
99
100 g_signal_connect_after (m_widget, "clicked",
101 G_CALLBACK (gtk_radiobutton_clicked_callback), this);
102
103 m_parent->DoAddChild( this );
104
105 PostCreation(size);
106
107 return true;
108 }
109
SetLabel(const wxString & label)110 void wxRadioButton::SetLabel( const wxString& label )
111 {
112 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
113
114 // save the original label
115 wxControlBase::SetLabel(label);
116
117 GTKSetLabelForLabel(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_widget))), label);
118 }
119
SetValue(bool val)120 void wxRadioButton::SetValue( bool val )
121 {
122 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
123
124 if (val == GetValue())
125 return;
126
127 g_signal_handlers_block_by_func(
128 m_widget, (void*)gtk_radiobutton_clicked_callback, this);
129
130 if (val)
131 {
132 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(m_widget), TRUE );
133 }
134 else
135 {
136 // should give an assert
137 // RL - No it shouldn't. A wxGenericValidator might try to set it
138 // as FALSE. Failing silently is probably TRTTD here.
139 }
140
141 g_signal_handlers_unblock_by_func(
142 m_widget, (void*)gtk_radiobutton_clicked_callback, this);
143 }
144
GetValue() const145 bool wxRadioButton::GetValue() const
146 {
147 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobutton") );
148
149 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widget)) != 0;
150 }
151
DoEnable(bool enable)152 void wxRadioButton::DoEnable(bool enable)
153 {
154 if ( !m_widget )
155 return;
156
157 base_type::DoEnable(enable);
158
159 gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable);
160
161 if (enable)
162 GTKFixSensitivity();
163 }
164
DoApplyWidgetStyle(GtkRcStyle * style)165 void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle *style)
166 {
167 GTKApplyStyle(m_widget, style);
168 GTKApplyStyle(gtk_bin_get_child(GTK_BIN(m_widget)), style);
169 }
170
171 GdkWindow *
GTKGetWindow(wxArrayGdkWindows & WXUNUSED (windows)) const172 wxRadioButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
173 {
174 return gtk_button_get_event_window(GTK_BUTTON(m_widget));
175 }
176
177 // static
178 wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant WXUNUSED (variant))179 wxRadioButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
180 {
181 return GetDefaultAttributesFromGTKWidget(gtk_radio_button_new_with_label(NULL, ""));
182 }
183
184
185 #endif
186