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