]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/toolbar.cpp
new file added
[wxWidgets.git] / src / gtk / toolbar.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
0b83552a 2// Name: src/gtk/toolbar.cpp
c801d85f
KB
3// Purpose: GTK toolbar
4// Author: Robert Roebling
8a0681f9 5// Modified: 13.12.99 by VZ to derive from wxToolBarBase
32e9da8b 6// RCS-ID: $Id$
c801d85f 7// Copyright: (c) Robert Roebling
65571936 8// Licence: wxWindows licence
c801d85f
KB
9/////////////////////////////////////////////////////////////////////////////
10
14f355c2
VS
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
8a0681f9 14#if wxUSE_TOOLBAR_NATIVE
dcf924a3 15
4e3e485b
WS
16#include "wx/toolbar.h"
17
9dc44eff 18#include <gtk/gtk.h>
9e691f46 19#include "wx/gtk/private.h"
9dc44eff 20#include "wx/gtk/private/gtk2-compat.h"
fc6557a6 21
8a0681f9
VZ
22// ----------------------------------------------------------------------------
23// globals
24// ----------------------------------------------------------------------------
acfd422a 25
314055fa 26// data
9b7e522a
RR
27extern bool g_blockEventsOnDrag;
28extern wxCursor g_globalCursor;
314055fa 29
8a0681f9
VZ
30// ----------------------------------------------------------------------------
31// wxToolBarTool
32// ----------------------------------------------------------------------------
33
34class wxToolBarTool : public wxToolBarToolBase
35{
36public:
37 wxToolBarTool(wxToolBar *tbar,
38 int id,
e76c0b5f 39 const wxString& label,
8a0681f9
VZ
40 const wxBitmap& bitmap1,
41 const wxBitmap& bitmap2,
e76c0b5f 42 wxItemKind kind,
8a0681f9
VZ
43 wxObject *clientData,
44 const wxString& shortHelpString,
45 const wxString& longHelpString)
e76c0b5f 46 : wxToolBarToolBase(tbar, id, label, bitmap1, bitmap2, kind,
8a0681f9
VZ
47 clientData, shortHelpString, longHelpString)
48 {
a1cb0b11 49 m_item = NULL;
8a0681f9
VZ
50 }
51
07d02e9e
VZ
52 wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
53 : wxToolBarToolBase(tbar, control, label)
8a0681f9 54 {
a1cb0b11 55 m_item = NULL;
1be45608
VZ
56 }
57
a1cb0b11
PC
58 void SetImage();
59 void CreateDropDown();
60 void ShowDropdown(GtkToggleButton* button);
8a0681f9 61
a1cb0b11 62 GtkToolItem* m_item;
8a0681f9
VZ
63};
64
65// ----------------------------------------------------------------------------
66// wxWin macros
67// ----------------------------------------------------------------------------
68
2eb10e2a 69IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
8a0681f9
VZ
70
71// ============================================================================
72// implementation
73// ============================================================================
74
c801d85f 75//-----------------------------------------------------------------------------
a1cb0b11 76// "clicked" from m_item
c801d85f
KB
77//-----------------------------------------------------------------------------
78
865bb325 79extern "C" {
a1cb0b11 80static void item_clicked(GtkToolButton*, wxToolBarTool* tool)
c801d85f 81{
1144d24d 82 if (g_blockEventsOnDrag) return;
a3622daa 83
a1cb0b11
PC
84 tool->GetToolBar()->OnLeftClick(tool->GetId(), false);
85}
86}
7062497f 87
a1cb0b11
PC
88//-----------------------------------------------------------------------------
89// "toggled" from m_item
90//-----------------------------------------------------------------------------
8a0681f9 91
a1cb0b11
PC
92extern "C" {
93static void item_toggled(GtkToggleToolButton* button, wxToolBarTool* tool)
94{
95 if (g_blockEventsOnDrag) return;
38762f09 96
a1cb0b11
PC
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;
a3622daa 101
a1cb0b11 102 if (!tool->GetToolBar()->OnLeftClick(tool->GetId(), active))
6bb7cee4
VZ
103 {
104 // revert back
105 tool->Toggle();
6bb7cee4 106 }
fc008f25 107}
865bb325 108}
c801d85f 109
729b4756 110//-----------------------------------------------------------------------------
a1cb0b11 111// "button_press_event" from m_item child
729b4756 112//-----------------------------------------------------------------------------
a1cb0b11 113
729b4756 114extern "C" {
a1cb0b11
PC
115static gboolean
116button_press_event(GtkWidget*, GdkEventButton* event, wxToolBarTool* tool)
729b4756
RR
117{
118 if (event->button != 3)
119 return FALSE;
120
729b4756 121 if (g_blockEventsOnDrag) return TRUE;
729b4756 122
a1cb0b11
PC
123 tool->GetToolBar()->OnRightClick(
124 tool->GetId(), int(event->x), int(event->y));
729b4756
RR
125
126 return TRUE;
127}
128}
129
fc6557a6 130//-----------------------------------------------------------------------------
a1cb0b11 131// "child_detached" from m_widget
fc6557a6
RR
132//-----------------------------------------------------------------------------
133
134extern "C" {
a1cb0b11 135static void child_detached(GtkWidget*, GtkToolbar* toolbar, void*)
fc6557a6 136{
a1cb0b11
PC
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);
fc6557a6
RR
140}
141}
142
143//-----------------------------------------------------------------------------
a1cb0b11 144// "child_attached" from m_widget
fc6557a6
RR
145//-----------------------------------------------------------------------------
146
a1cb0b11
PC
147extern "C" {
148static void child_attached(GtkWidget*, GtkToolbar* toolbar, void*)
fc6557a6 149{
a1cb0b11 150 gtk_toolbar_set_show_arrow(toolbar, true);
fc6557a6
RR
151}
152}
153
2f2aa628 154//-----------------------------------------------------------------------------
a1cb0b11 155// "enter_notify_event" / "leave_notify_event" from m_item
2f2aa628
RR
156//-----------------------------------------------------------------------------
157
865bb325 158extern "C" {
a1cb0b11
PC
159static gboolean
160enter_notify_event(GtkWidget*, GdkEventCrossing* event, wxToolBarTool* tool)
314055fa 161{
1144d24d 162 if (g_blockEventsOnDrag) return TRUE;
248bcf0a 163
a1cb0b11
PC
164 int id = -1;
165 if (event->type == GDK_ENTER_NOTIFY)
166 id = tool->GetId();
167 tool->GetToolBar()->OnMouseEnter(id);
248bcf0a 168
1144d24d 169 return FALSE;
314055fa 170}
865bb325 171}
314055fa 172
a1cb0b11
PC
173//-----------------------------------------------------------------------------
174// "expose_event" from GtkImage inside m_item
175//-----------------------------------------------------------------------------
176
177extern "C" {
178static gboolean
9dc44eff
PC
179#ifdef __WXGTK3__
180image_draw(GtkWidget* widget, cairo_t* cr, wxToolBarTool* tool)
181#else
a1cb0b11 182image_expose_event(GtkWidget* widget, GdkEventExpose*, wxToolBarTool* tool)
9dc44eff 183#endif
a1cb0b11
PC
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
385e8575
PC
190 GtkAllocation alloc;
191 gtk_widget_get_allocation(widget, &alloc);
192 GtkRequisition req;
193 gtk_widget_get_requisition(widget, &req);
9dc44eff
PC
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
a1cb0b11 199 gdk_draw_pixbuf(
385e8575 200 gtk_widget_get_window(widget), gtk_widget_get_style(widget)->black_gc, bitmap.GetPixbuf(),
9dc44eff 201 0, 0, x, y,
a1cb0b11 202 -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0);
9dc44eff 203#endif
a1cb0b11
PC
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
48200154 244void wxToolBar::AddChildGTK(wxWindowGTK* child)
bf9e3e73 245{
205177b0
PC
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);
205177b0 251 // position will be corrected in DoInsertTool if necessary
385e8575 252 gtk_toolbar_insert(GTK_TOOLBAR(gtk_bin_get_child(GTK_BIN(m_widget))), item, -1);
bf9e3e73
RR
253}
254
8a0681f9
VZ
255// ----------------------------------------------------------------------------
256// wxToolBarTool
257// ----------------------------------------------------------------------------
c801d85f 258
a1cb0b11 259void wxToolBarTool::SetImage()
8a0681f9 260{
a1cb0b11
PC
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 }
385e8575 286 GtkWidget* tool_button = gtk_bin_get_child(GTK_BIN(m_item));
a1cb0b11
PC
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 {
385e8575 310 GtkAllocation alloc;
628e8d44 311 gtk_widget_get_allocation(GTK_WIDGET(button), &alloc);
a1cb0b11
PC
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 }
8a0681f9 321}
c801d85f 322
8a0681f9 323wxToolBarToolBase *wxToolBar::CreateTool(int id,
e76c0b5f 324 const wxString& text,
8a0681f9
VZ
325 const wxBitmap& bitmap1,
326 const wxBitmap& bitmap2,
e76c0b5f 327 wxItemKind kind,
8a0681f9
VZ
328 wxObject *clientData,
329 const wxString& shortHelpString,
330 const wxString& longHelpString)
331{
e76c0b5f 332 return new wxToolBarTool(this, id, text, bitmap1, bitmap2, kind,
8a0681f9
VZ
333 clientData, shortHelpString, longHelpString);
334}
b1da76e1 335
07d02e9e
VZ
336wxToolBarToolBase *
337wxToolBar::CreateTool(wxControl *control, const wxString& label)
c801d85f 338{
07d02e9e 339 return new wxToolBarTool(this, control, label);
fc008f25 340}
c801d85f 341
8a0681f9
VZ
342//-----------------------------------------------------------------------------
343// wxToolBar construction
344//-----------------------------------------------------------------------------
345
346void wxToolBar::Init()
c801d85f 347{
d3b9f782 348 m_toolbar = NULL;
a1cb0b11 349 m_tooltips = NULL;
fc008f25 350}
c801d85f 351
a3622daa 352wxToolBar::~wxToolBar()
c801d85f 353{
9dc44eff 354#ifndef __WXGTK3__
85314957 355 if (m_tooltips) // always NULL if GTK >= 2.12
a1cb0b11
PC
356 {
357 gtk_object_destroy(GTK_OBJECT(m_tooltips));
358 g_object_unref(m_tooltips);
359 }
9dc44eff 360#endif
fc008f25 361}
c801d85f 362
8a0681f9
VZ
363bool wxToolBar::Create( wxWindow *parent,
364 wxWindowID id,
365 const wxPoint& pos,
366 const wxSize& size,
367 long style,
368 const wxString& name )
c801d85f 369{
8a0681f9
VZ
370 if ( !PreCreation( parent, pos, size ) ||
371 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
4dcaf11a 372 {
223d09f6 373 wxFAIL_MSG( wxT("wxToolBar creation failed") );
c801d85f 374
91af0895 375 return false;
8a0681f9 376 }
a3622daa 377
d408730c
VZ
378 FixupStyle();
379
9e691f46 380 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
9dc44eff 381#ifndef __WXGTK3__
85314957
VZ
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 }
385e8575 388#endif
e76c0b5f 389 GtkSetStyle();
99e8cb50 390
3502e687
RR
391 if (style & wxTB_DOCKABLE)
392 {
393 m_widget = gtk_handle_box_new();
a1cb0b11
PC
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);
8a0681f9 399
f03fc89f 400 if (style & wxTB_FLAT)
858b5bdd 401 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
3502e687
RR
402 }
403 else
248bcf0a
RD
404 {
405 m_widget = gtk_event_box_new();
248bcf0a 406 ConnectWidget( m_widget );
3502e687 407 }
9ff9d30c 408 g_object_ref(m_widget);
a1cb0b11
PC
409 gtk_container_add(GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar));
410 gtk_widget_show(GTK_WIDGET(m_toolbar));
be25e480 411
f03fc89f 412 m_parent->DoAddChild( this );
8a0681f9 413
abdeb9e7 414 PostCreation(size);
a3622daa 415
91af0895 416 return true;
fc008f25 417}
c801d85f 418
e4161a2a 419GdkWindow *wxToolBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
48468900 420{
385e8575 421 return gtk_widget_get_window(GTK_WIDGET(m_toolbar));
48468900
RR
422}
423
e76c0b5f
VZ
424void wxToolBar::GtkSetStyle()
425{
a1cb0b11
PC
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 }
e76c0b5f 439
9dc44eff 440#ifdef __WXGTK3__
385e8575
PC
441 gtk_orientable_set_orientation(GTK_ORIENTABLE(m_toolbar), orient);
442#else
e76c0b5f 443 gtk_toolbar_set_orientation(m_toolbar, orient);
385e8575 444#endif
e76c0b5f
VZ
445 gtk_toolbar_set_style(m_toolbar, style);
446}
447
448void wxToolBar::SetWindowStyleFlag( long style )
449{
450 wxToolBarBase::SetWindowStyleFlag(style);
8ad31f9d 451
e76c0b5f
VZ
452 if ( m_toolbar )
453 GtkSetStyle();
454}
455
9067c6c5
VZ
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
8a0681f9 482bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
c801d85f 483{
5c33522f 484 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
248bcf0a 485
a1cb0b11 486 GSList* radioGroup;
fbf49ef2 487 GtkWidget* bin_child;
8a0681f9
VZ
488 switch ( tool->GetStyle() )
489 {
490 case wxTOOL_STYLE_BUTTON:
a1cb0b11 491 switch (tool->GetKind())
8a0681f9 492 {
a1cb0b11
PC
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);
d4a762e3 500 if (!radioGroup)
38762f09
VZ
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
91af0895 505 tool->Toggle(true);
38762f09 506 }
a1cb0b11
PC
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);
9dc44eff
PC
528#ifdef __WXGTK3__
529 g_signal_connect(image, "draw",
530 G_CALLBACK(image_draw), tool);
531#else
a1cb0b11
PC
532 g_signal_connect(image, "expose_event",
533 G_CALLBACK(image_expose_event), tool);
9dc44eff 534#endif
8a0681f9 535 }
a1cb0b11
PC
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 {
85314957 545#if GTK_CHECK_VERSION(2, 12, 0)
385e8575 546 if (GTK_CHECK_VERSION(3,0,0) || gtk_check_version(2,12,0) == NULL)
85314957
VZ
547 {
548 gtk_tool_item_set_tooltip_text(tool->m_item,
549 wxGTK_CONV(tool->GetShortHelp()));
550 }
551 else
552#endif
553 {
9dc44eff 554#ifndef __WXGTK3__
85314957
VZ
555 gtk_tool_item_set_tooltip(tool->m_item,
556 m_tooltips, wxGTK_CONV(tool->GetShortHelp()), "");
385e8575 557#endif
85314957 558 }
a1cb0b11 559 }
fbf49ef2
PC
560 bin_child = gtk_bin_get_child(GTK_BIN(tool->m_item));
561 g_signal_connect(bin_child, "button_press_event",
a1cb0b11 562 G_CALLBACK(button_press_event), tool);
fbf49ef2 563 g_signal_connect(bin_child, "enter_notify_event",
a1cb0b11 564 G_CALLBACK(enter_notify_event), tool);
fbf49ef2 565 g_signal_connect(bin_child, "leave_notify_event",
a1cb0b11
PC
566 G_CALLBACK(enter_notify_event), tool);
567
568 if (tool->GetKind() == wxITEM_DROPDOWN)
569 tool->CreateDropDown();
205177b0 570 gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
8a0681f9
VZ
571 break;
572
573 case wxTOOL_STYLE_SEPARATOR:
a1cb0b11 574 tool->m_item = gtk_separator_tool_item_new();
cc260109
VZ
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 }
205177b0 584 gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
1be45608 585 break;
bf9e3e73 586
8a0681f9 587 case wxTOOL_STYLE_CONTROL:
a1cb0b11 588 wxWindow* control = tool->GetControl();
385e8575 589 if (gtk_widget_get_parent(control->m_widget) == NULL)
48200154 590 AddChildGTK(control);
385e8575 591 tool->m_item = GTK_TOOL_ITEM(gtk_widget_get_parent(gtk_widget_get_parent(control->m_widget)));
205177b0
PC
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 }
8a0681f9
VZ
600 break;
601 }
a1cb0b11 602 gtk_widget_show(GTK_WIDGET(tool->m_item));
bf9e3e73 603
9f884528 604 InvalidateBestSize();
bf9e3e73 605
91af0895 606 return true;
bf9e3e73
RR
607}
608
a1cb0b11 609bool wxToolBar::DoDeleteTool(size_t /* pos */, wxToolBarToolBase* toolBase)
c801d85f 610{
5c33522f 611 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
c801d85f 612
a1cb0b11 613 if (tool->GetStyle() == wxTOOL_STYLE_CONTROL)
97d7bfb8 614 {
a1cb0b11
PC
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;
385e8575 620 gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
8a0681f9 621 }
9dc44eff 622 gtk_widget_destroy(GTK_WIDGET(tool->m_item));
a1cb0b11 623 tool->m_item = NULL;
c801d85f 624
9f884528 625 InvalidateBestSize();
91af0895 626 return true;
fc008f25 627}
46dc76ba 628
a1cb0b11
PC
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
8a0681f9
VZ
650// ----------------------------------------------------------------------------
651// wxToolBar tools state
652// ----------------------------------------------------------------------------
653
654void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
c801d85f 655{
5c33522f 656 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
8a0681f9 657
8a0681f9 658 if (tool->m_item)
a1cb0b11 659 gtk_widget_set_sensitive(GTK_WIDGET(tool->m_item), enable);
fc008f25 660}
c801d85f 661
248bcf0a 662void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle )
c801d85f 663{
5c33522f 664 wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
8a0681f9 665
a1cb0b11 666 if (tool->m_item)
1144d24d 667 {
a1cb0b11 668 g_signal_handlers_block_by_func(tool->m_item, (void*)item_toggled, tool);
8a0681f9 669
a1cb0b11
PC
670 gtk_toggle_tool_button_set_active(
671 GTK_TOGGLE_TOOL_BUTTON(tool->m_item), toggle);
248bcf0a 672
a1cb0b11 673 g_signal_handlers_unblock_by_func(tool->m_item, (void*)item_toggled, tool);
1144d24d 674 }
fc008f25 675}
c801d85f 676
8a0681f9
VZ
677void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
678 bool WXUNUSED(toggle))
c801d85f 679{
8a0681f9 680 // VZ: absolutely no idea about how to do it
9a83f860 681 wxFAIL_MSG( wxT("not implemented") );
fc008f25 682}
c801d85f 683
8a0681f9
VZ
684// ----------------------------------------------------------------------------
685// wxToolBar geometry
686// ----------------------------------------------------------------------------
687
a1cb0b11
PC
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
8a0681f9
VZ
701wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x),
702 wxCoord WXUNUSED(y)) const
c801d85f 703{
8a0681f9 704 // VZ: GTK+ doesn't seem to have such thing
9a83f860 705 wxFAIL_MSG( wxT("wxToolBar::FindToolForPosition() not implemented") );
8a0681f9 706
d3b9f782 707 return NULL;
fc008f25 708}
c801d85f 709
a1f79c1e
VZ
710void wxToolBar::SetToolShortHelp( int id, const wxString& helpString )
711{
5c33522f 712 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
a1f79c1e
VZ
713
714 if ( tool )
715 {
716 (void)tool->SetShortHelp(helpString);
a1cb0b11
PC
717 if (tool->m_item)
718 {
85314957 719#if GTK_CHECK_VERSION(2, 12, 0)
385e8575 720 if (GTK_CHECK_VERSION(3,0,0) || gtk_check_version(2,12,0) == NULL)
85314957
VZ
721 {
722 gtk_tool_item_set_tooltip_text(tool->m_item,
723 wxGTK_CONV(helpString));
724 }
725 else
726#endif
727 {
9dc44eff 728#ifndef __WXGTK3__
85314957
VZ
729 gtk_tool_item_set_tooltip(tool->m_item,
730 m_tooltips, wxGTK_CONV(helpString), "");
385e8575 731#endif
85314957 732 }
a1cb0b11 733 }
a1f79c1e
VZ
734 }
735}
736
bbd321ff
RD
737void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
738{
5c33522f 739 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
bbd321ff
RD
740 if ( tool )
741 {
742 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
743
744 tool->SetNormalBitmap(bitmap);
a1cb0b11 745 tool->SetImage();
f4322df6 746 }
bbd321ff
RD
747}
748
749void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
750{
5c33522f 751 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
bbd321ff
RD
752 if ( tool )
753 {
754 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
755
756 tool->SetDisabledBitmap(bitmap);
f4322df6 757 }
bbd321ff
RD
758}
759
9d522606
RD
760// ----------------------------------------------------------------------------
761
762// static
763wxVisualAttributes
764wxToolBar::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
765{
9d522606 766 return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new);
9d522606
RD
767}
768
a1f79c1e 769#endif // wxUSE_TOOLBAR_NATIVE