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