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