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