1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/tbargtk.cpp 
   3 // Purpose:     GTK toolbar 
   4 // Author:      Robert Roebling 
   5 // Modified:    13.12.99 by VZ to derive from wxToolBarBase 
   7 // Copyright:   (c) Robert Roebling 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // For compilers that support precompilation, includes "wx.h". 
  12 #include "wx/wxprec.h" 
  14 #if wxUSE_TOOLBAR_NATIVE 
  16 #include "wx/toolbar.h" 
  22 // FIXME: Use GtkImage instead of GtkPixmap. Use the new toolbar API for when gtk runtime is new enough? 
  23 // Beware that the new and old toolbar API may not be mixed in usage. 
  24 #undef GTK_DISABLE_DEPRECATED 
  26 #include "wx/gtk/private.h" 
  29 static const char *arrow_down_xpm
[] = { 
  30 /* columns rows colors chars-per-pixel */ 
  45 // ---------------------------------------------------------------------------- 
  47 // ---------------------------------------------------------------------------- 
  50 extern bool       g_blockEventsOnDrag
; 
  51 extern wxCursor   g_globalCursor
; 
  53 // ---------------------------------------------------------------------------- 
  55 // ---------------------------------------------------------------------------- 
  57 // translate wxWidgets toolbar style flags to GTK orientation and style 
  58 static void GetGtkStyle(long style
, 
  59                         GtkOrientation 
*orient
, GtkToolbarStyle 
*gtkStyle
) 
  61     *orient 
= ( style 
& wxTB_LEFT 
|| style 
& wxTB_RIGHT 
) ? GTK_ORIENTATION_VERTICAL 
: GTK_ORIENTATION_HORIZONTAL
; 
  64     if ( style 
& wxTB_TEXT 
) 
  66         *gtkStyle 
= style 
& wxTB_NOICONS
 
  69                           style 
& wxTB_HORZ_LAYOUT 
? GTK_TOOLBAR_BOTH_HORIZ 
: 
  72     else // no text, hence we must have the icons or what would we show? 
  74         *gtkStyle 
= GTK_TOOLBAR_ICONS
; 
  78 // ---------------------------------------------------------------------------- 
  80 // ---------------------------------------------------------------------------- 
  82 class wxToolBarTool 
: public wxToolBarToolBase
 
  85     wxToolBarTool(wxToolBar 
*tbar
, 
  87                   const wxString
& label
, 
  88                   const wxBitmap
& bitmap1
, 
  89                   const wxBitmap
& bitmap2
, 
  92                   const wxString
& shortHelpString
, 
  93                   const wxString
& longHelpString
) 
  94         : wxToolBarToolBase(tbar
, id
, label
, bitmap1
, bitmap2
, kind
, 
  95                             clientData
, shortHelpString
, longHelpString
) 
 100     wxToolBarTool(wxToolBar 
*tbar
, wxControl 
*control
, const wxString
& label
) 
 101         : wxToolBarToolBase(tbar
, control
, label
) 
 106     virtual ~wxToolBarTool() 
 108         if ( IsControl() && !m_item 
) 
 110             // if we're a control which is not currently attached to the 
 111             // toolbar (as indicated by NULL m_item), we must undo the extra 
 112             // reference we added in DoDeleteTool() 
 113             g_object_unref(GetControl()->m_widget
); 
 117     // is this a radio button? 
 119     // unlike GetKind(), can be called for any kind of tools, not just buttons 
 120     bool IsRadio() const { return IsButton() && GetKind() == wxITEM_RADIO
; } 
 122     // this is only called for the normal buttons, i.e. not separators nor 
 124     GtkToolbarChildType 
GetGtkChildType() const 
 129                 return GTK_TOOLBAR_CHILD_TOGGLEBUTTON
; 
 132                 return GTK_TOOLBAR_CHILD_RADIOBUTTON
; 
 135                 wxFAIL_MSG( _T("unknown toolbar child type") ); 
 138             case wxITEM_DROPDOWN
: 
 140                 return GTK_TOOLBAR_CHILD_BUTTON
; 
 144     void SetImage(const wxBitmap
& bitmap
) 
 148             // setting from pixmap doesn't seem to work right, but pixbuf works well 
 149             gtk_image_set_from_pixbuf((GtkImage
*)m_image
, bitmap
.GetPixbuf()); 
 153     // the toolbar element for button tools or a GtkAlignment containing the 
 154     // control for control tools 
 157     // a GtkImage containing the image for a button-type tool, may be NULL 
 164 // ---------------------------------------------------------------------------- 
 166 // ---------------------------------------------------------------------------- 
 168 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxControl
) 
 170 // ============================================================================ 
 172 // ============================================================================ 
 174 //----------------------------------------------------------------------------- 
 175 // "clicked" (internal from gtk_toolbar) 
 176 //----------------------------------------------------------------------------- 
 179 static void gtk_toolbar_callback( GtkWidget 
*widget
, 
 180                                   wxToolBarTool 
*tool 
) 
 182     wxToolBar 
