]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/button.cpp
speeding up rectangle drawing by using specific methods, needs 40% less time
[wxWidgets.git] / src / gtk / button.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
93763ad5 2// Name: src/gtk/button.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
dbf858b5 5// Id: $Id$
01111366 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"
12
1e6feb95
VZ
13#if wxUSE_BUTTON
14
b84aec03 15#ifndef WX_PRECOMP
94aff5ff 16 #include "wx/button.h"
b84aec03
WS
17#endif
18
5f7bcb48 19#include "wx/stockitem.h"
c801d85f 20
9e691f46 21#include "wx/gtk/private.h"
83624f79 22
b4a4eafb
VZ
23// ----------------------------------------------------------------------------
24// GTK callbacks
25// ----------------------------------------------------------------------------
66bd6b93 26
b4a4eafb
VZ
27extern "C"
28{
c801d85f 29
b4a4eafb
VZ
30static void
31wxgtk_button_clicked_callback(GtkWidget *WXUNUSED(widget), wxButton *button)
c801d85f 32{
b4a4eafb
VZ
33 if ( button->GTKShouldIgnoreEvent() )
34 return;
9e691f46 35
acfd422a
RR
36 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, button->GetId());
37 event.SetEventObject(button);
937013e0 38 button->HandleWindowEvent(event);
6de97a3b 39}
b4a4eafb
VZ
40
41static void
42wxgtk_button_enter_callback(GtkWidget *WXUNUSED(widget), wxButton *button)
43{
44 if ( button->GTKShouldIgnoreEvent() )
45 return;
46
47 button->GTKMouseEnters();
48}
49
50static void
51wxgtk_button_leave_callback(GtkWidget *WXUNUSED(widget), wxButton *button)
52{
53 if ( button->GTKShouldIgnoreEvent() )
54 return;
55
56 button->GTKMouseLeaves();
57}
58
59static void
60wxgtk_button_press_callback(GtkWidget *WXUNUSED(widget), wxButton *button)
61{
62 if ( button->GTKShouldIgnoreEvent() )
63 return;
64
65 button->GTKPressed();
66}
67
68static void
69wxgtk_button_released_callback(GtkWidget *WXUNUSED(widget), wxButton *button)
70{
71 if ( button->GTKShouldIgnoreEvent() )
72 return;
73
74 button->GTKReleased();
865bb325 75}
c801d85f 76
a90c0600
RR
77//-----------------------------------------------------------------------------
78// "style_set" from m_widget
79//-----------------------------------------------------------------------------
80
4cdf71be 81static void
b4a4eafb 82wxgtk_button_style_set_callback(GtkWidget* widget, GtkStyle*, wxButton* win)
a90c0600 83{
f893066b 84 /* the default button has a border around it */
4cdf71be 85 wxWindow* parent = win->GetParent();
fc9ab22a 86 if (parent && parent->m_wxwindow && gtk_widget_get_can_default(widget))
f893066b 87 {
4cdf71be
PC
88 GtkBorder* border = NULL;
89 gtk_widget_style_get(widget, "default_border", &border, NULL);
90 if (border)
f893066b 91 {
4cdf71be
PC
92 win->MoveWindow(
93 win->m_x - border->left,
94 win->m_y - border->top,
95 win->m_width + border->left + border->right,
96 win->m_height + border->top + border->bottom);
97 gtk_border_free(border);
f893066b 98 }
b2ff89d6 99 }
4cdf71be 100}
b4a4eafb
VZ
101
102} // extern "C"
a90c0600 103
c801d85f 104//-----------------------------------------------------------------------------
e1e955e1
RR
105// wxButton
106//-----------------------------------------------------------------------------
107
e8375af8
VZ
108bool wxButton::Create(wxWindow *parent,
109 wxWindowID id,
110 const wxString &label,
111 const wxPoint& pos,
112 const wxSize& size,
113 long style,
114 const wxValidator& validator,
115 const wxString& name)
c801d85f 116{
4dcaf11a
RR
117 if (!PreCreation( parent, pos, size ) ||
118 !CreateBase( parent, id, pos, size, style, validator, name ))
119 {
223d09f6 120 wxFAIL_MSG( wxT("wxButton creation failed") );
93763ad5 121 return false;
4dcaf11a 122 }
c801d85f 123
c37dd6da
VZ
124 // create either a standard button with text label (which may still contain
125 // an image under GTK+ 2.6+) or a bitmap-only button if we don't have any
126 // label
a2117591
VZ
127 const bool
128 useLabel = !(style & wxBU_NOTEXT) && (!label.empty() || wxIsStockID(id));
c37dd6da
VZ
129 if ( useLabel )
130 {
131 m_widget = gtk_button_new_with_mnemonic("");
132 }
133 else // no label, suppose we will have a bitmap
134 {
135 m_widget = gtk_button_new();
136
137 GtkWidget *image = gtk_image_new();
138 gtk_widget_show(image);
139 gtk_container_add(GTK_CONTAINER(m_widget), image);
140 }
141
9ff9d30c 142 g_object_ref(m_widget);
354aa1e3 143
2e8613b7
RR
144 float x_alignment = 0.5;
145 if (HasFlag(wxBU_LEFT))
146 x_alignment = 0.0;
147 else if (HasFlag(wxBU_RIGHT))
148 x_alignment = 1.0;
149
150 float y_alignment = 0.5;
151 if (HasFlag(wxBU_TOP))
152 y_alignment = 0.0;
153 else if (HasFlag(wxBU_BOTTOM))
154 y_alignment = 1.0;
155
593ac8df 156 gtk_button_set_alignment(GTK_BUTTON(m_widget), x_alignment, y_alignment);
a696db45 157
c37dd6da
VZ
158 if ( useLabel )
159 SetLabel(label);
354aa1e3 160
de1c750f
RR
161 if (style & wxNO_BORDER)
162 gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
de1c750f 163
9fa72bd2 164 g_signal_connect_after (m_widget, "clicked",
b4a4eafb 165 G_CALLBACK (wxgtk_button_clicked_callback),
9fa72bd2 166 this);
c801d85f 167
9fa72bd2 168 g_signal_connect_after (m_widget, "style_set",
b4a4eafb 169 G_CALLBACK (wxgtk_button_style_set_callback),
9fa72bd2 170 this);
b2ff89d6 171
f03fc89f 172 m_parent->DoAddChild( this );
9e691f46 173
abdeb9e7 174 PostCreation(size);
db434467 175
4fa87bd9
VS
176 return true;
177}
b2ff89d6 178
32c77a71 179
94aff5ff 180wxWindow *wxButton::SetDefault()
c801d85f 181{
94aff5ff 182 wxWindow *oldDefault = wxButtonBase::SetDefault();
b2ff89d6 183
fc9ab22a 184 gtk_widget_set_can_default(m_widget, TRUE);
3502e687 185 gtk_widget_grab_default( m_widget );
b2ff89d6 186
f893066b 187 // resize for default border
b4a4eafb 188 wxgtk_button_style_set_callback( m_widget, NULL, this );
94aff5ff
VZ
189
190 return oldDefault;
6de97a3b 191}
c801d85f 192
ebea0891 193/* static */
4fa87bd9 194wxSize wxButtonBase::GetDefaultSize()
8dbf4589 195{
4fa87bd9
VS
196 static wxSize size = wxDefaultSize;
197 if (size == wxDefaultSize)
198 {
199 // NB: Default size of buttons should be same as size of stock
200 // buttons as used in most GTK+ apps. Unfortunately it's a little
201 // tricky to obtain this size: stock button's size may be smaller
202 // than size of button in GtkButtonBox and vice versa,
203 // GtkButtonBox's minimal button size may be smaller than stock
204 // button's size. We have to retrieve both values and combine them.
205
206 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
207 GtkWidget *box = gtk_hbutton_box_new();
208 GtkWidget *btn = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
209 gtk_container_add(GTK_CONTAINER(box), btn);
210 gtk_container_add(GTK_CONTAINER(wnd), box);
211 GtkRequisition req;
212 gtk_widget_size_request(btn, &req);
213
214 gint minwidth, minheight;
215 gtk_widget_style_get(box,
216 "child-min-width", &minwidth,
217 "child-min-height", &minheight,
218 NULL);
219
220 size.x = wxMax(minwidth, req.width);
221 size.y = wxMax(minheight, req.height);
b2ff89d6 222
4fa87bd9
VS
223 gtk_widget_destroy(wnd);
224 }
225 return size;
8dbf4589
RR
226}
227
5f7bcb48 228void wxButton::SetLabel( const wxString &lbl )
c801d85f 229{
223d09f6 230 wxCHECK_RET( m_widget != NULL, wxT("invalid button") );
9e691f46 231
5f7bcb48
VS
232 wxString label(lbl);
233
5f7bcb48
VS
234 if (label.empty() && wxIsStockID(m_windowId))
235 label = wxGetStockLabel(m_windowId);
5f7bcb48
VS
236
237 wxControl::SetLabel(label);
9e691f46 238
a2117591
VZ
239 // don't use label if it was explicitly disabled
240 if ( HasFlag(wxBU_NOTEXT) )
241 return;
242
5f7bcb48
VS
243 if (wxIsStockID(m_windowId) && wxIsStockLabel(m_windowId, label))
244 {
245 const char *stock = wxGetStockGtkID(m_windowId);
246 if (stock)
247 {
248 gtk_button_set_label(GTK_BUTTON(m_widget), stock);
249 gtk_button_set_use_stock(GTK_BUTTON(m_widget), TRUE);
b04683b1 250 return;
5f7bcb48 251 }
5f7bcb48
VS
252 }
253
5366ff46
VZ
254 // this call is necessary if the button had been initially created without
255 // a (text) label -- then we didn't use gtk_button_new_with_mnemonic() and
256 // so "use-underline" GtkButton property remained unset
257 gtk_button_set_use_underline(GTK_BUTTON(m_widget), TRUE);
4cdf71be 258 const wxString labelGTK = GTKConvertMnemonics(label);
b2ff89d6 259 gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
5f7bcb48 260 gtk_button_set_use_stock(GTK_BUTTON(m_widget), FALSE);
b2ff89d6 261
496e7ec6 262 GTKApplyWidgetStyle( false );
6de97a3b 263}
c801d85f 264
f382836f 265#if wxUSE_MARKUP
de1cc378
VZ
266bool wxButton::DoSetLabelMarkup(const wxString& markup)
267{
268 wxCHECK_MSG( m_widget != NULL, false, "invalid button" );
269
270 const wxString stripped = RemoveMarkup(markup);
271 if ( stripped.empty() && !markup.empty() )
272 return false;
273
274 wxControl::SetLabel(stripped);
275
276 GtkLabel * const label = GTKGetLabel();
277 wxCHECK_MSG( label, false, "no label in this button?" );
278
279 GTKSetLabelWithMarkupForLabel(label, markup);
280
281 return true;
282}
f382836f 283#endif // wxUSE_MARKUP
de1cc378 284
f03fc89f 285bool wxButton::Enable( bool enable )
a9c96bcc 286{
b545684e 287 if (!base_type::Enable(enable))
93763ad5 288 return false;
9e691f46 289
385e8575 290 gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable);
f03fc89f 291
b545684e 292 if (enable)
ad60f9e7 293 GTKFixSensitivity();
ad60f9e7 294
b4a4eafb
VZ
295 GTKUpdateBitmap();
296
93763ad5 297 return true;
a9c96bcc
RR
298}
299
ef5c70f9 300GdkWindow *wxButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
2b5f62a0 301{
2b5f62a0 302 return GTK_BUTTON(m_widget)->event_window;
2b5f62a0
VZ
303}
304
de1cc378
VZ
305GtkLabel *wxButton::GTKGetLabel() const
306{
385e8575 307 GtkWidget* child = gtk_bin_get_child(GTK_BIN(m_widget));
de1cc378
VZ
308 if ( GTK_IS_ALIGNMENT(child) )
309 {
385e8575
PC
310 GtkWidget* box = gtk_bin_get_child(GTK_BIN(child));
311 GtkLabel* label = NULL;
312 GList* list = gtk_container_get_children(GTK_CONTAINER(box));
313 for (GList* item = list; item; item = item->next)
de1cc378
VZ
314 {
315 GtkBoxChild* boxChild = static_cast<GtkBoxChild*>(item->data);
316 if ( GTK_IS_LABEL(boxChild->widget) )
385e8575 317 label = GTK_LABEL(boxChild->widget);
de1cc378 318 }
385e8575 319 g_list_free(list);
de1cc378 320
385e8575 321 return label;
de1cc378
VZ
322 }
323
324 return GTK_LABEL(child);
325}
326
f40fdaa3 327void wxButton::DoApplyWidgetStyle(GtkRcStyle *style)
868a2826 328{
f40fdaa3 329 gtk_widget_modify_style(m_widget, style);
385e8575 330 GtkWidget* child = gtk_bin_get_child(GTK_BIN(m_widget));
dfc22083
VZ
331 gtk_widget_modify_style(child, style);
332
333 // for buttons with images, the path to the label is (at least in 2.12)
334 // GtkButton -> GtkAlignment -> GtkHBox -> GtkLabel
335 if ( GTK_IS_ALIGNMENT(child) )
336 {
385e8575 337 GtkWidget* box = gtk_bin_get_child(GTK_BIN(child));
dfc22083
VZ
338 if ( GTK_IS_BOX(box) )
339 {
385e8575
PC
340 GList* list = gtk_container_get_children(GTK_CONTAINER(box));
341 for (GList* item = list; item; item = item->next)
f4b0832d
PC
342 {
343 GtkBoxChild* boxChild = static_cast<GtkBoxChild*>(item->data);
344 gtk_widget_modify_style(boxChild->widget, style);
345 }
385e8575 346 g_list_free(list);
dfc22083
VZ
347 }
348 }
a81258be 349}
db434467
RR
350
351wxSize wxButton::DoGetBestSize() const
352{
4f819fe4
VZ
353 // the default button in wxGTK is bigger than the other ones because of an
354 // extra border around it, but we don't want to take it into account in
7be740a3 355 // our size calculations (otherwise the result is visually ugly), so
4f819fe4 356 // always return the size of non default button from here
fc9ab22a 357 const bool isDefault = gtk_widget_has_default(m_widget);
4f819fe4
VZ
358 if ( isDefault )
359 {
360 // temporarily unset default flag
fc9ab22a 361 gtk_widget_set_can_default(m_widget, FALSE);
4f819fe4
VZ
362 }
363
db434467 364 wxSize ret( wxControl::DoGetBestSize() );
9e691f46 365
4f819fe4
VZ
366 if ( isDefault )
367 {
368 // set it back again
fc9ab22a 369 gtk_widget_set_can_default(m_widget, TRUE);
4f819fe4
VZ
370 }
371
8ab696e0
RR
372 if (!HasFlag(wxBU_EXACTFIT))
373 {
4fa87bd9 374 wxSize defaultSize = GetDefaultSize();
7be740a3
VZ
375 if (ret.x < defaultSize.x)
376 ret.x = defaultSize.x;
377 if (ret.y < defaultSize.y)
378 ret.y = defaultSize.y;
8ab696e0 379 }
9e691f46 380
9f884528 381 CacheBestSize(ret);
db434467
RR
382 return ret;
383}
384
9d522606
RD
385// static
386wxVisualAttributes
387wxButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
388{
389 return GetDefaultAttributesFromGTKWidget(gtk_button_new);
390}
391
7be740a3
VZ
392// ----------------------------------------------------------------------------
393// bitmaps support
394// ----------------------------------------------------------------------------
395
b4a4eafb
VZ
396void wxButton::GTKMouseEnters()
397{
398 m_isCurrent = true;
399
400 GTKUpdateBitmap();
401}
402
403void wxButton::GTKMouseLeaves()
404{
405 m_isCurrent = false;
406
407 GTKUpdateBitmap();
408}
409
410void wxButton::GTKPressed()
411{
412 m_isPressed = true;
413
414 GTKUpdateBitmap();
415}
416
417void wxButton::GTKReleased()
418{
419 m_isPressed = false;
420
421 GTKUpdateBitmap();
422}
423
424void wxButton::GTKOnFocus(wxFocusEvent& event)
425{
426 event.Skip();
427
428 GTKUpdateBitmap();
429}
430
431wxButton::State wxButton::GTKGetCurrentState() const
432{
433 if ( !IsThisEnabled() )
434 return m_bitmaps[State_Disabled].IsOk() ? State_Disabled : State_Normal;
435
436 if ( m_isPressed && m_bitmaps[State_Pressed].IsOk() )
437 return State_Pressed;
438
439 if ( m_isCurrent && m_bitmaps[State_Current].IsOk() )
440 return State_Current;
441
442 if ( HasFocus() && m_bitmaps[State_Focused].IsOk() )
443 return State_Focused;
444
445 return State_Normal;
446}
447
448void wxButton::GTKUpdateBitmap()
449{
e71aec80
VZ
450 // if we don't show bitmaps at all, there is nothing to update
451 if ( m_bitmaps[State_Normal].IsOk() )
452 {
453 // if we do show them, this will return a state for which we do have a
454 // valid bitmap
455 State state = GTKGetCurrentState();
b4a4eafb 456
e71aec80
VZ
457 GTKDoShowBitmap(m_bitmaps[state]);
458 }
b4a4eafb
VZ
459}
460
461void wxButton::GTKDoShowBitmap(const wxBitmap& bitmap)
462{
463 wxASSERT_MSG( bitmap.IsOk(), "invalid bitmap" );
464
c37dd6da 465 GtkWidget *image;
a2117591 466 if ( DontShowLabel() )
b4a4eafb 467 {
385e8575 468 image = gtk_bin_get_child(GTK_BIN(m_widget));
b4a4eafb 469 }
c37dd6da
VZ
470 else // have both label and bitmap
471 {
472#ifdef __WXGTK26__
473 if ( !gtk_check_version(2,6,0) )
474 {
475 image = gtk_button_get_image(GTK_BUTTON(m_widget));
476 }
477 else
b4a4eafb 478#endif // __WXGTK26__
c37dd6da
VZ
479 {
480 // buttons with both label and bitmap are only supported with GTK+
481 // 2.6 so far
482 //
483 // it shouldn't be difficult to implement them ourselves for the
484 // previous GTK+ versions by stuffing a container with a label and
485 // an image inside GtkButton but there doesn't seem to be much
486 // point in doing this for ancient GTK+ versions
487 return;
488 }
489 }
490
491 wxCHECK_RET( image && GTK_IS_IMAGE(image), "must have image widget" );
492
493 gtk_image_set_from_pixbuf(GTK_IMAGE(image), bitmap.GetPixbuf());
b4a4eafb
VZ
494}
495
7be740a3
VZ
496wxBitmap wxButton::DoGetBitmap(State which) const
497{
498 return m_bitmaps[which];
499}
500
501void wxButton::DoSetBitmap(const wxBitmap& bitmap, State which)
502{
b4a4eafb 503 switch ( which )
7be740a3 504 {
b4a4eafb 505 case State_Normal:
a2117591 506 if ( DontShowLabel() )
c37dd6da
VZ
507 {
508 // we only have the bitmap in this button, never remove it but
509 // do invalidate the best size when the bitmap (and presumably
510 // its size) changes
511 InvalidateBestSize();
512 }
b4a4eafb
VZ
513#ifdef __WXGTK26__
514 // normal image is special: setting it enables images for the button and
515 // resetting it to nothing disables all of them
c37dd6da 516 else if ( !gtk_check_version(2,6,0) )
7be740a3 517 {
b4a4eafb
VZ
518 GtkWidget *image = gtk_button_get_image(GTK_BUTTON(m_widget));
519 if ( image && !bitmap.IsOk() )
520 {
521 gtk_container_remove(GTK_CONTAINER(m_widget), image);
522 }
523 else if ( !image && bitmap.IsOk() )
524 {
525 image = gtk_image_new();
526 gtk_button_set_image(GTK_BUTTON(m_widget), image);
527 }
528 else // image presence or absence didn't change
529 {
530 // don't invalidate best size below
531 break;
532 }
533
7be740a3
VZ
534 InvalidateBestSize();
535 }
b4a4eafb
VZ
536#endif // GTK+ 2.6+
537 break;
538
539 case State_Pressed:
540 if ( bitmap.IsOk() )
541 {
542 if ( !m_bitmaps[which].IsOk() )
543 {
544 // we need to install the callbacks to be notified about
545 // the button pressed state change
546 g_signal_connect
547 (
548 m_widget,
549 "pressed",
550 G_CALLBACK(wxgtk_button_press_callback),
551 this
552 );
553
554 g_signal_connect
555 (
556 m_widget,
557 "released",
558 G_CALLBACK(wxgtk_button_released_callback),
559 this
560 );
561 }
562 }
563 else // no valid bitmap
7be740a3 564 {
b4a4eafb
VZ
565 if ( m_bitmaps[which].IsOk() )
566 {
567 // we don't need to be notified about the button pressed
568 // state changes any more
569 g_signal_handlers_disconnect_by_func
570 (
571 m_widget,
572 (gpointer)wxgtk_button_press_callback,
573 this
574 );
575
576 g_signal_handlers_disconnect_by_func
577 (
578 m_widget,
579 (gpointer)wxgtk_button_released_callback,
580 this
581 );
582
583 // also make sure we don't remain stuck in pressed state
584 if ( m_isPressed )
585 {
586 m_isPressed = false;
587 GTKUpdateBitmap();
588 }
589 }
7be740a3 590 }
b4a4eafb 591 break;
7be740a3 592
b4a4eafb
VZ
593 case State_Current:
594 // the logic here is the same as above for State_Pressed: we need
595 // to connect the handlers if we must be notified about the changes
596 // in the button current state and we disconnect them when/if we
597 // don't need them any more
7be740a3
VZ
598 if ( bitmap.IsOk() )
599 {
b4a4eafb
VZ
600 if ( !m_bitmaps[which].IsOk() )
601 {
602 g_signal_connect
603 (
604 m_widget,
605 "enter",
606 G_CALLBACK(wxgtk_button_enter_callback),
607 this
608 );
609
610 g_signal_connect
611 (
612 m_widget,
613 "leave",
614 G_CALLBACK(wxgtk_button_leave_callback),
615 this
616 );
617 }
7be740a3 618 }
b4a4eafb
VZ
619 else // no valid bitmap
620 {
621 if ( m_bitmaps[which].IsOk() )
622 {
623 g_signal_handlers_disconnect_by_func
624 (
625 m_widget,
626 (gpointer)wxgtk_button_enter_callback,
627 this
628 );
629
630 g_signal_handlers_disconnect_by_func
631 (
632 m_widget,
633 (gpointer)wxgtk_button_leave_callback,
634 this
635 );
636
637 if ( m_isCurrent )
638 {
639 m_isCurrent = false;
640 GTKUpdateBitmap();
641 }
642 }
643 }
644 break;
645
646 case State_Focused:
647 if ( bitmap.IsOk() )
648 {
649 Connect(wxEVT_SET_FOCUS,
650 wxFocusEventHandler(wxButton::GTKOnFocus));
651 Connect(wxEVT_KILL_FOCUS,
652 wxFocusEventHandler(wxButton::GTKOnFocus));
653 }
654 else // no valid focused bitmap
655 {
656 Disconnect(wxEVT_SET_FOCUS,
657 wxFocusEventHandler(wxButton::GTKOnFocus));
658 Disconnect(wxEVT_KILL_FOCUS,
659 wxFocusEventHandler(wxButton::GTKOnFocus));
660 }
661 break;
662
663 default:
664 // no callbacks to connect/disconnect
665 ;
7be740a3 666 }
7be740a3
VZ
667
668 m_bitmaps[which] = bitmap;
b4a4eafb
VZ
669
670 // update the bitmap immediately if necessary, otherwise it will be done
671 // when the bitmap for the corresponding state is needed the next time by
672 // GTKUpdateBitmap()
673 if ( bitmap.IsOk() && which == GTKGetCurrentState() )
674 {
675 GTKDoShowBitmap(bitmap);
676 }
7be740a3
VZ
677}
678
679void wxButton::DoSetBitmapPosition(wxDirection dir)
680{
681#ifdef __WXGTK210__
682 if ( !gtk_check_version(2,10,0) )
683 {
684 GtkPositionType gtkpos;
685 switch ( dir )
686 {
687 default:
688 wxFAIL_MSG( "invalid position" );
689 // fall through
690
691 case wxLEFT:
692 gtkpos = GTK_POS_LEFT;
693 break;
694
695 case wxRIGHT:
696 gtkpos = GTK_POS_RIGHT;
697 break;
698
699 case wxTOP:
700 gtkpos = GTK_POS_TOP;
701 break;
702
703 case wxBOTTOM:
704 gtkpos = GTK_POS_BOTTOM;
705 break;
706 }
707
708 gtk_button_set_image_position(GTK_BUTTON(m_widget), gtkpos);
06bb8d92 709 InvalidateBestSize();
7be740a3
VZ
710 }
711#endif // GTK+ 2.10+
712}
713
1e6feb95 714#endif // wxUSE_BUTTON