]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/tbargtk.cpp
1. wxChoice and wxComboBox support client data under MSW
[wxWidgets.git] / src / gtk / tbargtk.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: tbargtk.cpp
3// Purpose: GTK toolbar
4// Author: Robert Roebling
32e9da8b 5// RCS-ID: $Id$
c801d85f 6// Copyright: (c) Robert Roebling
a3622daa 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "tbargtk.h"
12#endif
13
14#include "wx/toolbar.h"
dcf924a3
RR
15
16#if wxUSE_TOOLBAR
17
e702ff0f 18#include "wx/frame.h"
c801d85f 19
83624f79
RR
20#include "glib.h"
21#include "gdk/gdk.h"
22#include "gtk/gtk.h"
23
acfd422a
RR
24//-----------------------------------------------------------------------------
25// idle system
26//-----------------------------------------------------------------------------
27
28extern void wxapp_install_idle_handler();
29extern bool g_isIdle;
30
314055fa
RR
31//-----------------------------------------------------------------------------
32// data
33//-----------------------------------------------------------------------------
34
35extern bool g_blockEventsOnDrag;
36
c801d85f 37//-----------------------------------------------------------------------------
2f2aa628 38// "clicked" (internal from gtk_toolbar)
c801d85f
KB
39//-----------------------------------------------------------------------------
40
41static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool )
42{
acfd422a
RR
43 if (g_isIdle) wxapp_install_idle_handler();
44
1144d24d
RR
45 if (g_blockEventsOnDrag) return;
46 if (!tool->m_enabled) return;
a3622daa 47
85eb36c2
RR
48 if (tool->m_isToggle)
49 {
50 tool->m_toggleState = !tool->m_toggleState;
51
52 if (tool->m_bitmap2.Ok())
53 {
54 wxBitmap bitmap = tool->m_bitmap1;
55 if (tool->m_toggleState) bitmap = tool->m_bitmap2;
56
57 GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap );
58
59 GdkBitmap *mask = (GdkBitmap *) NULL;
60 if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap();
61
62 gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
63 }
64 }
a3622daa 65
1144d24d 66 tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState );
fc008f25 67}
c801d85f 68
2f2aa628
RR
69//-----------------------------------------------------------------------------
70// "enter_notify_event"
71//-----------------------------------------------------------------------------
72
314055fa
RR
73static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget),
74 GdkEventCrossing *WXUNUSED(gdk_event), wxToolBarTool *tool )
75{
acfd422a
RR
76 if (g_isIdle) wxapp_install_idle_handler();
77
1144d24d 78 if (g_blockEventsOnDrag) return TRUE;
b98d804b 79
b98d804b
RR
80
81 wxToolBar *tb = tool->m_owner;
82
c693edf3
RR
83#if (GTK_MINOR_VERSION == 0)
84 /* we grey-out the tip text of disabled tool in GTK 1.0 */
b98d804b
RR
85 if (tool->m_enabled)
86 {
87 if (tb->m_fg->red != 0)
f03fc89f 88 {
b98d804b
RR
89 tb->m_fg->red = 0;
90 tb->m_fg->green = 0;
91 tb->m_fg->blue = 0;
92 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(tb->m_toolbar) ), tb->m_fg );
f03fc89f 93
b98d804b 94 gtk_tooltips_set_colors( GTK_TOOLBAR(tb->m_toolbar)->tooltips, tb->m_bg, tb->m_fg );
f03fc89f 95 }
b98d804b
RR
96 }
97 else
98 {
99 if (tb->m_fg->red == 0)
f03fc89f 100 {
b98d804b
RR
101 tb->m_fg->red = 33000;
102 tb->m_fg->green = 33000;
103 tb->m_fg->blue = 33000;
104 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(tb->m_toolbar) ), tb->m_fg );
105 gtk_tooltips_set_colors( GTK_TOOLBAR(tb->m_toolbar)->tooltips, tb->m_bg, tb->m_fg );
f03fc89f 106 }
b98d804b 107 }
f7ac40d1 108#endif
b98d804b
RR
109
110 /* emit the event */
314055fa 111
b98d804b 112 tb->OnMouseEnter( tool->m_index );
314055fa 113
1144d24d 114 return FALSE;
314055fa
RR
115}
116
2f2aa628
RR
117//-----------------------------------------------------------------------------
118// wxToolBar
c801d85f
KB
119//-----------------------------------------------------------------------------
120
716b7364 121IMPLEMENT_DYNAMIC_CLASS(wxToolBar,wxControl)
c801d85f 122
b1da76e1
RR
123BEGIN_EVENT_TABLE(wxToolBar, wxControl)
124 EVT_IDLE(wxToolBar::OnIdle)
125END_EVENT_TABLE()
126
a3622daa 127wxToolBar::wxToolBar()
c801d85f 128{
fc008f25 129}
c801d85f 130
a3622daa 131wxToolBar::wxToolBar( wxWindow *parent, wxWindowID id,
c801d85f 132 const wxPoint& pos, const wxSize& size,
debe6624 133 long style, const wxString& name )
c801d85f 134{
1144d24d 135 Create( parent, id, pos, size, style, name );
fc008f25 136}
c801d85f 137
a3622daa 138wxToolBar::~wxToolBar()
c801d85f 139{
83624f79
RR
140 delete m_fg;
141 delete m_bg;
fc008f25 142}
c801d85f 143
a3622daa 144bool wxToolBar::Create( wxWindow *parent, wxWindowID id,
c801d85f 145 const wxPoint& pos, const wxSize& size,
debe6624 146 long style, const wxString& name )
c801d85f 147{
1144d24d 148 m_needParent = TRUE;
a3622daa 149
1144d24d 150 PreCreation( parent, id, pos, size, style, name );
c801d85f 151
1144d24d 152 m_tools.DeleteContents( TRUE );
a3622daa 153
1144d24d
RR
154 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL,
155 GTK_TOOLBAR_ICONS ) );
a3622daa 156
1144d24d
RR
157 m_separation = 5;
158 gtk_toolbar_set_space_size( m_toolbar, m_separation );
159 m_hasToolAlready = FALSE;
3502e687
RR
160
161 if (style & wxTB_DOCKABLE)
162 {
163 m_widget = gtk_handle_box_new();
f03fc89f
VZ
164 gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
165 gtk_widget_show( GTK_WIDGET(m_toolbar) );
166
b0795d45 167#if (GTK_MINOR_VERSION > 0)
f03fc89f 168 if (style & wxTB_FLAT)
858b5bdd 169 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
b0795d45 170#endif
3502e687
RR
171 }
172 else
173 {
174 m_widget = GTK_WIDGET(m_toolbar);
175 }
f03fc89f 176
1144d24d 177 gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE );
858b5bdd
RR
178
179#if (GTK_MINOR_VERSION > 0)
180 if (style & wxTB_FLAT)
181 gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE );
182#endif
83624f79
RR
183
184 m_fg = new GdkColor;
185 m_fg->red = 0;
186 m_fg->green = 0;
187 m_fg->blue = 0;
188 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_fg );
b46e8696 189
83624f79
RR
190 m_bg = new GdkColor;
191 m_bg->red = 65535;
192 m_bg->green = 65535;
193 m_bg->blue = 50000;
194 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_bg );
b46e8696 195
fac4253c
RR
196#if (GTK_MINOR_VERSION > 0)
197 gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar)->tooltips );
198
199 GtkStyle *g_style =
200 gtk_style_copy(
201 gtk_widget_get_style(
202 GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) );
f03fc89f 203
fac4253c
RR
204 g_style->bg[GTK_STATE_NORMAL] = *m_bg;
205 gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style );
206#else
83624f79 207 gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar)->tooltips, m_bg, m_fg );
fac4253c 208#endif
a3622daa 209
1144d24d
RR
210 m_xMargin = 0;
211 m_yMargin = 0;
212
f03fc89f 213 m_parent->DoAddChild( this );
6ca41e57 214
1144d24d 215 PostCreation();
a3622daa 216
1144d24d 217 Show( TRUE );
a3622daa 218
1144d24d 219 return TRUE;
fc008f25 220}
c801d85f 221
716b7364 222bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown )
c801d85f 223{
1144d24d
RR
224 wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex );
225 event.SetEventObject(this);
226 event.SetInt( toolIndex );
227 event.SetExtraLong((long) toggleDown);
c801d85f 228
1144d24d 229 GetEventHandler()->ProcessEvent(event);
c801d85f 230
1144d24d 231 return TRUE;
fc008f25 232}
c801d85f 233
716b7364 234void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
c801d85f 235{
1144d24d
RR
236 wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex );
237 event.SetEventObject( this );
238 event.SetInt( toolIndex );
c801d85f 239
1144d24d 240 GetEventHandler()->ProcessEvent(event);
fc008f25 241}
c801d85f 242
716b7364 243void wxToolBar::OnMouseEnter( int toolIndex )
c801d85f 244{
1144d24d
RR
245 wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() );
246 event.SetEventObject(this);
247 event.SetInt( toolIndex );
314055fa 248
1144d24d 249 GetEventHandler()->ProcessEvent(event);
fc008f25 250}
c801d85f 251
a3622daa 252wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap,
debe6624
JS
253 const wxBitmap& pushedBitmap, bool toggle,
254 float WXUNUSED(xPos), float WXUNUSED(yPos), wxObject *clientData,
c801d85f
KB
255 const wxString& helpString1, const wxString& helpString2 )
256{
1144d24d
RR
257 m_hasToolAlready = TRUE;
258
259 wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL,
05939a81 260 _T("invalid bitmap for wxToolBar icon") );
a3622daa 261
1144d24d 262 wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL,
05939a81 263 _T("wxToolBar doesn't support GdkBitmap") );
03f38c58 264
1144d24d 265 wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL,
05939a81 266 _T("wxToolBar::Add needs a wxBitmap") );
903f689b 267
1144d24d 268 GtkWidget *tool_pixmap = (GtkWidget *)NULL;
903f689b 269
903f689b 270 GdkPixmap *pixmap = bitmap.GetPixmap();
a3622daa 271
68dda785
VZ
272 GdkBitmap *mask = (GdkBitmap *)NULL;
273 if ( bitmap.GetMask() )
274 mask = bitmap.GetMask()->GetBitmap();
903f689b
RR
275
276 tool_pixmap = gtk_pixmap_new( pixmap, mask );
c693edf3 277#if (GTK_MINOR_VERSION > 0)
f7ac40d1 278 gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE );
c693edf3 279#endif
f7ac40d1 280
1144d24d 281 gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
a3622daa 282
2b1c162e
RR
283 wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap,
284 toggle, clientData,
285 helpString1, helpString2,
f03fc89f 286 tool_pixmap );
2b1c162e 287
1144d24d
RR
288 GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
289 : GTK_TOOLBAR_CHILD_BUTTON;
03f38c58 290
1144d24d 291 GtkWidget *item = gtk_toolbar_append_element
68dda785
VZ
292 (
293 GTK_TOOLBAR(m_toolbar),
294 ctype,
295 (GtkWidget *)NULL,
296 (const char *)NULL,
05939a81 297 helpString1.mbc_str(),
68dda785
VZ
298 "",
299 tool_pixmap,
300 (GtkSignalFunc)gtk_toolbar_callback,
301 (gpointer)tool
302 );
303
1144d24d 304 tool->m_item = item;
03f38c58 305
1144d24d
RR
306 gtk_signal_connect( GTK_OBJECT(tool->m_item),
307 "enter_notify_event",
308 GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback),
309 (gpointer)tool );
314055fa 310
1144d24d 311 m_tools.Append( tool );
a3622daa 312
1144d24d 313 return tool;
fc008f25 314}
c801d85f 315
03f38c58 316void wxToolBar::AddSeparator()
c801d85f 317{
1144d24d 318 gtk_toolbar_append_space( m_toolbar );
fc008f25 319}
c801d85f 320
03f38c58 321void wxToolBar::ClearTools()
c801d85f 322{
05939a81 323 wxFAIL_MSG( _T("wxToolBar::ClearTools not implemented") );
fc008f25 324}
c801d85f 325
1144d24d 326bool wxToolBar::Realize()
46dc76ba 327{
1144d24d
RR
328 m_x = 0;
329 m_y = 0;
330 m_width = 100;
331 m_height = 0;
46dc76ba 332
1144d24d
RR
333 wxNode *node = m_tools.First();
334 while (node)
46dc76ba 335 {
1144d24d
RR
336 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
337 if (tool->m_bitmap1.Ok())
338 {
339 int tool_height = tool->m_bitmap1.GetHeight();
340 if (tool_height > m_height) m_height = tool_height;
341 }
46dc76ba 342
1144d24d
RR
343 node = node->Next();
344 }
46dc76ba 345
1144d24d
RR
346 m_height += 5 + 2*m_yMargin;
347
348 return TRUE;
fc008f25 349}
46dc76ba 350
716b7364 351void wxToolBar::EnableTool(int toolIndex, bool enable)
c801d85f 352{
1144d24d
RR
353 wxNode *node = m_tools.First();
354 while (node)
355 {
356 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
357 if (tool->m_index == toolIndex)
2b1c162e 358 {
1144d24d 359 tool->m_enabled = enable;
f03fc89f 360
c693edf3
RR
361#if (GTK_MINOR_VERSION > 0)
362 /* we don't disable the tools for GTK 1.0 as the bitmaps don't get
363 greyed anyway and this also disables tooltips */
f03fc89f
VZ
364 if (tool->m_item)
365 gtk_widget_set_sensitive( tool->m_item, enable );
c693edf3 366#endif
f03fc89f 367
1144d24d
RR
368 return;
369 }
370 node = node->Next();
cf4219e7 371 }
fc008f25 372
05939a81 373 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 374}
c801d85f 375
fc008f25 376void wxToolBar::ToggleTool( int toolIndex, bool toggle )
c801d85f 377{
1144d24d
RR
378 wxNode *node = m_tools.First();
379 while (node)
380 {
381 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
382 if (tool->m_index == toolIndex)
383 {
1144d24d 384 if ((tool->m_item) && (GTK_IS_TOGGLE_BUTTON(tool->m_item)))
e179bd65
RR
385 {
386 tool->m_toggleState = toggle;
387
388 if (tool->m_bitmap2.Ok())
389 {
390 wxBitmap bitmap = tool->m_bitmap1;
391 if (tool->m_toggleState) bitmap = tool->m_bitmap2;
392
393 GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap );
394
395 GdkBitmap *mask = (GdkBitmap *) NULL;
396 if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap();
397
398 gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
399 }
400
401 gtk_signal_disconnect_by_func( GTK_OBJECT(tool->m_item),
402 GTK_SIGNAL_FUNC(gtk_toolbar_callback), (gpointer*)tool );
403
1144d24d 404 gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool->m_item), toggle );
e179bd65
RR
405
406 gtk_signal_connect( GTK_OBJECT(tool->m_item), "clicked",
407 GTK_SIGNAL_FUNC(gtk_toolbar_callback), (gpointer*)tool );
408 }
409
1144d24d
RR
410 return;
411 }
412 node = node->Next();
fc008f25 413 }
fc008f25 414
05939a81 415 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 416}
c801d85f 417
fc008f25 418wxObject *wxToolBar::GetToolClientData( int index ) const
c801d85f 419{
1144d24d
RR
420 wxNode *node = m_tools.First();
421 while (node)
422 {
423 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
424 if (tool->m_index == index) return tool->m_clientData;;
425 node = node->Next();
426 }
fc008f25 427
05939a81 428 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 429
1144d24d 430 return (wxObject*)NULL;
fc008f25 431}
c801d85f 432
716b7364 433bool wxToolBar::GetToolState(int toolIndex) const
c801d85f 434{
1144d24d
RR
435 wxNode *node = m_tools.First();
436 while (node)
437 {
438 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
439 if (tool->m_index == toolIndex) return tool->m_toggleState;
440 node = node->Next();
441 }
fc008f25 442
05939a81 443 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 444
1144d24d 445 return FALSE;
fc008f25 446}
c801d85f 447
716b7364 448bool wxToolBar::GetToolEnabled(int toolIndex) const
c801d85f 449{
1144d24d
RR
450 wxNode *node = m_tools.First();
451 while (node)
452 {
453 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
454 if (tool->m_index == toolIndex) return tool->m_enabled;
455 node = node->Next();
456 }
fc008f25 457
05939a81 458 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 459
1144d24d 460 return FALSE;
fc008f25 461}
c801d85f 462
1144d24d 463void wxToolBar::SetMargins( int x, int y )
c801d85f 464{
05939a81 465 wxCHECK_RET( !m_hasToolAlready, _T("wxToolBar::SetMargins must be called before adding tool.") );
1144d24d
RR
466
467 if (x > 2) gtk_toolbar_append_space( m_toolbar ); // oh well
468
469 m_xMargin = x;
470 m_yMargin = y;
fc008f25 471}
c801d85f 472
cf4219e7 473void wxToolBar::SetToolPacking( int WXUNUSED(packing) )
c801d85f 474{
05939a81 475 wxFAIL_MSG( _T("wxToolBar::SetToolPacking not implemented") );
fc008f25 476}
c801d85f 477
cf4219e7 478void wxToolBar::SetToolSeparation( int separation )
c801d85f 479{
1144d24d
RR
480 gtk_toolbar_set_space_size( m_toolbar, separation );
481 m_separation = separation;
482}
483
484int wxToolBar::GetToolPacking()
485{
486 return 0;
487}
488
489int wxToolBar::GetToolSeparation()
490{
491 return m_separation;
492}
493
494wxString wxToolBar::GetToolLongHelp(int toolIndex)
495{
496 wxNode *node = m_tools.First();
497 while (node)
498 {
499 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
500 if (tool->m_index == toolIndex)
501 {
502 return tool->m_longHelpString;
503 }
504 node = node->Next();
505 }
506
05939a81 507 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d 508
05939a81 509 return _T("");
1144d24d
RR
510}
511
512wxString wxToolBar::GetToolShortHelp(int toolIndex)
513{
514 wxNode *node = m_tools.First();
515 while (node)
516 {
517 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
518 if (tool->m_index == toolIndex)
519 {
520 return tool->m_shortHelpString;
521 }
522 node = node->Next();
523 }
524
05939a81 525 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d 526
05939a81 527 return _T("");
fc008f25 528}
c801d85f 529
1144d24d
RR
530void wxToolBar::SetToolLongHelp(int toolIndex, const wxString& helpString)
531{
532 wxNode *node = m_tools.First();
533 while (node)
534 {
535 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
536 if (tool->m_index == toolIndex)
537 {
538 tool->m_longHelpString = helpString;
f03fc89f 539 return;
1144d24d
RR
540 }
541 node = node->Next();
542 }
543
05939a81 544 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d
RR
545
546 return;
547}
548
549void wxToolBar::SetToolShortHelp(int toolIndex, const wxString& helpString)
550{
551 wxNode *node = m_tools.First();
552 while (node)
553 {
554 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
555 if (tool->m_index == toolIndex)
556 {
557 tool->m_shortHelpString = helpString;
f03fc89f 558 return;
1144d24d
RR
559 }
560 node = node->Next();
561 }
562
05939a81 563 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d
RR
564
565 return;
566}
567
b1da76e1
RR
568void wxToolBar::OnIdle( wxIdleEvent &WXUNUSED(ievent) )
569{
570 wxEvtHandler* evtHandler = GetEventHandler();
571
572 wxNode* node = m_tools.First();
573 while (node)
574 {
575 wxToolBarTool* tool = (wxToolBarTool*) node->Data();
576
577 wxUpdateUIEvent event( tool->m_index );
578 event.SetEventObject(this);
579
580 if (evtHandler->ProcessEvent( event ))
581 {
582 if (event.GetSetEnabled())
583 EnableTool(tool->m_index, event.GetEnabled());
584 if (event.GetSetChecked())
585 ToggleTool(tool->m_index, event.GetChecked());
586/*
587 if (event.GetSetText())
588 // Set tooltip?
589*/
590 }
591
592 node = node->Next();
593 }
594}
1144d24d 595
dcf924a3 596#endif