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