*tbar 
= (wxToolBar 
*)tool
->GetToolBar(); 
 184     if (tbar
->m_blockEvent
) return; 
 186     if (g_blockEventsOnDrag
) return; 
 187     if (!tool
->IsEnabled()) return; 
 189     if (tool
->CanBeToggled()) 
 191         if (tool
->IsRadio() && 
 192             gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget
)) && 
 195             // pressed an already pressed radio button 
 201         tool
->SetImage(tool
->GetBitmap()); 
 203         if ( tool
->IsRadio() && !tool
->IsToggled() ) 
 205             // radio button went up, don't report this as a wxWin event 
 210     if( !tbar
->OnLeftClick( tool
->GetId(), tool
->IsToggled() ) && tool
->CanBeToggled() ) 
 215         tool
->SetImage(tool
->GetBitmap()); 
 220 //----------------------------------------------------------------------------- 
 222 //----------------------------------------------------------------------------- 
 224 static gboolean 
gtk_toolbar_tool_rclick_callback(GtkWidget 
*WXUNUSED(widget
), 
 225                                                  GdkEventButton 
*event
, 
 226                                                  wxToolBarToolBase 
*tool
) 
 228     if (event
->button 
!= 3) 
 231     wxToolBar 
*tbar 
= (wxToolBar 
*)tool
->GetToolBar(); 
 233     if (tbar
->m_blockEvent
) return TRUE
; 
 235     if (g_blockEventsOnDrag
) return TRUE
; 
 236     if (!tool
->IsEnabled()) return TRUE
; 
 238     tbar
->OnRightClick( tool
->GetId(), (int)event
->x
, (int)event
->y 
); 
 244 //----------------------------------------------------------------------------- 
 245 // "enter_notify_event" / "leave_notify_event" from dropdown 
 246 //----------------------------------------------------------------------------- 
 249 static gint 
