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