1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        wx/gtk/tglbtn.cpp 
   3 // Purpose:     Definition of the wxToggleButton class, which implements a 
   4 //              toggle button under wxGTK. 
   5 // Author:      John Norris, minor changes by Axel Schlueter 
   9 // Copyright:   (c) 2000 Johnny C. Norris II 
  10 // License:     Rocketeer license 
  11 ///////////////////////////////////////////////////////////////////////////// 
  13 #include "wx/tglbtn.h" 
  14 #include "wx/button.h" 
  18 #include "wx/gtk/private.h" 
  20 extern void wxapp_install_idle_handler(); 
  22 extern bool      g_blockEventsOnDrag
; 
  23 extern wxCursor   g_globalCursor
; 
  24 extern wxWindowGTK 
*g_delayedFocus
; 
  26 static void gtk_togglebutton_clicked_callback(GtkWidget 
*WXUNUSED(widget
), wxToggleButton 
*cb
) 
  29       wxapp_install_idle_handler(); 
  31    if (!cb
->m_hasVMT 
|| g_blockEventsOnDrag
) 
  34    if (cb
->m_blockEvent
) return; 
  36    // Generate a wx event. 
  37    wxCommandEvent 
event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED
, cb
->GetId()); 
  38    event
.SetInt(cb
->GetValue()); 
  39    event
.SetEventObject(cb
); 
  40    cb
->GetEventHandler()->ProcessEvent(event
); 
  43 IMPLEMENT_DYNAMIC_CLASS(wxToggleButton
, wxControl
) 
  44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED
) 
  46 bool wxToggleButton::Create(wxWindow 
*parent
, wxWindowID id
, 
  47                             const wxString 
&label
, const wxPoint 
&pos
, 
  48                             const wxSize 
&size
, long style
, 
  49                             const wxValidator
& validator
, 
  53    m_acceptsFocus 
= TRUE
; 
  57    if (!PreCreation(parent
, pos
, size
) || 
  58        !CreateBase(parent
, id
, pos
, size
, style
, validator
, name 
)) { 
  59       wxFAIL_MSG(wxT("wxToggleButton creation failed")); 
  63    wxControl::SetLabel(label
); 
  65    // Create the gtk widget. 
  66    m_widget 
= gtk_toggle_button_new_with_label( wxGTK_CONV( m_label 
) ); 
  68    gtk_signal_connect(GTK_OBJECT(m_widget
), "clicked", 
  69                       GTK_SIGNAL_FUNC(gtk_togglebutton_clicked_callback
), 
  72    m_parent
->DoAddChild(this); 
  76    SetFont(parent
->GetFont()); 
  78    wxSize 
size_best(DoGetBestSize()); 
  79    wxSize 
new_size(size
); 
  81       new_size
.x 
= size_best
.x
; 
  83       new_size
.y 
= size_best
.y
; 
  84    if ((new_size
.x 
!= size
.x
) || (new_size
.y 
!= size
.y
)) 
  85       SetSize(new_size
.x
, new_size
.y
); 
  87    SetBackgroundColour(parent
->GetBackgroundColour()); 
  88    SetForegroundColour(parent
->GetForegroundColour()); 
  95 // void SetValue(bool state) 
  96 // Set the value of the toggle button. 
  97 void wxToggleButton::SetValue(bool state
) 
  99    wxCHECK_RET(m_widget 
!= NULL
, wxT("invalid toggle button")); 
 101    if (state 
== GetValue()) 
 106    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget
), state
); 
 108    m_blockEvent 
= FALSE
; 
 111 // bool GetValue() const 
 112 // Get the value of the toggle button. 
 113 bool wxToggleButton::GetValue() const 
 115    wxCHECK_MSG(m_widget 
!= NULL
, FALSE
, wxT("invalid toggle button")); 
 117    return GTK_TOGGLE_BUTTON(m_widget
)->active
; 
 120 void wxToggleButton::SetLabel(const wxString
& label
) 
 122     wxCHECK_RET(m_widget 
!= NULL
, wxT("invalid toggle button")); 
 124     wxControl::SetLabel(label
); 
 126     gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget
)), wxGTK_CONV( GetLabel() ) ); 
 129 bool wxToggleButton::Enable(bool enable 
/*=TRUE*/) 
 131     if (!wxControl::Enable(enable
)) 
 134     gtk_widget_set_sensitive(BUTTON_CHILD(m_widget
), enable
); 
 139 void wxToggleButton::ApplyWidgetStyle() 
 142     gtk_widget_set_style(m_widget
, m_widgetStyle
); 
 143     gtk_widget_set_style(BUTTON_CHILD(m_widget
), m_widgetStyle
); 
 146 bool wxToggleButton::IsOwnGtkWindow(GdkWindow 
*window
) 
 148     return window 
== TOGGLE_BUTTON_EVENT_WIN(m_widget
); 
 151 void wxToggleButton::OnInternalIdle() 
 153     wxCursor cursor 
= m_cursor
; 
 155     if (g_globalCursor
.Ok()) 
 156         cursor 
= g_globalCursor
; 
 158     GdkWindow 
*win 
= TOGGLE_BUTTON_EVENT_WIN(m_widget
); 
 159     if ( win 
&& cursor
.Ok() ) 
 161       /* I now set the cursor the anew in every OnInternalIdle call 
 162          as setting the cursor in a parent window also effects the 
 163          windows above so that checking for the current cursor is 
 166         gdk_window_set_cursor(win
, cursor
.GetCursor()); 
 169     if (wxUpdateUIEvent::CanUpdate(this)) 
 170         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
 173 // wxSize DoGetBestSize() const 
 174 // Get the "best" size for this control. 
 175 wxSize 
wxToggleButton::DoGetBestSize() const 
 177     wxSize 
ret(wxControl::DoGetBestSize()); 
 179     if (!HasFlag(wxBU_EXACTFIT
)) 
 181         if (ret
.x 
< 80) ret
.x 
= 80; 
 188 #endif // wxUSE_TOGGLEBTN