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