gtk_toolbar_buddy_enter_callback( GtkWidget 
*WXUNUSED(widget
), 
 250                                        GdkEventCrossing 
*WXUNUSED(gdk_event
), 
 253     guint8 state 
= GTK_WIDGET_STATE( tool 
); 
 254     state 
|= GTK_STATE_PRELIGHT
; 
 255     gtk_widget_set_state( tool
, (GtkStateType
) state 
); 
 259 static gint 
gtk_toolbar_buddy_leave_callback( GtkWidget 
*WXUNUSED(widget
), 
 260                                        GdkEventCrossing 
*WXUNUSED(gdk_event
), 
 263     guint8 state 
= GTK_WIDGET_STATE( tool 
); 
 264     state 
&= ~GTK_STATE_PRELIGHT
; 
 265     gtk_widget_set_state( tool
, (GtkStateType
) state 
); 
 270 //----------------------------------------------------------------------------- 
 271 // "left-click" on dropdown 
 272 //----------------------------------------------------------------------------- 
 276 static void gtk_pop_tb_hide_callback( GtkWidget 
*WXUNUSED(menu
), GtkToggleButton 
*button  
) 
 278     gtk_toggle_button_set_active( button
, FALSE 
); 
 281 static gboolean 
gtk_toolbar_dropdown_lclick_callback(GtkWidget 
*widget
, 
 282                                                  GdkEventButton 
*event
, 
 283                                                  wxToolBarToolBase 
*tool
) 
 285     if (event
->button 
!= 1) 
 288     wxToolBar 
*tbar 
= (wxToolBar 
*)tool
->GetToolBar(); 
 290     if (tbar
->m_blockEvent
) return FALSE
; 
 292     if (g_blockEventsOnDrag
) return FALSE
; 
 293     if (!tool
->IsEnabled()) return FALSE
; 
 295     wxCommandEvent 
evt(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED
, tool
->GetId() ); 
 296     if ( tbar
->HandleWindowEvent(evt
) ) 
 301     wxMenu 
* const menu 
= tool
->GetDropdownMenu(); 
 306     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widget
), TRUE 
); 
 308     g_signal_connect (menu
->m_menu
, "hide", 
 309                                     G_CALLBACK (gtk_pop_tb_hide_callback
), 
 312     tbar
->PopupMenu( menu
, widget
->allocation
.x
, 
 313                            widget
->allocation
.y 
+ widget
->allocation
.height 
); 
 320 //----------------------------------------------------------------------------- 
 321 // "enter_notify_event" / "leave_notify_event" 
 322 //----------------------------------------------------------------------------- 
 325 static gint 
gtk_toolbar_tool_callback( GtkWidget 
*WXUNUSED(widget
), 
 326                                        GdkEventCrossing 
*gdk_event
, 
 327                                        wxToolBarTool 
*tool 
) 
 329     if (g_blockEventsOnDrag
) return TRUE
; 
 331     wxToolBar 
*tb 
= (wxToolBar 
*)tool
->GetToolBar(); 
 334     if( gdk_event
->type 
== GDK_ENTER_NOTIFY 
) 
 335         tb
->OnMouseEnter( tool
->GetId() ); 
 337         tb
->OnMouseEnter( -1 ); 
 343 //----------------------------------------------------------------------------- 
 344 // "size_request" from m_toolbar 
 345 //----------------------------------------------------------------------------- 
 349 size_request(GtkWidget
*, GtkRequisition
* req
, wxToolBar
* win
) 
 351     const wxSize margins 
= win
->GetMargins(); 
 352     req
->width  
+= margins
.x
; 
 353     req
->height 
+= 2 * margins
.y
; 
 357 //----------------------------------------------------------------------------- 
 358 // InsertChild callback for wxToolBar 
 359 //----------------------------------------------------------------------------- 
 361 static void wxInsertChildInToolBar( wxWindow
* WXUNUSED(parent
), 
 364     // Child widget will be inserted into GtkToolbar by DoInsertTool. Ref it 
 365     // here so reparenting into wxToolBar doesn't delete it. 
 366     g_object_ref(child
->m_widget
); 
 369 // ---------------------------------------------------------------------------- 
 371 // ---------------------------------------------------------------------------- 
 373 void wxToolBarTool::Init() 
 379 wxToolBarToolBase 
*wxToolBar::CreateTool(int id
, 
 380                                          const wxString
& text
, 
 381                                          const wxBitmap
& bitmap1
, 
 382                                          const wxBitmap
& bitmap2
, 
 384                                          wxObject 
*clientData
, 
 385                                          const wxString
& shortHelpString
, 
 386                                          const wxString
& longHelpString
) 
 388     return new wxToolBarTool(this, id
, text
, bitmap1
, bitmap2
, kind
, 
 389                              clientData
, shortHelpString
, longHelpString
); 
 393 wxToolBar::CreateTool(wxControl 
*control
, const wxString
& label
) 
 395     return new wxToolBarTool(this, control
, label
); 
 398 //----------------------------------------------------------------------------- 
 399 // wxToolBar construction 
 400 //----------------------------------------------------------------------------- 
 402 void wxToolBar::Init() 
 404     m_toolbar 
= (GtkToolbar 
*)NULL
; 
 405     m_blockEvent 
= false; 
 407     m_defaultHeight 
= 32; 
 410 wxToolBar::~wxToolBar() 
 414 bool wxToolBar::Create( wxWindow 
*parent
, 
 419                         const wxString
& name 
) 
 421     m_insertCallback 
= wxInsertChildInToolBar
; 
 423     if ( !PreCreation( parent
, pos
, size 
) || 
 424          !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 426         wxFAIL_MSG( wxT("wxToolBar creation failed") ); 
 433     m_toolbar 
= GTK_TOOLBAR( gtk_toolbar_new() ); 
 436     // Doesn't work this way. 
 437     // GtkToolbarSpaceStyle space_style = GTK_TOOLBAR_SPACE_EMPTY; 
 438     // gtk_widget_style_set (GTK_WIDGET (m_toolbar), "space_style", &space_style, NULL); 
 440     SetToolSeparation(7); 
 442     if (style 
& wxTB_DOCKABLE
) 
 444         m_widget 
= gtk_handle_box_new(); 
 445         gtk_container_add( GTK_CONTAINER(m_widget
), GTK_WIDGET(m_toolbar
) ); 
 446         gtk_widget_show( GTK_WIDGET(m_toolbar
) ); 
 448         if (style 
& wxTB_FLAT
) 
 449             gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget
), GTK_SHADOW_NONE 
); 
 453         m_widget 
= gtk_event_box_new(); 
 454         gtk_container_add( GTK_CONTAINER(m_widget
), GTK_WIDGET(m_toolbar
) ); 
 455         ConnectWidget( m_widget 
); 
 456         gtk_widget_show(GTK_WIDGET(m_toolbar
)); 
 459     // FIXME: there is no such function for toolbars in 2.0 
 461     if (style 
& wxTB_FLAT
) 
 462         gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar
), GTK_RELIEF_NONE 
); 
 465     m_parent
