1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk1/button.cpp 
   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/button.h" 
  16 #include "wx/stockitem.h" 
  18 #include "wx/gtk1/private.h" 
  19 #include "wx/gtk1/win_gtk.h" 
  21 //----------------------------------------------------------------------------- 
  23 //----------------------------------------------------------------------------- 
  27 //----------------------------------------------------------------------------- 
  29 //----------------------------------------------------------------------------- 
  31 extern void wxapp_install_idle_handler(); 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  38 extern bool   g_blockEventsOnDrag
; 
  40 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  45 static void gtk_button_clicked_callback( GtkWidget 
*WXUNUSED(widget
), wxButton 
*button 
) 
  48        wxapp_install_idle_handler(); 
  50     if (!button
->m_hasVMT
) return; 
  51     if (g_blockEventsOnDrag
) return; 
  53     wxCommandEvent 
event(wxEVT_COMMAND_BUTTON_CLICKED
, button
->GetId()); 
  54     event
.SetEventObject(button
); 
  55     button
->GetEventHandler()->ProcessEvent(event
); 
  59 //----------------------------------------------------------------------------- 
  60 // "style_set" from m_widget 
  61 //----------------------------------------------------------------------------- 
  64 gtk_button_style_set_callback( GtkWidget 
*m_widget
, GtkStyle 
*WXUNUSED(style
), wxButton 
*win 
) 
  67         wxapp_install_idle_handler(); 
  72     int bottom_border 
= 0; 
  74     /* the default button has a border around it */ 
  75     if (GTK_WIDGET_CAN_DEFAULT(m_widget
)) 
  81         win
->DoMoveWindow( win
->m_x
-top_border
, 
  83                            win
->m_width
+left_border
+right_border
, 
  84                            win
->m_height
+top_border
+bottom_border 
); 
  90 //----------------------------------------------------------------------------- 
  92 //----------------------------------------------------------------------------- 
  94 IMPLEMENT_DYNAMIC_CLASS(wxButton
,wxControl
) 
 100 wxButton::~wxButton() 
 104 bool wxButton::Create(  wxWindow 
*parent
, wxWindowID id
, const wxString 
&label
, 
 105       const wxPoint 
&pos
, const wxSize 
&size
, 
 106       long style
, const wxValidator
& validator
, const wxString 
&name 
) 
 109     m_acceptsFocus 
= true; 
 111     if (!PreCreation( parent
, pos
, size 
) || 
 112         !CreateBase( parent
, id
, pos
, size
, style
, validator
, name 
)) 
 114         wxFAIL_MSG( wxT("wxButton creation failed") ); 
 118     m_widget 
= gtk_button_new_with_label(""); 
 120     float x_alignment 
= 0.5; 
 121     if (HasFlag(wxBU_LEFT
)) 
 123     else if (HasFlag(wxBU_RIGHT
)) 
 126     float y_alignment 
= 0.5; 
 127     if (HasFlag(wxBU_TOP
)) 
 129     else if (HasFlag(wxBU_BOTTOM
)) 
 132     if (GTK_IS_MISC(BUTTON_CHILD(m_widget
))) 
 133         gtk_misc_set_alignment (GTK_MISC (BUTTON_CHILD (m_widget
)), 
 134                                 x_alignment
, y_alignment
); 
 138     if (style 
& wxNO_BORDER
) 
 139        gtk_button_set_relief( GTK_BUTTON(m_widget
), GTK_RELIEF_NONE 
); 
 141     gtk_signal_connect_after( GTK_OBJECT(m_widget
), "clicked", 
 142       GTK_SIGNAL_FUNC(gtk_button_clicked_callback
), (gpointer
*)this ); 
 144     gtk_signal_connect_after( GTK_OBJECT(m_widget
), "style_set", 
 145       GTK_SIGNAL_FUNC(gtk_button_style_set_callback
), (gpointer
*) this ); 
 147     m_parent
->DoAddChild( this ); 
 155 void wxButton::SetDefault() 
 157     wxWindow 
*parent 
= GetParent(); 
 158     wxCHECK_RET( parent
, _T("button without parent?") ); 
 160     parent
->SetDefaultItem(this); 
 162     GTK_WIDGET_SET_FLAGS( m_widget
, GTK_CAN_DEFAULT 
); 
 163     gtk_widget_grab_default( m_widget 
); 
 165     // resize for default border 
 166     gtk_button_style_set_callback( m_widget
, NULL
, this ); 
 170 wxSize 
wxButtonBase::GetDefaultSize() 
 172     return wxSize(80,26); 
 175 void wxButton::SetLabel( const wxString 
&lbl 
) 
 177     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid button") ); 
 181     if (label
.empty() && wxIsStockID(m_windowId
)) 
 182         label 
= wxGetStockLabel(m_windowId
); 
 184     wxControl::SetLabel(label
); 
 186     const wxString labelGTK 
= GTKRemoveMnemonics(label
); 
 188     gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget
)), wxGTK_CONV(labelGTK
)); 
 191 bool wxButton::Enable( bool enable 
) 
 193     if ( !wxControl::Enable( enable 
) ) 
 196     gtk_widget_set_sensitive( BUTTON_CHILD(m_widget
), enable 
); 
 201 bool wxButton::IsOwnGtkWindow( GdkWindow 
*window 
) 
 203     return (window 
== m_widget
->window
); 
 206 void wxButton::DoApplyWidgetStyle(GtkRcStyle 
*style
) 
 208     gtk_widget_modify_style(m_widget
, style
); 
 209     gtk_widget_modify_style(BUTTON_CHILD(m_widget
), style
); 
 212 wxSize 
wxButton::DoGetBestSize() const 
 214     // the default button in wxGTK is bigger than the other ones because of an 
 215     // extra border around it, but we don't want to take it into account in 
 216     // our size calculations (otherwsie the result is visually ugly), so 
 217     // always return the size of non default button from here 
 218     const bool isDefault 
= GTK_WIDGET_HAS_DEFAULT(m_widget
); 
 221         // temporarily unset default flag 
 222         GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_DEFAULT 
); 
 225     wxSize 
ret( wxControl::DoGetBestSize() ); 
 230         GTK_WIDGET_SET_FLAGS( m_widget
, GTK_CAN_DEFAULT 
); 
 233     ret
.x 
+= 10;  // add a few pixels for sloppy (but common) themes 
 235     if (!HasFlag(wxBU_EXACTFIT
)) 
 237         wxSize defaultSize 
= GetDefaultSize(); 
 238         if (ret
.x 
< defaultSize
.x
) ret
.x 
= defaultSize
.x
; 
 239         if (ret
.y 
< defaultSize
.y
) ret
.y 
= defaultSize
.y
; 
 248 wxButton::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 250     return GetDefaultAttributesFromGTKWidget(gtk_button_new
); 
 253 #endif // wxUSE_BUTTON