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