->DoAddChild( this ); 
 469     g_signal_connect_after(m_toolbar
, "size_request", 
 470         G_CALLBACK(size_request
), this); 
 475 GdkWindow 
*wxToolBar::GTKGetWindow(wxArrayGdkWindows
& WXUNUSED(windows
)) const 
 477     return GTK_WIDGET(m_toolbar
)->window
; 
 480 void wxToolBar::GtkSetStyle() 
 482     GtkOrientation orient
; 
 483     GtkToolbarStyle style
; 
 484     GetGtkStyle(GetWindowStyle(), &orient
, &style
); 
 486     gtk_toolbar_set_orientation(m_toolbar
, orient
); 
 487     gtk_toolbar_set_style(m_toolbar
, style
); 
 488     gtk_toolbar_set_tooltips(m_toolbar
, !(style 
& wxTB_NO_TOOLTIPS
)); 
 491 void wxToolBar::SetWindowStyleFlag( long style 
) 
 493     wxToolBarBase::SetWindowStyleFlag(style
); 
 499 bool wxToolBar::DoInsertTool(size_t pos
, wxToolBarToolBase 
*toolBase
) 
 501     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, toolBase
); 
 503     if ( tool
->IsButton() ) 
 505         if ( !HasFlag(wxTB_NOICONS
) ) 
 507             wxBitmap bitmap 
= tool
->GetNormalBitmap(); 
 509             wxCHECK_MSG( bitmap
.Ok(), false, 
 510                          wxT("invalid bitmap for wxToolBar icon") ); 
 512             tool
