]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/radiobut.cpp
revert nested event loop support for wxGTK1 because it causes applications hangs
[wxWidgets.git] / src / gtk1 / radiobut.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/gtk1/radiobut.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
f96aa4d9 5// Copyright: (c) 1998 Robert Roebling
65571936 6// Licence: wxWindows licence
c801d85f
KB
7/////////////////////////////////////////////////////////////////////////////
8
14f355c2
VS
9// For compilers that support precompilation, includes "wx.h".
10#include "wx/wxprec.h"
dcf924a3
RR
11
12#if wxUSE_RADIOBOX
13
1e6feb95
VZ
14#include "wx/radiobut.h"
15
3cbab641 16#include "wx/gtk1/private.h"
c801d85f 17
acfd422a
RR
18//-----------------------------------------------------------------------------
19// idle system
20//-----------------------------------------------------------------------------
21
22extern void wxapp_install_idle_handler();
23extern bool g_isIdle;
24
6de97a3b
RR
25//-----------------------------------------------------------------------------
26// data
27//-----------------------------------------------------------------------------
28
d7fa7eaa
RR
29extern bool g_blockEventsOnDrag;
30extern wxCursor g_globalCursor;
31extern wxWindowGTK *g_delayedFocus;
6de97a3b
RR
32
33//-----------------------------------------------------------------------------
bb4549de 34// "clicked"
6de97a3b
RR
35//-----------------------------------------------------------------------------
36
865bb325 37extern "C" {
b2ff89d6 38static
e2762ff0 39void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *rb )
6de97a3b 40{
acfd422a
RR
41 if (g_isIdle) wxapp_install_idle_handler();
42
a2053b27 43 if (!rb->m_hasVMT) return;
b2ff89d6 44
f5d29b39 45 if (g_blockEventsOnDrag) return;
b2ff89d6 46
e2762ff0 47 if (!button->active) return;
b2ff89d6 48
9864c56d 49 if (rb->m_blockEvent) return;
b2ff89d6 50
ce7fe42e 51 wxCommandEvent event( wxEVT_RADIOBUTTON, rb->GetId());
f5d29b39
RR
52 event.SetInt( rb->GetValue() );
53 event.SetEventObject( rb );
937013e0 54 rb->HandleWindowEvent( event );
6de97a3b 55}
865bb325 56}
6de97a3b 57
bb4549de
RR
58//-----------------------------------------------------------------------------
59// wxRadioButton
60//-----------------------------------------------------------------------------
61
2b4f3c9f
VZ
62bool 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 )
6de97a3b 70{
b292e2f5 71 m_acceptsFocus = TRUE;
f5d29b39 72 m_needParent = TRUE;
b2ff89d6 73
9864c56d 74 m_blockEvent = FALSE;
6de97a3b 75
4dcaf11a
RR
76 if (!PreCreation( parent, pos, size ) ||
77 !CreateBase( parent, id, pos, size, style, validator, name ))
78 {
223d09f6 79 wxFAIL_MSG( wxT("wxRadioButton creation failed") );
9864c56d 80 return FALSE;
4dcaf11a 81 }
953704c1 82
739b7529
DS
83 GSList* radioButtonGroup = NULL;
84 if (!HasFlag(wxRB_GROUP))
953704c1 85 {
9864c56d 86 // search backward for last group start
d3b9f782 87 wxRadioButton *chief = NULL;
222ed1d6 88 wxWindowList::compatibility_iterator node = parent->GetChildren().GetLast();
953704c1 89 while (node)
e2762ff0
RR
90 {
91 wxWindow *child = node->GetData();
2b4f3c9f 92 if (child->IsRadioButton())
e2762ff0
RR
93 {
94 chief = (wxRadioButton*) child;
2b4f3c9f
VZ
95 if (child->HasFlag(wxRB_GROUP))
96 break;
e2762ff0
RR
97 }
98 node = node->GetPrevious();
953704c1 99 }
e2762ff0
RR
100 if (chief)
101 {
9864c56d 102 // we are part of the group started by chief
739b7529 103 radioButtonGroup = gtk_radio_button_group( GTK_RADIO_BUTTON(chief->m_widget) );
e2762ff0 104 }
953704c1
RR
105 }
106
739b7529 107 m_widget = gtk_radio_button_new_with_label( radioButtonGroup, wxGTK_CONV( label ) );
b2ff89d6 108
f5d29b39 109 SetLabel(label);
6de97a3b 110
b2ff89d6 111 gtk_signal_connect( GTK_OBJECT(m_widget), "clicked",
f5d29b39 112 GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
b2ff89d6 113
f03fc89f 114 m_parent->DoAddChild( this );
b2ff89d6 115
abdeb9e7 116 PostCreation(size);
6de97a3b 117
f5d29b39 118 return TRUE;
6de97a3b
RR
119}
120
121void wxRadioButton::SetLabel( const wxString& label )
122{
223d09f6 123 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
b2ff89d6
VZ
124
125 GTKSetLabelForLabel(GTK_LABEL(BUTTON_CHILD(m_widget)), label);
6de97a3b
RR
126}
127
128void wxRadioButton::SetValue( bool val )
129{
223d09f6 130 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
f6bcfd97 131
953704c1 132 if (val == GetValue())
0659e7ee
RR
133 return;
134
9864c56d 135 m_blockEvent = TRUE;
953704c1 136
f5d29b39 137 if (val)
953704c1 138 {
e2762ff0 139 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(m_widget), TRUE );
953704c1 140 }
f5d29b39 141 else
953704c1
RR
142 {
143 // should give an assert
f6bcfd97
BP
144 // RL - No it shouldn't. A wxGenericValidator might try to set it
145 // as FALSE. Failing silently is probably TRTTD here.
953704c1 146 }
f6bcfd97 147
9864c56d 148 m_blockEvent = FALSE;
6de97a3b
RR
149}
150
eb082a08 151bool wxRadioButton::GetValue() const
6de97a3b 152{
223d09f6 153 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid radiobutton") );
b2ff89d6 154
f5d29b39 155 return GTK_TOGGLE_BUTTON(m_widget)->active;
6de97a3b
RR
156}
157
f03fc89f 158bool wxRadioButton::Enable( bool enable )
d3904ceb 159{
f03fc89f
VZ
160 if ( !wxControl::Enable( enable ) )
161 return FALSE;
b2ff89d6 162
9e691f46 163 gtk_widget_set_sensitive( BUTTON_CHILD(m_widget), enable );
f03fc89f
VZ
164
165 return TRUE;
d3904ceb
RR
166}
167
f40fdaa3 168void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle *style)
868a2826 169{
f40fdaa3
VS
170 gtk_widget_modify_style(m_widget, style);
171 gtk_widget_modify_style(BUTTON_CHILD(m_widget), style);
f96aa4d9 172}
dcf924a3 173
2f073eb2
RR
174bool wxRadioButton::IsOwnGtkWindow( GdkWindow *window )
175{
9e691f46 176 return window == TOGGLE_BUTTON_EVENT_WIN(m_widget);
2f073eb2
RR
177}
178
179void wxRadioButton::OnInternalIdle()
180{
181 wxCursor cursor = m_cursor;
a1b806b9 182 if (g_globalCursor.IsOk()) cursor = g_globalCursor;
2f073eb2 183
9e691f46 184 GdkWindow *win = TOGGLE_BUTTON_EVENT_WIN(m_widget);
a1b806b9 185 if ( win && cursor.IsOk())
2f073eb2
RR
186 {
187 /* I now set the cursor the anew in every OnInternalIdle call
e2762ff0
RR
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. */
b2ff89d6 191
9e691f46 192 gdk_window_set_cursor( win, cursor.GetCursor() );
2f073eb2
RR
193 }
194
d7fa7eaa
RR
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
e39af974
JS
204 if (wxUpdateUIEvent::CanUpdate(this))
205 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2f073eb2
RR
206}
207
db434467
RR
208wxSize wxRadioButton::DoGetBestSize() const
209{
210 return wxControl::DoGetBestSize();
211}
212
9d522606
RD
213// static
214wxVisualAttributes
215wxRadioButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
216{
217 wxVisualAttributes attr;
bc0eb46c
VS
218 // NB: we need toplevel window so that GTK+ can find the right style
219 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 220 GtkWidget* widget = gtk_radio_button_new_with_label(NULL, "");
bc0eb46c 221 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 222 attr = GetDefaultAttributesFromGTKWidget(widget);
bc0eb46c 223 gtk_widget_destroy(wnd);
9d522606
RD
224 return attr;
225}
226
227
dcf924a3 228#endif