1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  15 #include "wx/radiobut.h" 
  17 #include "wx/gtk1/private.h" 
  19 //----------------------------------------------------------------------------- 
  21 //----------------------------------------------------------------------------- 
  23 extern void wxapp_install_idle_handler(); 
  26 //----------------------------------------------------------------------------- 
  28 //----------------------------------------------------------------------------- 
  30 extern bool           g_blockEventsOnDrag
; 
  31 extern wxCursor       g_globalCursor
; 
  32 extern wxWindowGTK   
*g_delayedFocus
; 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  40 void gtk_radiobutton_clicked_callback( GtkToggleButton 
*button
, wxRadioButton 
*rb 
) 
  42     if (g_isIdle
) wxapp_install_idle_handler(); 
  44     if (!rb
->m_hasVMT
) return; 
  46     if (g_blockEventsOnDrag
) return; 
  48     if (!button
->active
) return; 
  50     if (rb
->m_blockEvent
) return; 
  52     wxCommandEvent 
event( wxEVT_COMMAND_RADIOBUTTON_SELECTED
, rb
->GetId()); 
  53     event
.SetInt( rb
->GetValue() ); 
  54     event
.SetEventObject( rb 
); 
  55     rb
->GetEventHandler()->ProcessEvent( event 
); 
  59 //----------------------------------------------------------------------------- 
  61 //----------------------------------------------------------------------------- 
  63 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton
,wxControl
) 
  65 bool wxRadioButton::Create( wxWindow 
*parent
, 
  67                             const wxString
& label
, 
  71                             const wxValidator
& validator
, 
  72                             const wxString
& name 
) 
  74     m_acceptsFocus 
= TRUE
; 
  79     if (!PreCreation( parent
, pos
, size 
) || 
  80         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
  82         wxFAIL_MSG( wxT("wxRadioButton creation failed") ); 
  86     GSList
* radioButtonGroup 
= NULL
; 
  87     if (!HasFlag(wxRB_GROUP
)) 
  89         // search backward for last group start 
  90         wxRadioButton 
*chief 
= (wxRadioButton
*) NULL
; 
  91         wxWindowList::compatibility_iterator node 
= parent
->GetChildren().GetLast(); 
  94             wxWindow 
*child 
= node
->GetData(); 
  95             if (child
->IsRadioButton()) 
  97                 chief 
= (wxRadioButton
*) child
; 
  98                 if (child
->HasFlag(wxRB_GROUP
)) 
 101             node 
= node
->GetPrevious(); 
 105             // we are part of the group started by chief 
 106             radioButtonGroup 
= gtk_radio_button_group( GTK_RADIO_BUTTON(chief
->m_widget
) ); 
 110     m_widget 
= gtk_radio_button_new_with_label( radioButtonGroup
, wxGTK_CONV( label 
) ); 
 114     gtk_signal_connect( GTK_OBJECT(m_widget
), "clicked", 
 115       GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback
), (gpointer
*)this ); 
 117     m_parent
->DoAddChild( this ); 
 124 void wxRadioButton::SetLabel( const wxString
& label 
) 
 126     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid radiobutton") ); 
 128     GTKSetLabelForLabel(GTK_LABEL(BUTTON_CHILD(m_widget
)), label
); 
 131 void wxRadioButton::SetValue( bool val 
) 
 133     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid radiobutton") ); 
 135     if (val 
== GetValue()) 
 142         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(m_widget
), TRUE 
); 
 146         // should give an assert 
 147         // RL - No it shouldn't.  A wxGenericValidator might try to set it 
 148         //      as FALSE.  Failing silently is probably TRTTD here. 
 151     m_blockEvent 
= FALSE
; 
 154 bool wxRadioButton::GetValue() const 
 156     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid radiobutton") ); 
 158     return GTK_TOGGLE_BUTTON(m_widget
)->active
; 
 161 bool wxRadioButton::Enable( bool enable 
) 
 163     if ( !wxControl::Enable( enable 
) ) 
 166     gtk_widget_set_sensitive( BUTTON_CHILD(m_widget
), enable 
); 
 171 void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle 
*style
) 
 173     gtk_widget_modify_style(m_widget
, style
); 
 174     gtk_widget_modify_style(BUTTON_CHILD(m_widget
), style
); 
 177 bool wxRadioButton::IsOwnGtkWindow( GdkWindow 
*window 
) 
 179     return window 
== TOGGLE_BUTTON_EVENT_WIN(m_widget
); 
 182 void wxRadioButton::OnInternalIdle() 
 184     wxCursor cursor 
= m_cursor
; 
 185     if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
 187     GdkWindow 
*win 
= TOGGLE_BUTTON_EVENT_WIN(m_widget
); 
 188     if ( win 
&& cursor
.Ok()) 
 190         /* I now set the cursor the anew in every OnInternalIdle call 
 191        as setting the cursor in a parent window also effects the 
 192        windows above so that checking for the current cursor is 
 195        gdk_window_set_cursor( win
, cursor
.GetCursor() ); 
 198     if (g_delayedFocus 
== this) 
 200         if (GTK_WIDGET_REALIZED(m_widget
)) 
 202             gtk_widget_grab_focus( m_widget 
); 
 203             g_delayedFocus 
= NULL
; 
 207     if (wxUpdateUIEvent::CanUpdate(this)) 
 208         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
 211 wxSize 
wxRadioButton::DoGetBestSize() const 
 213     return wxControl::DoGetBestSize(); 
 218 wxRadioButton::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 220     wxVisualAttributes attr
; 
 221     // NB: we need toplevel window so that GTK+ can find the right style 
 222     GtkWidget 
*wnd 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 223     GtkWidget
* widget 
= gtk_radio_button_new_with_label(NULL
, ""); 
 224     gtk_container_add(GTK_CONTAINER(wnd
), widget
); 
 225     attr 
= GetDefaultAttributesFromGTKWidget(widget
); 
 226     gtk_widget_destroy(wnd
);