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
6 // RCS-ID:      $Id: tbargtk.cpp 53915 2008-06-01 20:18:12Z PC $
7 // Copyright:   (c) Robert Roebling
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // ============================================================================
12 // declarations
13 // ============================================================================
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21 
22 #if wxUSE_TOOLBAR_NATIVE
23 
24 #include "wx/toolbar.h"
25 
26 #ifndef WX_PRECOMP
27     #include "wx/frame.h"
28 #endif
29 
30 // FIXME: Use GtkImage instead of GtkPixmap. Use the new toolbar API for when gtk runtime is new enough?
31 // Beware that the new and old toolbar API may not be mixed in usage.
32 #include <gtk/gtkversion.h>
33 #ifdef GTK_DISABLE_DEPRECATED
34 #undef GTK_DISABLE_DEPRECATED
35 #endif
36 
37 #include "wx/gtk/private.h"
38 
39 // ----------------------------------------------------------------------------
40 // globals
41 // ----------------------------------------------------------------------------
42 
43 // data
44 extern bool       g_blockEventsOnDrag;
45 extern wxCursor   g_globalCursor;
46 
47 // ----------------------------------------------------------------------------
48 // private functions
49 // ----------------------------------------------------------------------------
50 
51 // translate wxWidgets toolbar style flags to GTK orientation and style
GetGtkStyle(long style,GtkOrientation * orient,GtkToolbarStyle * gtkStyle)52 static void GetGtkStyle(long style,
53                         GtkOrientation *orient, GtkToolbarStyle *gtkStyle)
54 {
55     *orient = ( style & wxTB_LEFT || style & wxTB_RIGHT ) ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
56 
57 
58     if ( style & wxTB_TEXT )
59     {
60         *gtkStyle = style & wxTB_NOICONS
61                         ? GTK_TOOLBAR_TEXT
62                         : (
63                           style & wxTB_HORZ_LAYOUT ? GTK_TOOLBAR_BOTH_HORIZ :
64                           GTK_TOOLBAR_BOTH);
65     }
66     else // no text, hence we must have the icons or what would we show?
67     {
68         *gtkStyle = GTK_TOOLBAR_ICONS;
69     }
70 }
71 
72 // ----------------------------------------------------------------------------
73 // wxToolBarTool
74 // ----------------------------------------------------------------------------
75 
76 class wxToolBarTool : public wxToolBarToolBase
77 {
78 public:
wxToolBarTool(wxToolBar * tbar,int id,const wxString & label,const wxBitmap & bitmap1,const wxBitmap & bitmap2,wxItemKind kind,wxObject * clientData,const wxString & shortHelpString,const wxString & longHelpString)79     wxToolBarTool(wxToolBar *tbar,
80                   int id,
81                   const wxString& label,
82                   const wxBitmap& bitmap1,
83                   const wxBitmap& bitmap2,
84                   wxItemKind kind,
85                   wxObject *clientData,
86                   const wxString& shortHelpString,
87                   const wxString& longHelpString)
88         : wxToolBarToolBase(tbar, id, label, bitmap1, bitmap2, kind,
89                             clientData, shortHelpString, longHelpString)
90     {
91         Init();
92     }
93 
wxToolBarTool(wxToolBar * tbar,wxControl * control)94     wxToolBarTool(wxToolBar *tbar, wxControl *control)
95         : wxToolBarToolBase(tbar, control)
96     {
97         Init();
98         // Hold a reference to keep control alive until DoInsertTool() is
99         // called, or if RemoveTool() is called (see DoDeleteTool)
100         g_object_ref(control->m_widget);
101         // release reference when gtk_widget_destroy() is called on control
102         g_signal_connect(
103             control->m_widget, "destroy", G_CALLBACK(g_object_unref), NULL);
104     }
105 
106     // is this a radio button?
107     //
108     // unlike GetKind(), can be called for any kind of tools, not just buttons
IsRadio() const109     bool IsRadio() const { return IsButton() && GetKind() == wxITEM_RADIO; }
110 
111     // this is only called for the normal buttons, i.e. not separators nor
112     // controls
GetGtkChildType() const113     GtkToolbarChildType GetGtkChildType() const
114     {
115         switch ( GetKind() )
116         {
117             case wxITEM_CHECK:
118                 return GTK_TOOLBAR_CHILD_TOGGLEBUTTON;
119 
120             case wxITEM_RADIO:
121                 return GTK_TOOLBAR_CHILD_RADIOBUTTON;
122 
123             default:
124                 wxFAIL_MSG( _T("unknown toolbar child type") );
125                 // fall through
126 
127             case wxITEM_NORMAL:
128                 return GTK_TOOLBAR_CHILD_BUTTON;
129         }
130     }
131 
SetImage(const wxBitmap & bitmap)132     void SetImage(const wxBitmap& bitmap)
133     {
134         if (bitmap.Ok())
135         {
136             // setting from pixmap doesn't seem to work right, but pixbuf works well
137             gtk_image_set_from_pixbuf((GtkImage*)m_image, bitmap.GetPixbuf());
138         }
139     }
140 
141     GtkWidget            *m_item;
142     GtkWidget            *m_image;
143 
144 protected:
145     void Init();
146 };
147 
148 // ----------------------------------------------------------------------------
149 // wxWin macros
150 // ----------------------------------------------------------------------------
151 
IMPLEMENT_DYNAMIC_CLASS(wxToolBar,wxControl)152 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
153 
154 // ============================================================================
155 // implementation
156 // ============================================================================
157 
158 //-----------------------------------------------------------------------------
159 // "clicked" (internal from gtk_toolbar)
160 //-----------------------------------------------------------------------------
161 
162 extern "C" {
163 static void gtk_toolbar_callback( GtkWidget *widget,
164                                   wxToolBarTool *tool )
165 {
166     if (g_isIdle)
167         wxapp_install_idle_handler();
168 
169     wxToolBar *tbar = (wxToolBar *)tool->GetToolBar();
170 
171     if (tbar->m_blockEvent) return;
172 
173     if (g_blockEventsOnDrag) return;
174     if (!tool->IsEnabled()) return;
175 
176     if (tool->CanBeToggled())
177     {
178         if (tool->IsRadio() &&
179             gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget)) &&
180             tool->IsToggled())
181         {
182             // pressed an already pressed radio button
183             return;
184         }
185 
186         tool->Toggle();
187 
188         tool->SetImage(tool->GetBitmap());
189 
190         if ( tool->IsRadio() && !tool->IsToggled() )
191         {
192             // radio button went up, don't report this as a wxWin event
193             return;
194         }
195     }
196 
197     if( !tbar->OnLeftClick( tool->GetId(), tool->IsToggled() ) && tool->CanBeToggled() )
198     {
199         // revert back
200         tool->Toggle();
201 
202         tool->SetImage(tool->GetBitmap());
203     }
204 }
205 }
206 
207 //-----------------------------------------------------------------------------
208 // "right-click"
209 //-----------------------------------------------------------------------------
210 extern "C" {
gtk_toolbar_tool_rclick_callback(GtkWidget * WXUNUSED (widget),GdkEventButton * event,wxToolBarToolBase * tool)211 static gboolean gtk_toolbar_tool_rclick_callback(GtkWidget *WXUNUSED(widget),
212                                                  GdkEventButton *event,
213                                                  wxToolBarToolBase *tool)
214 {
215     if (event->button != 3)
216         return FALSE;
217 
218     wxToolBar *tbar = (wxToolBar *)tool->GetToolBar();
219 
220     if (tbar->m_blockEvent) return TRUE;
221 
222     if (g_blockEventsOnDrag) return TRUE;
223     if (!tool->IsEnabled()) return TRUE;
224 
225     tbar->OnRightClick( tool->GetId(), (int)event->x, (int)event->y );
226 
227     return TRUE;
228 }
229 }
230 
231 //-----------------------------------------------------------------------------
232 // "enter_notify_event" / "leave_notify_event"
233 //-----------------------------------------------------------------------------
234 
235 extern "C" {
gtk_toolbar_tool_callback(GtkWidget * WXUNUSED (widget),GdkEventCrossing * gdk_event,wxToolBarTool * tool)236 static gint gtk_toolbar_tool_callback( GtkWidget *WXUNUSED(widget),
237                                        GdkEventCrossing *gdk_event,
238                                        wxToolBarTool *tool )
239 {
240     // don't need to install idle handler, its done from "event" signal
241 
242     if (g_blockEventsOnDrag) return TRUE;
243 
244     wxToolBar *tb = (wxToolBar *)tool->GetToolBar();
245 
246     // emit the event
247     if( gdk_event->type == GDK_ENTER_NOTIFY )
248         tb->OnMouseEnter( tool->GetId() );
249     else
250         tb->OnMouseEnter( -1 );
251 
252     return FALSE;
253 }
254 }
255 
256 //-----------------------------------------------------------------------------
257 // InsertChild callback for wxToolBar
258 //-----------------------------------------------------------------------------
259 
wxInsertChildInToolBar(wxToolBar * WXUNUSED (parent),wxWindow *)260 static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent),
261                                     wxWindow* /* child */)
262 {
263      // Child widget will be inserted into GtkToolbar by DoInsertTool()
264 }
265 
266 // ----------------------------------------------------------------------------
267 // wxToolBarTool
268 // ----------------------------------------------------------------------------
269 
Init()270 void wxToolBarTool::Init()
271 {
272     m_item =
273     m_image = NULL;
274 }
275 
CreateTool(int id,const wxString & text,const wxBitmap & bitmap1,const wxBitmap & bitmap2,wxItemKind kind,wxObject * clientData,const wxString & shortHelpString,const wxString & longHelpString)276 wxToolBarToolBase *wxToolBar::CreateTool(int id,
277                                          const wxString& text,
278                                          const wxBitmap& bitmap1,
279                                          const wxBitmap& bitmap2,
280                                          wxItemKind kind,
281                                          wxObject *clientData,
282                                          const wxString& shortHelpString,
283                                          const wxString& longHelpString)
284 {
285     return new wxToolBarTool(this, id, text, bitmap1, bitmap2, kind,
286                              clientData, shortHelpString, longHelpString);
287 }
288 
CreateTool(wxControl * control)289 wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
290 {
291     return new wxToolBarTool(this, control);
292 }
293 
294 //-----------------------------------------------------------------------------
295 // wxToolBar construction
296 //-----------------------------------------------------------------------------
297 
Init()298 void wxToolBar::Init()
299 {
300     m_toolbar = (GtkToolbar *)NULL;
301     m_blockEvent = false;
302     m_defaultWidth = 32;
303     m_defaultHeight = 32;
304 }
305 
~wxToolBar()306 wxToolBar::~wxToolBar()
307 {
308 }
309 
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)310 bool wxToolBar::Create( wxWindow *parent,
311                         wxWindowID id,
312                         const wxPoint& pos,
313                         const wxSize& size,
314                         long style,
315                         const wxString& name )
316 {
317     m_needParent = true;
318     m_insertCallback = (wxInsertChildFunction)wxInsertChildInToolBar;
319 
320     if ( !PreCreation( parent, pos, size ) ||
321          !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
322     {
323         wxFAIL_MSG( wxT("wxToolBar creation failed") );
324 
325         return false;
326     }
327 
328     FixupStyle();
329 
330     m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
331     GtkSetStyle();
332 
333     // Doesn't work this way.
334     // GtkToolbarSpaceStyle space_style = GTK_TOOLBAR_SPACE_EMPTY;
335     // gtk_widget_style_set (GTK_WIDGET (m_toolbar), "space_style", &space_style, NULL);
336 
337     SetToolSeparation(7);
338 
339     if (style & wxTB_DOCKABLE)
340     {
341         m_widget = gtk_handle_box_new();
342         gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
343         gtk_widget_show( GTK_WIDGET(m_toolbar) );
344 
345         if (style & wxTB_FLAT)
346             gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
347     }
348     else
349     {
350         m_widget = gtk_event_box_new();
351         gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
352         ConnectWidget( m_widget );
353         gtk_widget_show(GTK_WIDGET(m_toolbar));
354     }
355 
356     // FIXME: there is no such function for toolbars in 2.0
357 #if 0
358     if (style & wxTB_FLAT)
359         gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE );
360 #endif
361 
362     m_parent->DoAddChild( this );
363 
364     PostCreation(size);
365 
366     return true;
367 }
368 
GTKGetWindow(wxArrayGdkWindows & windows) const369 GdkWindow *wxToolBar::GTKGetWindow(wxArrayGdkWindows& windows) const
370 {
371     return GTK_WIDGET(m_toolbar)->window;
372 }
373 
GtkSetStyle()374 void wxToolBar::GtkSetStyle()
375 {
376     GtkOrientation orient;
377     GtkToolbarStyle style;
378     GetGtkStyle(GetWindowStyle(), &orient, &style);
379 
380     gtk_toolbar_set_orientation(m_toolbar, orient);
381     gtk_toolbar_set_style(m_toolbar, style);
382     gtk_toolbar_set_tooltips(m_toolbar, !(style & wxTB_NO_TOOLTIPS));
383 }
384 
SetWindowStyleFlag(long style)385 void wxToolBar::SetWindowStyleFlag( long style )
386 {
387     wxToolBarBase::SetWindowStyleFlag(style);
388 
389     if ( m_toolbar )
390         GtkSetStyle();
391 }
392 
DoInsertTool(size_t pos,wxToolBarToolBase * toolBase)393 bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
394 {
395     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, toolBase);
396 
397     if ( tool->IsButton() )
398     {
399         if ( !HasFlag(wxTB_NOICONS) )
400         {
401             wxBitmap bitmap = tool->GetNormalBitmap();
402 
403             wxCHECK_MSG( bitmap.Ok(), false,
404                          wxT("invalid bitmap for wxToolBar icon") );
405 
406             tool->m_image = gtk_image_new();
407             tool->SetImage(bitmap);
408 
409             gtk_misc_set_alignment((GtkMisc*)tool->m_image, 0.5, 0.5);
410         }
411     }
412 
413     const int posGtk = int(pos);
414 
415     switch ( tool->GetStyle() )
416     {
417         case wxTOOL_STYLE_BUTTON:
418             // for a radio button we need the widget which starts the radio
419             // group it belongs to, i.e. the first radio button immediately
420             // preceding this one
421             {
422                 GtkWidget *widget = NULL;
423 
424                 if ( tool->IsRadio() )
425                 {
426                     wxToolBarToolsList::compatibility_iterator node
427                         = wxToolBarToolsList::compatibility_iterator();
428                     if ( pos )
429                         node = m_tools.Item(pos - 1);
430 
431                     while ( node )
432                     {
433                         wxToolBarTool *toolNext = (wxToolBarTool *)node->GetData();
434                         if ( !toolNext->IsRadio() )
435                             break;
436 
437                         widget = toolNext->m_item;
438 
439                         node = node->GetPrevious();
440                     }
441 
442                     if ( !widget )
443                     {
444                         // this is the first button in the radio button group,
445                         // it will be toggled automatically by GTK so bring the
446                         // internal flag in sync
447                         tool->Toggle(true);
448                     }
449                 }
450 
451                 tool->m_item = gtk_toolbar_insert_element
452                                (
453                                   m_toolbar,
454                                   tool->GetGtkChildType(),
455                                   widget,
456                                   tool->GetLabel().empty()
457                                     ? NULL
458                                     : (const char*) wxGTK_CONV( tool->GetLabel() ),
459                                   tool->GetShortHelp().empty()
460                                     ? NULL
461                                     : (const char*) wxGTK_CONV( tool->GetShortHelp() ),
462                                   "", // tooltip_private_text (?)
463                                   tool->m_image,
464                                   (GtkSignalFunc)gtk_toolbar_callback,
465                                   (gpointer)tool,
466                                   posGtk
467                                );
468 
469                 wxCHECK_MSG(tool->m_item != NULL, false, _T("gtk_toolbar_insert_element() failed"));
470 
471                 g_signal_connect (tool->m_item, "enter_notify_event",
472                                   G_CALLBACK (gtk_toolbar_tool_callback),
473                                   tool);
474                 g_signal_connect (tool->m_item, "leave_notify_event",
475                                   G_CALLBACK (gtk_toolbar_tool_callback),
476                                   tool);
477                 g_signal_connect(tool->m_item, "button-press-event",
478                                   G_CALLBACK (gtk_toolbar_tool_rclick_callback),
479                                   tool);
480             }
481             break;
482 
483         case wxTOOL_STYLE_SEPARATOR:
484             gtk_toolbar_insert_space( m_toolbar, posGtk );
485 
486             // skip the rest
487             return true;
488 
489         case wxTOOL_STYLE_CONTROL:
490             GtkWidget* align = gtk_alignment_new(0.5, 0.5, 0, 0);
491             gtk_widget_show(align);
492             gtk_container_add((GtkContainer*)align, tool->GetControl()->m_widget);
493             gtk_toolbar_insert_widget(
494                                        m_toolbar,
495                                        align,
496                                        (const char *) NULL,
497                                        (const char *) NULL,
498                                        posGtk
499                                       );
500             tool->m_item = align;
501             break;
502     }
503 
504     GtkRequisition req;
505     (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
506         (m_widget, &req );
507     m_width = req.width + m_xMargin;
508     m_height = req.height + 2*m_yMargin;
509     InvalidateBestSize();
510 
511     return true;
512 }
513 
DoDeleteTool(size_t pos,wxToolBarToolBase * toolBase)514 bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *toolBase)
515 {
516     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, toolBase);
517 
518     switch ( tool->GetStyle() )
519     {
520         case wxTOOL_STYLE_CONTROL:
521             // don't destroy the control here as we can be called from
522             // RemoveTool() and then we need to keep the control alive;
523             // while if we're called from DeleteTool() the control will
524             // be destroyed when wxToolBarToolBase itself is deleted
525             gtk_container_remove(
526                 GTK_CONTAINER(tool->m_item), tool->GetControl()->m_widget);
527             // fall through
528 
529         case wxTOOL_STYLE_BUTTON:
530             gtk_widget_destroy( tool->m_item );
531             tool->m_item = NULL;
532             break;
533 
534         case wxTOOL_STYLE_SEPARATOR:
535             gtk_toolbar_remove_space( m_toolbar, pos );
536             break;
537     }
538 
539     InvalidateBestSize();
540     return true;
541 }
542 
543 // ----------------------------------------------------------------------------
544 // wxToolBar tools state
545 // ----------------------------------------------------------------------------
546 
DoEnableTool(wxToolBarToolBase * toolBase,bool enable)547 void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
548 {
549     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, toolBase);
550 
551     if (tool->m_item)
552     {
553         gtk_widget_set_sensitive( tool->m_item, enable );
554     }
555 }
556 
DoToggleTool(wxToolBarToolBase * toolBase,bool toggle)557 void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle )
558 {
559     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, toolBase);
560 
561     GtkWidget *item = tool->m_item;
562     if ( item && GTK_IS_TOGGLE_BUTTON(item) )
563     {
564         tool->SetImage(tool->GetBitmap());
565 
566         m_blockEvent = true;
567 
568         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(item), toggle );
569 
570         m_blockEvent = false;
571     }
572 }
573 
DoSetToggle(wxToolBarToolBase * WXUNUSED (tool),bool WXUNUSED (toggle))574 void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
575                             bool WXUNUSED(toggle))
576 {
577     // VZ: absolutely no idea about how to do it
578     wxFAIL_MSG( _T("not implemented") );
579 }
580 
581 // ----------------------------------------------------------------------------
582 // wxToolBar geometry
583 // ----------------------------------------------------------------------------
584 
FindToolForPosition(wxCoord WXUNUSED (x),wxCoord WXUNUSED (y)) const585 wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x),
586                                                   wxCoord WXUNUSED(y)) const
587 {
588     // VZ: GTK+ doesn't seem to have such thing
589     wxFAIL_MSG( _T("wxToolBar::FindToolForPosition() not implemented") );
590 
591     return (wxToolBarToolBase *)NULL;
592 }
593 
SetMargins(int x,int y)594 void wxToolBar::SetMargins( int x, int y )
595 {
596     wxCHECK_RET( GetToolsCount() == 0,
597                  wxT("wxToolBar::SetMargins must be called before adding tools.") );
598 
599     m_xMargin = x;
600     m_yMargin = y;
601 }
602 
SetToolSeparation(int separation)603 void wxToolBar::SetToolSeparation( int separation )
604 {
605     // FIXME: this function disappeared
606 #if 0
607     gtk_toolbar_set_space_size( m_toolbar, separation );
608 #endif
609 
610     m_toolSeparation = separation;
611 }
612 
SetToolShortHelp(int id,const wxString & helpString)613 void wxToolBar::SetToolShortHelp( int id, const wxString& helpString )
614 {
615     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
616 
617     if ( tool )
618     {
619         (void)tool->SetShortHelp(helpString);
620         gtk_tooltips_set_tip(m_toolbar->tooltips, tool->m_item,
621                              wxGTK_CONV( helpString ), "");
622     }
623 }
624 
SetToolNormalBitmap(int id,const wxBitmap & bitmap)625 void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
626 {
627     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
628     if ( tool )
629     {
630         wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
631 
632         tool->SetNormalBitmap(bitmap);
633         tool->SetImage(tool->GetBitmap());
634     }
635 }
636 
SetToolDisabledBitmap(int id,const wxBitmap & bitmap)637 void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
638 {
639     wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
640     if ( tool )
641     {
642         wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
643 
644         tool->SetDisabledBitmap(bitmap);
645         tool->SetImage(tool->GetBitmap());
646     }
647 }
648 
649 // ----------------------------------------------------------------------------
650 // wxToolBar idle handling
651 // ----------------------------------------------------------------------------
652 
OnInternalIdle()653 void wxToolBar::OnInternalIdle()
654 {
655     // Check if we have to show window now
656     if (GtkShowFromOnIdle()) return;
657 
658     wxCursor cursor = m_cursor;
659     if (g_globalCursor.Ok()) cursor = g_globalCursor;
660 
661     if (cursor.Ok())
662     {
663         /* I now set the cursor the anew in every OnInternalIdle call
664            as setting the cursor in a parent window also effects the
665            windows above so that checking for the current cursor is
666            not possible. */
667 
668         if (HasFlag(wxTB_DOCKABLE) && (m_widget->window))
669         {
670             /* if the toolbar is dockable, then m_widget stands for the
671                GtkHandleBox widget, which uses its own window so that we
672                can set the cursor for it. if the toolbar is not dockable,
673                m_widget comes from m_toolbar which uses its parent's
674                window ("windowless windows") and thus we cannot set the
675                cursor. */
676             gdk_window_set_cursor( m_widget->window, cursor.GetCursor() );
677         }
678 
679         wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
680         while ( node )
681         {
682             wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
683             node = node->GetNext();
684 
685             GtkWidget *item = tool->m_item;
686             if ( item )
687             {
688                 GdkWindow *window = item->window;
689 
690                 if ( window )
691                 {
692                     gdk_window_set_cursor( window, cursor.GetCursor() );
693                 }
694             }
695         }
696     }
697 
698     if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
699         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
700 }
701 
702 
703 // ----------------------------------------------------------------------------
704 
705 // static
706 wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant WXUNUSED (variant))707 wxToolBar::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
708 {
709     return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new);
710 }
711 
712 #endif // wxUSE_TOOLBAR_NATIVE
713