]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/radiobut.cpp
better support for ui action simulation
[wxWidgets.git] / src / gtk1 / radiobut.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk1/radiobut.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if wxUSE_RADIOBOX
14
15 #include "wx/radiobut.h"
16
17 #include "wx/gtk1/private.h"
18
19 //-----------------------------------------------------------------------------
20 // idle system
21 //-----------------------------------------------------------------------------
22
23 extern void wxapp_install_idle_handler();
24 extern bool g_isIdle;
25
26 //-----------------------------------------------------------------------------
27 // data
28 //-----------------------------------------------------------------------------
29
30 extern bool g_blockEventsOnDrag;
31 extern wxCursor g_globalCursor;
32 extern wxWindowGTK *g_delayedFocus;
33
34 //-----------------------------------------------------------------------------
35 // "clicked"
36 //-----------------------------------------------------------------------------
37
38 extern "C" {
39 static
40 void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *rb )
41 {
42 if (g_isIdle) wxapp_install_idle_handler();
43
44 if (!rb->m_hasVMT) return;
45
46 if (g_blockEventsOnDrag) return;
47
48 if (!button->active) return;
49
50 if (rb->m_blockEvent) return;
51
52 wxCommandEvent event( wxEVT_RADIOBUTTON, rb->GetId());
53 event.SetInt( rb->GetValue() );
54 event.SetEventObject( rb );
55 rb->HandleWindowEvent( event );
56 }
57 }
58
59 //-----------------------------------------------------------------------------
60 // wxRadioButton
61 //-----------------------------------------------------------------------------
62
63 bool wxRadioButton::Create( wxWindow *parent,
64 wxWindowID id,
65 const wxString& label,
66 const wxPoint& pos,
67 const wxSize& size,
68 long style,
69 const wxValidator& validator,
70 const wxString& name )
71 {
72 m_acceptsFocus = TRUE;
73 m_needParent = TRUE;
74
75 m_blockEvent = FALSE;
76
77 if (!PreCreation( parent, pos, size ) ||
78 !CreateBase( parent, id, pos, size, style, validator, name ))
79 {
80 wxFAIL_MSG( wxT("wxRadioButton creation failed") );
81 return FALSE;
82 }
83
84 GSList* radioButtonGroup = NULL;
85 if (!HasFlag(wxRB_GROUP))
86 {
87 // search backward for last group start
88 wxRadioButton *chief = NULL;
89 wxWindowList::compatibility_iterator node = parent->GetChildren().GetLast();
90 while (node)
91 {
92 wxWindow *child = node->GetData();
93 if (child->IsRadioButton())
94 {
95 chief = (wxRadioButton*) child;
96 if (child->HasFlag(wxRB_GROUP))
97 break;
98 }
99 node = node->GetPrevious();
100 }
101 if (chief)
102 {
103 // we are part of the group started by chief
104 radioButtonGroup = gtk_radio_button_group( GTK_RADIO_BUTTON(chief->m_widget) );
105 }
106 }
107
108 m_widget = gtk_radio_button_new_with_label( radioButtonGroup, wxGTK_CONV( label ) );
109
110 SetLabel(label);
111
112 gtk_signal_connect( GTK_OBJECT(m_widget), "clicked",
113 GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
114
115 m_parent->DoAddChild( this );
116
117 PostCreation(size);
118
119 return TRUE;
120 }
121
122 void wxRadioButton::SetLabel( const wxString& label )
123 {
124 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
125
126 GTKSetLabelForLabel(GTK_LABEL(BUTTON_CHILD(m_widget)), label);
127 }
128
129 void wxRadioButton::SetValue( bool val )
130 {
131 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
132
133 if (val == GetValue())
134 return;
135
136 m_blockEvent = TRUE;
137
138 if (val)
139 {
140 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(m_widget), TRUE );
141 }
142 else
143 {
144 // should give an assert
145 // RL - No it shouldn't. A wxGenericValidator might try to set it
146 // as FALSE. Failing silently is probably TRTTD here.
147 }
148
149 m_blockEvent = FALSE;
150 }
151
152 bool wxRadioButton::GetValue() const
153 {
154 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid radiobutton") );
155
156 return GTK_TOGGLE_BUTTON(m_widget)->active;
157 }
158
159 bool wxRadioButton::Enable( bool enable )
160 {
161 if ( !wxControl::Enable( enable ) )
162 return FALSE;
163
164 gtk_widget_set_sensitive( BUTTON_CHILD(m_widget), enable );
165
166 return TRUE;
167 }
168
169 void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle *style)
170 {
171 gtk_widget_modify_style(m_widget, style);
172 gtk_widget_modify_style(BUTTON_CHILD(m_widget), style);
173 }
174
175 bool wxRadioButton::IsOwnGtkWindow( GdkWindow *window )
176 {
177 return window == TOGGLE_BUTTON_EVENT_WIN(m_widget);
178 }
179
180 void wxRadioButton::OnInternalIdle()
181 {
182 wxCursor cursor = m_cursor;
183 if (g_globalCursor.IsOk()) cursor = g_globalCursor;
184
185 GdkWindow *win = TOGGLE_BUTTON_EVENT_WIN(m_widget);
186 if ( win && cursor.IsOk())
187 {
188 /* I now set the cursor the anew in every OnInternalIdle call
189 as setting the cursor in a parent window also effects the
190 windows above so that checking for the current cursor is
191 not possible. */
192
193 gdk_window_set_cursor( win, cursor.GetCursor() );
194 }
195
196 if (g_delayedFocus == this)
197 {
198 if (GTK_WIDGET_REALIZED(m_widget))
199 {
200 gtk_widget_grab_focus( m_widget );
201 g_delayedFocus = NULL;
202 }
203 }
204
205 if (wxUpdateUIEvent::CanUpdate(this))
206 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
207 }
208
209 wxSize wxRadioButton::DoGetBestSize() const
210 {
211 return wxControl::DoGetBestSize();
212 }
213
214 // static
215 wxVisualAttributes
216 wxRadioButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
217 {
218 wxVisualAttributes attr;
219 // NB: we need toplevel window so that GTK+ can find the right style
220 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
221 GtkWidget* widget = gtk_radio_button_new_with_label(NULL, "");
222 gtk_container_add(GTK_CONTAINER(wnd), widget);
223 attr = GetDefaultAttributesFromGTKWidget(widget);
224 gtk_widget_destroy(wnd);
225 return attr;
226 }
227
228
229 #endif