->m_image 
= gtk_image_new(); 
 513             tool
->SetImage(bitmap
); 
 515             gtk_misc_set_alignment((GtkMisc
*)tool
->m_image
, 0.5, 0.5); 
 522         for ( size_t i 
= 0; i 
< pos
; i
++ ) 
 526             // if we have a dropdown menu, we use 2 GTK tools internally 
 527             wxToolBarToolsList::compatibility_iterator node 
= m_tools
.Item( i 
); 
 528             wxToolBarTool 
* const tool2 
= (wxToolBarTool
*) node
->GetData(); 
 529             if ( tool2
->IsButton() && tool2
->GetKind() == wxITEM_DROPDOWN 
) 
 535     switch ( tool
->GetStyle() ) 
 537         case wxTOOL_STYLE_BUTTON
: 
 538             // for a radio button we need the widget which starts the radio 
 539             // group it belongs to, i.e. the first radio button immediately 
 540             // preceding this one 
 542                 GtkWidget 
*widget 
= NULL
; 
 544                 if ( tool
->IsRadio() ) 
 546                     wxToolBarToolsList::compatibility_iterator node
 
 547                         = wxToolBarToolsList::compatibility_iterator(); 
 549                         node 
= m_tools
.Item(pos 
- 1); 
 553                         wxToolBarTool 
*toolNext 
= (wxToolBarTool 
*)node
->GetData(); 
 554                         if ( !toolNext
->IsRadio() ) 
 557                         widget 
= toolNext
->m_item
; 
 559                         node 
= node
->GetPrevious(); 
 564                         // this is the first button in the radio button group, 
 565                         // it will be toggled automatically by GTK so bring the 
 566                         // internal flag in sync 
 571                 tool
->m_item 
= gtk_toolbar_insert_element
 
 574                                   tool
->GetGtkChildType(), 
 576                                   tool
->GetLabel().empty() 
 578                                     : (const char*) wxGTK_CONV( tool
->GetLabel() ), 
 579                                   tool
