support for GTK3
[wxWidgets.git] / src / gtk / toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/toolbar.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 #include <gtk/gtk.h>
19 #include "wx/gtk/private.h"
20 #include "wx/gtk/private/gtk2-compat.h"
21
22 // ----------------------------------------------------------------------------
23 // globals
24 // ----------------------------------------------------------------------------
25
26 // data
27 extern bool g_blockEventsOnDrag;
28 extern wxCursor g_globalCursor;
29
30 // ----------------------------------------------------------------------------
31 // wxToolBarTool
32 // ----------------------------------------------------------------------------
33
34 class wxToolBarTool : public wxToolBarToolBase
35 {
36 public:
37 wxToolBarTool(wxToolBar *tbar,
38 int id,
39 const wxString& label,
40 const wxBitmap& bitmap1,
41 const wxBitmap& bitmap2,
42 wxItemKind kind,
43 wxObject *clientData,
44 const wxString& shortHelpString,
45 const wxString& longHelpString)
46 : wxToolBarToolBase(tbar, id, label, bitmap1, bitmap2, kind,
47 clientData, shortHelpString, longHelpString)
48 {
49 m_item = NULL;
50 }
51
52 wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
53 : wxToolBarToolBase(tbar, control, label)
54 {
55 m_item = NULL;
56 }
57
58 void SetImage();
59 void CreateDropDown();
60 void ShowDropdown(GtkToggleButton* button);
61
62 GtkToolItem* m_item;
63 };
64
65 // ----------------------------------------------------------------------------
66 // wxWin macros
67 // ----------------------------------------------------------------------------
68
69 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
70
71 // ============================================================================
72 // implementation
73 // ============================================================================
74
75 //-----------------------------------------------------------------------------
76 // "clicked" from m_item
77 //-----------------------------------------------------------------------------
78
79 extern "C" {
80 static void item_clicked(GtkToolButton*, wxToolBarTool* tool)
81 {
82 if (g_blockEventsOnDrag) return;
83
84 tool->GetToolBar()->OnLeftClick(tool->GetId(), false);
85 }
86 }
87
88 //-----------------------------------------------------------------------------
89 // "toggled" from m_item
90 //-----------------------------------------------------------------------------
91
92 extern "C" {
93 static void item_toggled(GtkToggleToolButton* button, wxToolBarTool* tool)
94 {
95 if (g_blockEventsOnDrag) return;
96
97 const bool active = gtk_toggle_tool_button_get_active(button) != 0;
98 tool->Toggle(active);
99 if (!active && tool->GetKind() == wxITEM_RADIO)
100 return;
101
102 if (!tool->GetToolBar()->OnLeftClick(tool->GetId(), active))
103 {
104 // revert back
105 tool->Toggle();
106 }
107 }
108 }
109
110 //-----------------------------------------------------------------------------
111 // "button_press_event" from m_item child
112 //-----------------------------------------------------------------------------
113
114 extern "C" {
115 static gboolean
116 button_press_event(GtkWidget*, GdkEventButton* event, wxToolBarTool* tool)
117 {
118 if (event->button != 3)
119 return FALSE;
120
121 if (g_blockEventsOnDrag) return TRUE;
122
123 tool->GetToolBar()->OnRightClick(
124 tool->GetId(), int(event->x), int(event->y));
125
126 return TRUE;
127 }
128 }
129
130 //-----------------------------------------------------------------------------
131 // "child_detached" from m_widget
132 //-----------------------------------------------------------------------------
133
134 extern "C" {
135 static void child_detached(GtkWidget*, GtkToolbar* toolbar, void*)
136 {
137 // disable showing overflow arrow when toolbar is detached,
138 // otherwise toolbar collapses to just an arrow
139 gtk_toolbar_set_show_arrow(toolbar, false);
140 }
141 }
142
143 //-----------------------------------------------------------------------------
144 // "child_attached" from m_widget
145 //-----------------------------------------------------------------------------
146
147 extern "C" {
148 static void child_attached(GtkWidget*, GtkToolbar* toolbar, void*)
149 {
150 gtk_toolbar_set_show_arrow(toolbar, true);
151 }
152 }
153
154 //-----------------------------------------------------------------------------
155 // "enter_notify_event" / "leave_notify_event" from m_item
156 //-----------------------------------------------------------------------------
157
158 extern "C" {
159 static gboolean
160 enter_notify_event(GtkWidget*, GdkEventCrossing* event, wxToolBarTool* tool)
161 {
162 if (g_blockEventsOnDrag) return TRUE;
163
164 int id = -1;
165 if (event->type == GDK_ENTER_NOTIFY)
166 id = tool->GetId();
167 tool->GetToolBar()->OnMouseEnter(id);
168
169 return FALSE;
170 }
171 }
172
173 //-----------------------------------------------------------------------------
174 // "expose_event" from GtkImage inside m_item
175 //-----------------------------------------------------------------------------
176
177 extern "C" {
178 static gboolean
179 #ifdef __WXGTK3__
180 image_draw(GtkWidget* widget, cairo_t* cr, wxToolBarTool* tool)
181 #else
182 image_expose_event(GtkWidget* widget, GdkEventExpose*, wxToolBarTool* tool)
183 #endif
184 {
185 const wxBitmap& bitmap = tool->GetDisabledBitmap();
186 if (tool->IsEnabled() || !bitmap.IsOk())
187 return false;
188
189 // draw disabled bitmap ourselves, GtkImage has no way to specify it
190 GtkAllocation alloc;
191 gtk_widget_get_allocation(widget, &alloc);
192 GtkRequisition req;
193 gtk_widget_get_requisition(widget, &req);
194 const int x = alloc.x + (alloc.width - req.width) / 2;
195 const int y = alloc.y + (alloc.height - req.height) / 2;
196 #ifdef __WXGTK3__
197 bitmap.Draw(cr, x, y);
198 #else
199 gdk_draw_pixbuf(
200 gtk_widget_get_window(widget), gtk_widget_get_style(widget)->black_gc, bitmap.GetPixbuf(),
201 0, 0, x, y,
202 -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0);
203 #endif
204 return true;
205 }
206 }
207
208 //-----------------------------------------------------------------------------
209 // "toggled" from dropdown menu button
210 //-----------------------------------------------------------------------------
211
212 extern "C" {
213 static void arrow_toggled(GtkToggleButton* button, wxToolBarTool* tool)
214 {
215 if (gtk_toggle_button_get_active(button))
216 {
217 tool->ShowDropdown(button);
218 gtk_toggle_button_set_active(button, false);
219 }
220 }
221 }
222
223 //-----------------------------------------------------------------------------
224 // "button_press_event" from dropdown menu button
225 //-----------------------------------------------------------------------------
226
227 extern "C" {
228 static gboolean
229 arrow_button_press_event(GtkToggleButton* button, GdkEventButton* event, wxToolBarTool* tool)
230 {
231 if (event->button == 1)
232 {
233 g_signal_handlers_block_by_func(button, (void*)arrow_toggled, tool);
234 gtk_toggle_button_set_active(button, true);
235 tool->ShowDropdown(button);
236 gtk_toggle_button_set_active(button, false);
237 g_signal_handlers_unblock_by_func(button, (void*)arrow_toggled, tool);
238 return true;
239 }
240 return false;
241 }
242 }
243
244 void wxToolBar::AddChildGTK(wxWindowGTK* child)
245 {
246 GtkWidget* align = gtk_alignment_new(0.5, 0.5, 0, 0);
247 gtk_widget_show(align);
248 gtk_container_add(GTK_CONTAINER(align), child->m_widget);
249 GtkToolItem* item = gtk_tool_item_new();
250 gtk_container_add(GTK_CONTAINER(item), align);
251 // position will be corrected in DoInsertTool if necessary
252 gtk_toolbar_insert(GTK_TOOLBAR(gtk_bin_get_child(GTK_BIN(m_widget))), item, -1);
253 }
254
255 // ----------------------------------------------------------------------------
256 // wxToolBarTool
257 // ----------------------------------------------------------------------------
258
259 void wxToolBarTool::SetImage()
260 {
261 const wxBitmap& bitmap = GetNormalBitmap();
262 wxCHECK_RET(bitmap.IsOk(), "invalid bitmap for wxToolBar icon");
263
264 GtkWidget* image = gtk_tool_button_get_icon_widget(GTK_TOOL_BUTTON(m_item));
265 // always use pixbuf, because pixmap mask does not
266 // work with disabled images in some themes
267 gtk_image_set_from_pixbuf(GTK_IMAGE(image), bitmap.GetPixbuf());
268 }
269
270 // helper to create a dropdown menu item
271 void wxToolBarTool::CreateDropDown()
272 {
273 gtk_tool_item_set_homogeneous(m_item, false);
274 GtkWidget* box;
275 GtkWidget* arrow;
276 if (GetToolBar()->HasFlag(wxTB_LEFT | wxTB_RIGHT))
277 {
278 box = gtk_vbox_new(false, 0);
279 arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
280 }
281 else
282 {
283 box = gtk_hbox_new(false, 0);
284 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
285 }
286 GtkWidget* tool_button = gtk_bin_get_child(GTK_BIN(m_item));
287 gtk_widget_reparent(tool_button, box);
288 GtkWidget* arrow_button = gtk_toggle_button_new();
289 gtk_button_set_relief(GTK_BUTTON(arrow_button),
290 gtk_tool_item_get_relief_style(GTK_TOOL_ITEM(m_item)));
291 gtk_container_add(GTK_CONTAINER(arrow_button), arrow);
292 gtk_container_add(GTK_CONTAINER(box), arrow_button);
293 gtk_widget_show_all(box);
294 gtk_container_add(GTK_CONTAINER(m_item), box);
295
296 g_signal_connect(arrow_button, "toggled", G_CALLBACK(arrow_toggled), this);
297 g_signal_connect(arrow_button, "button_press_event",
298 G_CALLBACK(arrow_button_press_event), this);
299 }
300
301 void wxToolBarTool::ShowDropdown(GtkToggleButton* button)
302 {
303 wxToolBarBase* toolbar = GetToolBar();
304 wxCommandEvent event(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, GetId());
305 if (!toolbar->HandleWindowEvent(event))
306 {
307 wxMenu* menu = GetDropdownMenu();
308 if (menu)
309 {
310 GtkAllocation alloc;
311 gtk_widget_get_allocation(GTK_WIDGET(button), &alloc);
312 int x = alloc.x;
313 int y = alloc.y;
314 if (toolbar->HasFlag(wxTB_LEFT | wxTB_RIGHT))
315 x += alloc.width;
316 else
317 y += alloc.height;
318 toolbar->PopupMenu(menu, x, y);
319 }
320 }
321 }
322
323 wxToolBarToolBase *wxToolBar::CreateTool(int id,
324 const wxString& text,
325 const wxBitmap& bitmap1,
326 const wxBitmap& bitmap2,
327 wxItemKind kind,
328 wxObject *clientData,
329 const wxString& shortHelpString,
330 const wxString& longHelpString)
331 {
332 return new wxToolBarTool(this, id, text, bitmap1, bitmap2, kind,
333 clientData, shortHelpString, longHelpString);
334 }
335
336 wxToolBarToolBase *
337 wxToolBar::CreateTool(wxControl *control, const wxString& label)
338 {
339 return new wxToolBarTool(this, control, label);
340 }
341
342 //-----------------------------------------------------------------------------
343 // wxToolBar construction
344 //-----------------------------------------------------------------------------
345
346 void wxToolBar::Init()
347 {
348 m_toolbar = NULL;
349 m_tooltips = NULL;
350 }
351
352 wxToolBar::~wxToolBar()
353 {
354 #ifndef __WXGTK3__
355 if (m_tooltips) // always NULL if GTK >= 2.12
356 {
357 gtk_object_destroy(GTK_OBJECT(m_tooltips));
358 g_object_unref(m_tooltips);
359 }
360 #endif
361 }
362
363 bool wxToolBar::Create( wxWindow *parent,
364 wxWindowID id,
365 const wxPoint& pos,
366 const wxSize& size,
367 long style,
368 const wxString& name )
369 {
370 if ( !PreCreation( parent, pos, size ) ||
371 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
372 {
373 wxFAIL_MSG( wxT("wxToolBar creation failed") );
374
375 return false;
376 }
377
378 FixupStyle();
379
380 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
381 #ifndef __WXGTK3__
382 if (gtk_check_version(2, 12, 0))
383 {
384 m_tooltips = gtk_tooltips_new();
385 g_object_ref(m_tooltips);
386 gtk_object_sink(GTK_OBJECT(m_tooltips));
387 }
388 #endif
389 GtkSetStyle();
390
391 if (style & wxTB_DOCKABLE)
392 {
393 m_widget = gtk_handle_box_new();
394
395 g_signal_connect(m_widget, "child_detached",
396 G_CALLBACK(child_detached), NULL);
397 g_signal_connect(m_widget, "child_attached",
398 G_CALLBACK(child_attached), NULL);
399
400 if (style & wxTB_FLAT)
401 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
402 }
403 else
404 {
405 m_widget = gtk_event_box_new();
406 ConnectWidget( m_widget );
407 }
408 g_object_ref(m_widget);
409 gtk_container_add(GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar));
410 gtk_widget_show(GTK_WIDGET(m_toolbar));
411
412 m_parent->DoAddChild( this );
413
414 PostCreation(size);
415
416 return true;
417 }
418
419 GdkWindow *wxToolBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
420 {
421 return gtk_widget_get_window(GTK_WIDGET(m_toolbar));
422 }
423
424 void wxToolBar::GtkSetStyle()
425 {
426 GtkOrientation orient = GTK_ORIENTATION_HORIZONTAL;
427 if (HasFlag(wxTB_LEFT | wxTB_RIGHT))
428 orient = GTK_ORIENTATION_VERTICAL;
429
430 GtkToolbarStyle style = GTK_TOOLBAR_ICONS;
431 if (HasFlag(wxTB_NOICONS))
432 style = GTK_TOOLBAR_TEXT;
433 else if (HasFlag(wxTB_TEXT))
434 {
435 style = GTK_TOOLBAR_BOTH;
436 if (HasFlag(wxTB_HORZ_LAYOUT))
437 style = GTK_TOOLBAR_BOTH_HORIZ;
438 }
439
440 #ifdef __WXGTK3__
441 gtk_orientable_set_orientation(GTK_ORIENTABLE(m_toolbar), orient);
442 #else
443 gtk_toolbar_set_orientation(m_toolbar, orient);
444 #endif
445 gtk_toolbar_set_style(m_toolbar, style);
446 }
447
448 void wxToolBar::SetWindowStyleFlag( long style )
449 {
450 wxToolBarBase::SetWindowStyleFlag(style);
451
452 if ( m_toolbar )
453 GtkSetStyle();
454 }
455
456 bool wxToolBar::Realize()
457 {
458 if ( !wxToolBarBase::Realize() )
459 return false;
460
461 // bring the initial state of all the toolbar items in line with the
462 // internal state if the latter was changed by calling wxToolBarTool::
463 // Enable(): this works under MSW, where the toolbar items are only created
464 // in Realize() which uses the internal state to determine the initial
465 // button state, so make it work under GTK too
466 for ( wxToolBarToolsList::const_iterator i = m_tools.begin();
467 i != m_tools.end();
468 ++i )
469 {
470 // by default the toolbar items are enabled and not toggled, so we only
471 // have to do something if their internal state doesn't correspond to
472 // this
473 if ( !(*i)->IsEnabled() )
474 DoEnableTool(*i, false);
475 if ( (*i)->IsToggled() )
476 DoToggleTool(*i, true);
477 }
478
479 return true;
480 }
481
482 bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
483 {
484 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
485
486 GSList* radioGroup;
487 GtkWidget* bin_child;
488 switch ( tool->GetStyle() )
489 {
490 case wxTOOL_STYLE_BUTTON:
491 switch (tool->GetKind())
492 {
493 case wxITEM_CHECK:
494 tool->m_item = gtk_toggle_tool_button_new();
495 g_signal_connect(tool->m_item, "toggled",
496 G_CALLBACK(item_toggled), tool);
497 break;
498 case wxITEM_RADIO:
499 radioGroup = GetRadioGroup(pos);
500 if (!radioGroup)
501 {
502 // this is the first button in the radio button group,
503 // it will be toggled automatically by GTK so bring the
504 // internal flag in sync
505 tool->Toggle(true);
506 }
507 tool->m_item = gtk_radio_tool_button_new(radioGroup);
508 g_signal_connect(tool->m_item, "toggled",
509 G_CALLBACK(item_toggled), tool);
510 break;
511 default:
512 wxFAIL_MSG("unknown toolbar child type");
513 // fall through
514 case wxITEM_DROPDOWN:
515 case wxITEM_NORMAL:
516 tool->m_item = gtk_tool_button_new(NULL, "");
517 g_signal_connect(tool->m_item, "clicked",
518 G_CALLBACK(item_clicked), tool);
519 break;
520 }
521 if (!HasFlag(wxTB_NOICONS))
522 {
523 GtkWidget* image = gtk_image_new();
524 gtk_tool_button_set_icon_widget(
525 GTK_TOOL_BUTTON(tool->m_item), image);
526 tool->SetImage();
527 gtk_widget_show(image);
528 #ifdef __WXGTK3__
529 g_signal_connect(image, "draw",
530 G_CALLBACK(image_draw), tool);
531 #else
532 g_signal_connect(image, "expose_event",
533 G_CALLBACK(image_expose_event), tool);
534 #endif
535 }
536 if (!tool->GetLabel().empty())
537 {
538 gtk_tool_button_set_label(
539 GTK_TOOL_BUTTON(tool->m_item), wxGTK_CONV(tool->GetLabel()));
540 // needed for labels in horizontal toolbar with wxTB_HORZ_LAYOUT
541 gtk_tool_item_set_is_important(tool->m_item, true);
542 }
543 if (!HasFlag(wxTB_NO_TOOLTIPS) && !tool->GetShortHelp().empty())
544 {
545 #if GTK_CHECK_VERSION(2, 12, 0)
546 if (GTK_CHECK_VERSION(3,0,0) || gtk_check_version(2,12,0) == NULL)
547 {
548 gtk_tool_item_set_tooltip_text(tool->m_item,
549 wxGTK_CONV(tool->GetShortHelp()));
550 }
551 else
552 #endif
553 {
554 #ifndef __WXGTK3__
555 gtk_tool_item_set_tooltip(tool->m_item,
556 m_tooltips, wxGTK_CONV(tool->GetShortHelp()), "");
557 #endif
558 }
559 }
560 bin_child = gtk_bin_get_child(GTK_BIN(tool->m_item));
561 g_signal_connect(bin_child, "button_press_event",
562 G_CALLBACK(button_press_event), tool);
563 g_signal_connect(bin_child, "enter_notify_event",
564 G_CALLBACK(enter_notify_event), tool);
565 g_signal_connect(bin_child, "leave_notify_event",
566 G_CALLBACK(enter_notify_event), tool);
567
568 if (tool->GetKind() == wxITEM_DROPDOWN)
569 tool->CreateDropDown();
570 gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
571 break;
572
573 case wxTOOL_STYLE_SEPARATOR:
574 tool->m_item = gtk_separator_tool_item_new();
575 if ( tool->IsStretchable() )
576 {
577 gtk_separator_tool_item_set_draw
578 (
579 GTK_SEPARATOR_TOOL_ITEM(tool->m_item),
580 FALSE
581 );
582 gtk_tool_item_set_expand(tool->m_item, TRUE);
583 }
584 gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
585 break;
586
587 case wxTOOL_STYLE_CONTROL:
588 wxWindow* control = tool->GetControl();
589 if (gtk_widget_get_parent(control->m_widget) == NULL)
590 AddChildGTK(control);
591 tool->m_item = GTK_TOOL_ITEM(gtk_widget_get_parent(gtk_widget_get_parent(control->m_widget)));
592 if (gtk_toolbar_get_item_index(m_toolbar, tool->m_item) != int(pos))
593 {
594 g_object_ref(tool->m_item);
595 gtk_container_remove(
596 GTK_CONTAINER(m_toolbar), GTK_WIDGET(tool->m_item));
597 gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
598 g_object_unref(tool->m_item);
599 }
600 break;
601 }
602 gtk_widget_show(GTK_WIDGET(tool->m_item));
603
604 InvalidateBestSize();
605
606 return true;
607 }
608
609 bool wxToolBar::DoDeleteTool(size_t /* pos */, wxToolBarToolBase* toolBase)
610 {
611 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
612
613 if (tool->GetStyle() == wxTOOL_STYLE_CONTROL)
614 {
615 // don't destroy the control here as we can be called from
616 // RemoveTool() and then we need to keep the control alive;
617 // while if we're called from DeleteTool() the control will
618 // be destroyed when wxToolBarToolBase itself is deleted
619 GtkWidget* widget = tool->GetControl()->m_widget;
620 gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
621 }
622 gtk_widget_destroy(GTK_WIDGET(tool->m_item));
623 tool->m_item = NULL;
624
625 InvalidateBestSize();
626 return true;
627 }
628
629 GSList* wxToolBar::GetRadioGroup(size_t pos)
630 {
631 GSList* radioGroup = NULL;
632 GtkToolItem* item = NULL;
633 if (pos > 0)
634 {
635 item = gtk_toolbar_get_nth_item(m_toolbar, int(pos) - 1);
636 if (!GTK_IS_RADIO_TOOL_BUTTON(item))
637 item = NULL;
638 }
639 if (item == NULL && pos < m_tools.size())
640 {
641 item = gtk_toolbar_get_nth_item(m_toolbar, int(pos));
642 if (!GTK_IS_RADIO_TOOL_BUTTON(item))
643 item = NULL;
644 }
645 if (item)
646 radioGroup = gtk_radio_tool_button_get_group((GtkRadioToolButton*)item);
647 return radioGroup;
648 }
649
650 // ----------------------------------------------------------------------------
651 // wxToolBar tools state
652 // ----------------------------------------------------------------------------
653
654 void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
655 {
656 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
657
658 if (tool->m_item)
659 gtk_widget_set_sensitive(GTK_WIDGET(tool->m_item), enable);
660 }
661
662 void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle )
663 {
664 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
665
666 if (tool->m_item)
667 {
668 g_signal_handlers_block_by_func(tool->m_item, (void*)item_toggled, tool);
669
670 gtk_toggle_tool_button_set_active(
671 GTK_TOGGLE_TOOL_BUTTON(tool->m_item), toggle);
672
673 g_signal_handlers_unblock_by_func(tool->m_item, (void*)item_toggled, tool);
674 }
675 }
676
677 void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
678 bool WXUNUSED(toggle))
679 {
680 // VZ: absolutely no idea about how to do it
681 wxFAIL_MSG( wxT("not implemented") );
682 }
683
684 // ----------------------------------------------------------------------------
685 // wxToolBar geometry
686 // ----------------------------------------------------------------------------
687
688 wxSize wxToolBar::DoGetBestSize() const
689 {
690 // Unfortunately, if overflow arrow is enabled GtkToolbar only reports size
691 // of arrow. To get the real size, the arrow is temporarily disabled here.
692 // This is gross, since it will cause a queue_resize, and could potentially
693 // lead to an infinite loop. But there seems to be no alternative, short of
694 // disabling the arrow entirely.
695 gtk_toolbar_set_show_arrow(m_toolbar, false);
696 const wxSize size = wxToolBarBase::DoGetBestSize();
697 gtk_toolbar_set_show_arrow(m_toolbar, true);
698 return size;
699 }
700
701 wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x),
702 wxCoord WXUNUSED(y)) const
703 {
704 // VZ: GTK+ doesn't seem to have such thing
705 wxFAIL_MSG( wxT("wxToolBar::FindToolForPosition() not implemented") );
706
707 return NULL;
708 }
709
710 void wxToolBar::SetToolShortHelp( int id, const wxString& helpString )
711 {
712 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
713
714 if ( tool )
715 {
716 (void)tool->SetShortHelp(helpString);
717 if (tool->m_item)
718 {
719 #if GTK_CHECK_VERSION(2, 12, 0)
720 if (GTK_CHECK_VERSION(3,0,0) || gtk_check_version(2,12,0) == NULL)
721 {
722 gtk_tool_item_set_tooltip_text(tool->m_item,
723 wxGTK_CONV(helpString));
724 }
725 else
726 #endif
727 {
728 #ifndef __WXGTK3__
729 gtk_tool_item_set_tooltip(tool->m_item,
730 m_tooltips, wxGTK_CONV(helpString), "");
731 #endif
732 }
733 }
734 }
735 }
736
737 void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
738 {
739 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
740 if ( tool )
741 {
742 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
743
744 tool->SetNormalBitmap(bitmap);
745 tool->SetImage();
746 }
747 }
748
749 void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
750 {
751 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
752 if ( tool )
753 {
754 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
755
756 tool->SetDisabledBitmap(bitmap);
757 }
758 }
759
760 // ----------------------------------------------------------------------------
761
762 // static
763 wxVisualAttributes
764 wxToolBar::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
765 {
766 return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new);
767 }
768
769 #endif // wxUSE_TOOLBAR_NATIVE