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