->GetShortHelp().empty() 
 581                                     : (const char*) wxGTK_CONV( tool
->GetShortHelp() ), 
 582                                   "", // tooltip_private_text (?) 
 584                                   (GtkSignalFunc
)gtk_toolbar_callback
, 
 589                 wxCHECK_MSG(tool
->m_item 
!= NULL
, false, _T("gtk_toolbar_insert_element() failed")); 
 591                 g_signal_connect (tool
->m_item
, "enter_notify_event", 
 592                                   G_CALLBACK (gtk_toolbar_tool_callback
), 
 594                 g_signal_connect (tool
->m_item
, "leave_notify_event", 
 595                                   G_CALLBACK (gtk_toolbar_tool_callback
), 
 597                 g_signal_connect(tool
->m_item
, "button-press-event", 
 598                                   G_CALLBACK (gtk_toolbar_tool_rclick_callback
), 
 601                 if (tool
->GetKind() == wxITEM_DROPDOWN
) 
 603                     GdkPixbuf 
*pixbuf 
= gdk_pixbuf_new_from_xpm_data( arrow_down_xpm 
); 
 604                     GtkWidget 
*dropdown 
= gtk_toggle_button_new(); 
 605                     GtkWidget 
*image 
= gtk_image_new_from_pixbuf( pixbuf 
); 
 606                     gtk_widget_show( image 
); 
 607                     gtk_container_add( GTK_CONTAINER(dropdown
), image 
); 
 609                     if (GetWindowStyle() & wxTB_FLAT
) 
 610                         gtk_button_set_relief( GTK_BUTTON(dropdown
), GTK_RELIEF_NONE 
); 
 611                     GTK_WIDGET_UNSET_FLAGS (dropdown
, GTK_CAN_FOCUS
); 
 612                     gtk_widget_show( dropdown 
); 
 614                     g_signal_connect (dropdown
, "enter_notify_event", 
 615                                   G_CALLBACK (gtk_toolbar_buddy_enter_callback
), 
 617                     g_signal_connect (dropdown
, "leave_notify_event", 
 618                                   G_CALLBACK (gtk_toolbar_buddy_leave_callback
), 
 620                     g_signal_connect(dropdown
, "button-press-event", 
 621                                   G_CALLBACK (gtk_toolbar_dropdown_lclick_callback
), 
 625                     (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(tool
->m_item
) )->size_request 
) 
 626                         (tool
->m_item
, &req 
); 
 627                     gtk_widget_set_size_request( dropdown
, -1, req
.height 
); 
 629                     gtk_toolbar_insert_widget(m_toolbar
, dropdown
, NULL
, NULL
, 
 635         case wxTOOL_STYLE_SEPARATOR
: 
 636             gtk_toolbar_insert_space( m_toolbar
, posGtk 
); 
 639         case wxTOOL_STYLE_CONTROL
: 
 640             GtkWidget 
* const align 
= gtk_alignment_new(0.5, 0.5, 0, 0); 
 641             gtk_widget_show(align
); 
 642             gtk_container_add(GTK_CONTAINER(align
), 
 643                               tool
->GetControl()->m_widget
); 
 644             gtk_toolbar_insert_widget(m_toolbar
, align
, NULL
, NULL
, posGtk
); 
 646             // release reference obtained by wxInsertChildInToolBar 
 647             g_object_unref(tool
->GetControl()->m_widget
); 
 649             // remember the container we're in so that we could remove 
 650             // ourselves from it when we're detached from the toolbar 
 651             tool
->m_item 
= align
; 
 655     InvalidateBestSize(); 
 660 bool wxToolBar::DoDeleteTool(size_t pos
, wxToolBarToolBase 
*toolBase
) 
 662     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, toolBase
); 
 664     switch ( tool
->GetStyle() ) 
 666         case wxTOOL_STYLE_CONTROL
: 
 667             // don't destroy the control here as we can be called from 
 668             // RemoveTool() and then we need to keep the control alive; 
 669             // while if we're called from DeleteTool() the control will 
 670             // be destroyed when wxToolBarToolBase itself is deleted 
 672                 GtkWidget 
* const w 
= tool
->GetControl()->m_widget
; 
 674                 gtk_container_remove(GTK_CONTAINER(tool
->m_item
), w
); 
 678         case wxTOOL_STYLE_BUTTON
: 
 679             gtk_widget_destroy( tool
->m_item 
); 
 683         case wxTOOL_STYLE_SEPARATOR
: 
 684             gtk_toolbar_remove_space( m_toolbar
, pos 
); 
 688             wxFAIL_MSG( "unknown tool style" ); 
 692     InvalidateBestSize(); 
 696 // ---------------------------------------------------------------------------- 
 697 // wxToolBar tools state 
 698 // ---------------------------------------------------------------------------- 
 700 void wxToolBar::DoEnableTool(wxToolBarToolBase 
*toolBase
, bool enable
) 
 702     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, toolBase
); 
 706         gtk_widget_set_sensitive( tool
->m_item
, enable 
); 
 710 void wxToolBar::DoToggleTool( wxToolBarToolBase 
*toolBase
, bool toggle 
) 
 712     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, toolBase
); 
 714     GtkWidget 
*item 
= tool
->m_item
; 
 715     if ( item 
&& GTK_IS_TOGGLE_BUTTON(item
) ) 
 717         tool
->SetImage(tool
->GetBitmap()); 
 721         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(item
), toggle 
); 
 723         m_blockEvent 
= false; 
 727 void wxToolBar::DoSetToggle(wxToolBarToolBase 
* WXUNUSED(tool
), 
 728                             bool WXUNUSED(toggle
)) 
 730     // VZ: absolutely no idea about how to do it 
 731     wxFAIL_MSG( _T("not implemented") ); 
 734 // ---------------------------------------------------------------------------- 
 735 // wxToolBar geometry 
 736 // ---------------------------------------------------------------------------- 
 738 wxToolBarToolBase 
*wxToolBar::FindToolForPosition(wxCoord 
WXUNUSED(x
), 
 739                                                   wxCoord 
WXUNUSED(y
)) const 
 741     // VZ: GTK+ doesn't seem to have such thing 
 742     wxFAIL_MSG( _T("wxToolBar::FindToolForPosition() not implemented") ); 
 744     return (wxToolBarToolBase 
*)NULL
; 
 747 void wxToolBar::SetMargins( int x
, int y 
) 
 749     wxCHECK_RET( GetToolsCount() == 0, 
 750                  wxT("wxToolBar::SetMargins must be called before adding tools.") ); 
 756 void wxToolBar::SetToolSeparation( int separation 
) 
 758     // FIXME: this function disappeared 
 760     gtk_toolbar_set_space_size( m_toolbar
, separation 
); 
 763     m_toolSeparation 
= separation
; 
 766 void wxToolBar::SetToolShortHelp( int id
, const wxString
& helpString 
) 
 768     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, FindById(id
)); 
 772         (void)tool
->SetShortHelp(helpString
); 
 773         gtk_tooltips_set_tip(m_toolbar
->tooltips
, tool
->m_item
, 
 774                              wxGTK_CONV( helpString 
), ""); 
 778 void wxToolBar::SetToolNormalBitmap( int id
, const wxBitmap
& bitmap 
) 
 780     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, FindById(id
)); 
 783         wxCHECK_RET( tool
->IsButton(), wxT("Can only set bitmap on button tools.")); 
 785         tool
