]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/toolbar.cpp
new file added
[wxWidgets.git] / src / gtk / toolbar.cpp
... / ...
CommitLineData
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
27extern bool g_blockEventsOnDrag;
28extern wxCursor g_globalCursor;
29
30// ----------------------------------------------------------------------------
31// wxToolBarTool
32// ----------------------------------------------------------------------------
33
34class wxToolBarTool : public wxToolBarToolBase
35{
36public:
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
69IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
70
71// ============================================================================
72// implementation
73// ============================================================================
74
75//-----------------------------------------------------------------------------
76// "clicked" from m_item
77//-----------------------------------------------------------------------------
78
79extern "C" {
80static 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
92extern "C" {
93static 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
114extern "C" {
115static gboolean
116button_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
134extern "C" {
135static 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
147extern "C" {
148static 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
158extern "C" {
159static gboolean
160enter_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
177extern "C" {
178static gboolean
179#ifdef __WXGTK3__
180image_draw(GtkWidget* widget, cairo_t* cr, wxToolBarTool* tool)
181#else
182image_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
212extern "C" {
213static 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
227extern "C" {
228static gboolean
229arrow_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
244void 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
259void 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
271void 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
301void 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
323wxToolBarToolBase *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
336wxToolBarToolBase *
337wxToolBar::CreateTool(wxControl *control, const wxString& label)
338{
339 return new wxToolBarTool(this, control, label);
340}
341
342//-----------------------------------------------------------------------------
343// wxToolBar construction
344//-----------------------------------------------------------------------------
345
346void wxToolBar::Init()
347{
348 m_toolbar = NULL;
349 m_tooltips = NULL;
350}
351
352wxToolBar::~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
363bool 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
419GdkWindow *wxToolBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
420{
421 return gtk_widget_get_window(GTK_WIDGET(m_toolbar));
422}
423
424void 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
448void wxToolBar::SetWindowStyleFlag( long style )
449{
450 wxToolBarBase::SetWindowStyleFlag(style);
451
452 if ( m_toolbar )
453 GtkSetStyle();
454}
455
456bool 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
482bool 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
609bool 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
629GSList* 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
654void 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
662void 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
677void 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
688wxSize 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
701wxToolBarToolBase *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
710void 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
737void 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
749void 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
763wxVisualAttributes
764wxToolBar::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
765{
766 return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new);
767}
768
769#endif // wxUSE_TOOLBAR_NATIVE