1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/anybutton.cpp
4 // Author: Robert Roebling
5 // Created: 1998-05-20 (extracted from button.cpp)
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"
13 #ifdef wxHAS_ANY_BUTTON
16 #include "wx/anybutton.h"
19 #include "wx/stockitem.h"
22 #include "wx/gtk/private/gtk2-compat.h"
24 // ----------------------------------------------------------------------------
26 // ----------------------------------------------------------------------------
32 wxgtk_button_enter_callback(GtkWidget
*WXUNUSED(widget
), wxAnyButton
*button
)
34 if ( button
->GTKShouldIgnoreEvent() )
37 button
->GTKMouseEnters();
41 wxgtk_button_leave_callback(GtkWidget
*WXUNUSED(widget
), wxAnyButton
*button
)
43 if ( button
->GTKShouldIgnoreEvent() )
46 button
->GTKMouseLeaves();
50 wxgtk_button_press_callback(GtkWidget
*WXUNUSED(widget
), wxAnyButton
*button
)
52 if ( button
->GTKShouldIgnoreEvent() )
59 wxgtk_button_released_callback(GtkWidget
*WXUNUSED(widget
), wxAnyButton
*button
)
61 if ( button
->GTKShouldIgnoreEvent() )
64 button
->GTKReleased();
69 //-----------------------------------------------------------------------------
71 //-----------------------------------------------------------------------------
73 bool wxAnyButton::Enable( bool enable
)
75 if (!base_type::Enable(enable
))
78 gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget
)), enable
);
88 GdkWindow
*wxAnyButton::GTKGetWindow(wxArrayGdkWindows
& WXUNUSED(windows
)) const
90 return gtk_button_get_event_window(GTK_BUTTON(m_widget
));
95 wxAnyButton::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
97 return GetDefaultAttributesFromGTKWidget(gtk_button_new());
100 // ----------------------------------------------------------------------------
102 // ----------------------------------------------------------------------------
104 void wxAnyButton::GTKMouseEnters()
111 void wxAnyButton::GTKMouseLeaves()
118 void wxAnyButton::GTKPressed()
125 void wxAnyButton::GTKReleased()
132 void wxAnyButton::GTKOnFocus(wxFocusEvent
& event
)
139 wxAnyButton::State
wxAnyButton::GTKGetCurrentState() const
141 if ( !IsThisEnabled() )
142 return m_bitmaps
[State_Disabled
].IsOk() ? State_Disabled
: State_Normal
;
144 if ( m_isPressed
&& m_bitmaps
[State_Pressed
].IsOk() )
145 return State_Pressed
;
147 if ( m_isCurrent
&& m_bitmaps
[State_Current
].IsOk() )
148 return State_Current
;
150 if ( HasFocus() && m_bitmaps
[State_Focused
].IsOk() )
151 return State_Focused
;
156 void wxAnyButton::GTKUpdateBitmap()
158 // if we don't show bitmaps at all, there is nothing to update
159 if ( m_bitmaps
[State_Normal
].IsOk() )
161 // if we do show them, this will return a state for which we do have a
163 State state
= GTKGetCurrentState();
165 GTKDoShowBitmap(m_bitmaps
[state
]);
169 void wxAnyButton::GTKDoShowBitmap(const wxBitmap
& bitmap
)
171 wxASSERT_MSG( bitmap
.IsOk(), "invalid bitmap" );
174 if ( DontShowLabel() )
176 image
= gtk_bin_get_child(GTK_BIN(m_widget
));
178 else // have both label and bitmap
180 image
= gtk_button_get_image(GTK_BUTTON(m_widget
));
183 wxCHECK_RET( image
&& GTK_IS_IMAGE(image
), "must have image widget" );
185 gtk_image_set_from_pixbuf(GTK_IMAGE(image
), bitmap
.GetPixbuf());
188 wxBitmap
wxAnyButton::DoGetBitmap(State which
) const
190 return m_bitmaps
[which
];
193 void wxAnyButton::DoSetBitmap(const wxBitmap
& bitmap
, State which
)
198 if ( DontShowLabel() )
200 // we only have the bitmap in this button, never remove it but
201 // do invalidate the best size when the bitmap (and presumably
203 InvalidateBestSize();
205 // normal image is special: setting it enables images for the button and
206 // resetting it to nothing disables all of them
209 GtkWidget
*image
= gtk_button_get_image(GTK_BUTTON(m_widget
));
210 if ( image
&& !bitmap
.IsOk() )
212 gtk_container_remove(GTK_CONTAINER(m_widget
), image
);
214 else if ( !image
&& bitmap
.IsOk() )
216 image
= gtk_image_new();
217 gtk_button_set_image(GTK_BUTTON(m_widget
), image
);
219 else // image presence or absence didn't change
221 // don't invalidate best size below
225 InvalidateBestSize();
232 if ( !m_bitmaps
[which
].IsOk() )
234 // we need to install the callbacks to be notified about
235 // the button pressed state change
240 G_CALLBACK(wxgtk_button_press_callback
),
248 G_CALLBACK(wxgtk_button_released_callback
),
253 else // no valid bitmap
255 if ( m_bitmaps
[which
].IsOk() )
257 // we don't need to be notified about the button pressed
258 // state changes any more
259 g_signal_handlers_disconnect_by_func
262 (gpointer
)wxgtk_button_press_callback
,
266 g_signal_handlers_disconnect_by_func
269 (gpointer
)wxgtk_button_released_callback
,
273 // also make sure we don't remain stuck in pressed state
284 // the logic here is the same as above for State_Pressed: we need
285 // to connect the handlers if we must be notified about the changes
286 // in the button current state and we disconnect them when/if we
287 // don't need them any more
290 if ( !m_bitmaps
[which
].IsOk() )
296 G_CALLBACK(wxgtk_button_enter_callback
),
304 G_CALLBACK(wxgtk_button_leave_callback
),
309 else // no valid bitmap
311 if ( m_bitmaps
[which
].IsOk() )
313 g_signal_handlers_disconnect_by_func
316 (gpointer
)wxgtk_button_enter_callback
,
320 g_signal_handlers_disconnect_by_func
323 (gpointer
)wxgtk_button_leave_callback
,
339 Connect(wxEVT_SET_FOCUS
,
340 wxFocusEventHandler(wxAnyButton::GTKOnFocus
));
341 Connect(wxEVT_KILL_FOCUS
,
342 wxFocusEventHandler(wxAnyButton::GTKOnFocus
));
344 else // no valid focused bitmap
346 Disconnect(wxEVT_SET_FOCUS
,
347 wxFocusEventHandler(wxAnyButton::GTKOnFocus
));
348 Disconnect(wxEVT_KILL_FOCUS
,
349 wxFocusEventHandler(wxAnyButton::GTKOnFocus
));
354 // no callbacks to connect/disconnect
358 m_bitmaps
[which
] = bitmap
;
360 // update the bitmap immediately if necessary, otherwise it will be done
361 // when the bitmap for the corresponding state is needed the next time by
363 if ( bitmap
.IsOk() && which
== GTKGetCurrentState() )
365 GTKDoShowBitmap(bitmap
);
369 void wxAnyButton::DoSetBitmapPosition(wxDirection dir
)
372 if ( !gtk_check_version(2,10,0) )
374 GtkPositionType gtkpos
;
378 wxFAIL_MSG( "invalid position" );
382 gtkpos
= GTK_POS_LEFT
;
386 gtkpos
= GTK_POS_RIGHT
;
390 gtkpos
= GTK_POS_TOP
;
394 gtkpos
= GTK_POS_BOTTOM
;
398 gtk_button_set_image_position(GTK_BUTTON(m_widget
), gtkpos
);
399 InvalidateBestSize();
404 #endif // wxHAS_ANY_BUTTON