->SetNormalBitmap(bitmap
); 
 786         tool
->SetImage(tool
->GetBitmap()); 
 790 void wxToolBar::SetToolDisabledBitmap( int id
, const wxBitmap
& bitmap 
) 
 792     wxToolBarTool
* tool 
= wx_static_cast(wxToolBarTool
*, FindById(id
)); 
 795         wxCHECK_RET( tool
->IsButton(), wxT("Can only set bitmap on button tools.")); 
 797         tool
->SetDisabledBitmap(bitmap
); 
 798         tool
->SetImage(tool
->GetBitmap()); 
 802 // ---------------------------------------------------------------------------- 
 803 // wxToolBar idle handling 
 804 // ---------------------------------------------------------------------------- 
 806 void wxToolBar::OnInternalIdle() 
 808     // Check if we have to show window now 
 809     if (GtkShowFromOnIdle()) return; 
 811     wxCursor cursor 
= m_cursor
; 
 812     if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
 816         /* I now set the cursor the anew in every OnInternalIdle call 
 817            as setting the cursor in a parent window also effects the 
 818            windows above so that checking for the current cursor is 
 821         if (HasFlag(wxTB_DOCKABLE
) && (m_widget
->window
)) 
 823             /* if the toolbar is dockable, then m_widget stands for the 
 824                GtkHandleBox widget, which uses its own window so that we 
 825                can set the cursor for it. if the toolbar is not dockable, 
 826                m_widget comes from m_toolbar which uses its parent's 
 827                window ("windowless windows") and thus we cannot set the 
 829             gdk_window_set_cursor( m_widget
->window
, cursor
.GetCursor() ); 
 832         wxToolBarToolsList::compatibility_iterator node 
= m_tools
.GetFirst(); 
 835             wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 836             node 
= node
->GetNext(); 
 838             GtkWidget 
*item 
= tool
->m_item
; 
 841                 GdkWindow 
*window 
= item
->window
; 
 845                     gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
 851     if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) 
 852         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
 856 // ---------------------------------------------------------------------------- 
 860 wxToolBar::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 862     return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new
); 
 865 #endif // wxUSE_TOOLBAR_NATIVE