]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/tbargtk.cpp
Small cursor improvements
[wxWidgets.git] / src / gtk1 / 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)
f03fc89f 68 {
b98d804b
RR
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 );
f03fc89f 73
fac4253c
RR
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 ) );
f03fc89f 79
fac4253c
RR
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
f03fc89f 85 }
b98d804b
RR
86 }
87 else
88 {
89 if (tb->m_fg->red == 0)
f03fc89f 90 {
b98d804b
RR
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 ) );
f03fc89f 100
fac4253c
RR
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
f03fc89f 106 }
b98d804b
RR
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();
f03fc89f
VZ
163 gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
164 gtk_widget_show( GTK_WIDGET(m_toolbar) );
165
b0795d45 166#if (GTK_MINOR_VERSION > 0)
f03fc89f 167 if (style & wxTB_FLAT)
858b5bdd 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 }
f03fc89f 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 ) );
f03fc89f 202
fac4253c
RR
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
f03fc89f 212 m_parent->DoAddChild( this );
6ca41e57 213
1144d24d 214 PostCreation();
a3622daa 215
1144d24d 216 Show( TRUE );
a3622daa 217
1144d24d 218 return TRUE;
fc008f25 219}
c801d85f 220
716b7364 221bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown )
c801d85f 222{
1144d24d
RR
223 wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex );
224 event.SetEventObject(this);
225 event.SetInt( toolIndex );
226 event.SetExtraLong((long) toggleDown);
c801d85f 227
1144d24d 228 GetEventHandler()->ProcessEvent(event);
c801d85f 229
1144d24d 230 return TRUE;
fc008f25 231}
c801d85f 232
716b7364 233void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
c801d85f 234{
1144d24d
RR
235 wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex );
236 event.SetEventObject( this );
237 event.SetInt( toolIndex );
c801d85f 238
1144d24d 239 GetEventHandler()->ProcessEvent(event);
fc008f25 240}
c801d85f 241
716b7364 242void wxToolBar::OnMouseEnter( int toolIndex )
c801d85f 243{
1144d24d
RR
244 wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() );
245 event.SetEventObject(this);
246 event.SetInt( toolIndex );
314055fa 247
1144d24d 248 GetEventHandler()->ProcessEvent(event);
fc008f25 249}
c801d85f 250
a3622daa 251wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap,
debe6624
JS
252 const wxBitmap& pushedBitmap, bool toggle,
253 float WXUNUSED(xPos), float WXUNUSED(yPos), wxObject *clientData,
c801d85f
KB
254 const wxString& helpString1, const wxString& helpString2 )
255{
1144d24d
RR
256 m_hasToolAlready = TRUE;
257
258 wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL,
05939a81 259 _T("invalid bitmap for wxToolBar icon") );
a3622daa 260
1144d24d 261 wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL,
05939a81 262 _T("wxToolBar doesn't support GdkBitmap") );
03f38c58 263
1144d24d 264 wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL,
05939a81 265 _T("wxToolBar::Add needs a wxBitmap") );
903f689b 266
1144d24d 267 GtkWidget *tool_pixmap = (GtkWidget *)NULL;
903f689b 268
903f689b 269 GdkPixmap *pixmap = bitmap.GetPixmap();
a3622daa 270
68dda785
VZ
271 GdkBitmap *mask = (GdkBitmap *)NULL;
272 if ( bitmap.GetMask() )
273 mask = bitmap.GetMask()->GetBitmap();
903f689b
RR
274
275 tool_pixmap = gtk_pixmap_new( pixmap, mask );
903f689b 276
1144d24d 277 gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
a3622daa 278
2b1c162e
RR
279 wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap,
280 toggle, clientData,
281 helpString1, helpString2,
f03fc89f 282 tool_pixmap );
2b1c162e 283
1144d24d
RR
284 GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
285 : GTK_TOOLBAR_CHILD_BUTTON;
03f38c58 286
1144d24d 287 GtkWidget *item = gtk_toolbar_append_element
68dda785
VZ
288 (
289 GTK_TOOLBAR(m_toolbar),
290 ctype,
291 (GtkWidget *)NULL,
292 (const char *)NULL,
05939a81 293 helpString1.mbc_str(),
68dda785
VZ
294 "",
295 tool_pixmap,
296 (GtkSignalFunc)gtk_toolbar_callback,
297 (gpointer)tool
298 );
299
1144d24d 300 tool->m_item = item;
03f38c58 301
1144d24d
RR
302 gtk_signal_connect( GTK_OBJECT(tool->m_item),
303 "enter_notify_event",
304 GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback),
305 (gpointer)tool );
314055fa 306
1144d24d 307 m_tools.Append( tool );
a3622daa 308
1144d24d 309 return tool;
fc008f25 310}
c801d85f 311
03f38c58 312void wxToolBar::AddSeparator()
c801d85f 313{
1144d24d 314 gtk_toolbar_append_space( m_toolbar );
fc008f25 315}
c801d85f 316
03f38c58 317void wxToolBar::ClearTools()
c801d85f 318{
05939a81 319 wxFAIL_MSG( _T("wxToolBar::ClearTools not implemented") );
fc008f25 320}
c801d85f 321
1144d24d 322bool wxToolBar::Realize()
46dc76ba 323{
1144d24d
RR
324 m_x = 0;
325 m_y = 0;
326 m_width = 100;
327 m_height = 0;
46dc76ba 328
1144d24d
RR
329 wxNode *node = m_tools.First();
330 while (node)
46dc76ba 331 {
1144d24d
RR
332 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
333 if (tool->m_bitmap1.Ok())
334 {
335 int tool_height = tool->m_bitmap1.GetHeight();
336 if (tool_height > m_height) m_height = tool_height;
337 }
46dc76ba 338
1144d24d
RR
339 node = node->Next();
340 }
46dc76ba 341
1144d24d
RR
342 m_height += 5 + 2*m_yMargin;
343
344 return TRUE;
fc008f25 345}
46dc76ba 346
716b7364 347void wxToolBar::EnableTool(int toolIndex, bool enable)
c801d85f 348{
1144d24d
RR
349 wxNode *node = m_tools.First();
350 while (node)
351 {
352 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
353 if (tool->m_index == toolIndex)
2b1c162e 354 {
1144d24d 355 tool->m_enabled = enable;
f03fc89f 356
b98d804b
RR
357/* we don't disable the tools for now as the bitmaps don't get
358 greyed anyway and this also disables tooltips
359
f03fc89f
VZ
360 if (tool->m_item)
361 gtk_widget_set_sensitive( tool->m_item, enable );
b98d804b 362*/
f03fc89f 363
1144d24d
RR
364 return;
365 }
366 node = node->Next();
cf4219e7 367 }
fc008f25 368
05939a81 369 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 370}
c801d85f 371
fc008f25 372void wxToolBar::ToggleTool( int toolIndex, bool toggle )
c801d85f 373{
1144d24d
RR
374 wxNode *node = m_tools.First();
375 while (node)
376 {
377 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
378 if (tool->m_index == toolIndex)
379 {
380 tool->m_toggleState = toggle;
381 if ((tool->m_item) && (GTK_IS_TOGGLE_BUTTON(tool->m_item)))
382 gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool->m_item), toggle );
383 return;
384 }
385 node = node->Next();
fc008f25 386 }
fc008f25 387
05939a81 388 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 389}
c801d85f 390
fc008f25 391wxObject *wxToolBar::GetToolClientData( int index ) const
c801d85f 392{
1144d24d
RR
393 wxNode *node = m_tools.First();
394 while (node)
395 {
396 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
397 if (tool->m_index == index) return tool->m_clientData;;
398 node = node->Next();
399 }
fc008f25 400
05939a81 401 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 402
1144d24d 403 return (wxObject*)NULL;
fc008f25 404}
c801d85f 405
716b7364 406bool wxToolBar::GetToolState(int toolIndex) const
c801d85f 407{
1144d24d
RR
408 wxNode *node = m_tools.First();
409 while (node)
410 {
411 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
412 if (tool->m_index == toolIndex) return tool->m_toggleState;
413 node = node->Next();
414 }
fc008f25 415
05939a81 416 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 417
1144d24d 418 return FALSE;
fc008f25 419}
c801d85f 420
716b7364 421bool wxToolBar::GetToolEnabled(int toolIndex) const
c801d85f 422{
1144d24d
RR
423 wxNode *node = m_tools.First();
424 while (node)
425 {
426 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
427 if (tool->m_index == toolIndex) return tool->m_enabled;
428 node = node->Next();
429 }
fc008f25 430
05939a81 431 wxFAIL_MSG( _T("wrong toolbar index") );
fc008f25 432
1144d24d 433 return FALSE;
fc008f25 434}
c801d85f 435
1144d24d 436void wxToolBar::SetMargins( int x, int y )
c801d85f 437{
05939a81 438 wxCHECK_RET( !m_hasToolAlready, _T("wxToolBar::SetMargins must be called before adding tool.") );
1144d24d
RR
439
440 if (x > 2) gtk_toolbar_append_space( m_toolbar ); // oh well
441
442 m_xMargin = x;
443 m_yMargin = y;
fc008f25 444}
c801d85f 445
cf4219e7 446void wxToolBar::SetToolPacking( int WXUNUSED(packing) )
c801d85f 447{
05939a81 448 wxFAIL_MSG( _T("wxToolBar::SetToolPacking not implemented") );
fc008f25 449}
c801d85f 450
cf4219e7 451void wxToolBar::SetToolSeparation( int separation )
c801d85f 452{
1144d24d
RR
453 gtk_toolbar_set_space_size( m_toolbar, separation );
454 m_separation = separation;
455}
456
457int wxToolBar::GetToolPacking()
458{
459 return 0;
460}
461
462int wxToolBar::GetToolSeparation()
463{
464 return m_separation;
465}
466
467wxString wxToolBar::GetToolLongHelp(int toolIndex)
468{
469 wxNode *node = m_tools.First();
470 while (node)
471 {
472 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
473 if (tool->m_index == toolIndex)
474 {
475 return tool->m_longHelpString;
476 }
477 node = node->Next();
478 }
479
05939a81 480 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d 481
05939a81 482 return _T("");
1144d24d
RR
483}
484
485wxString wxToolBar::GetToolShortHelp(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_shortHelpString;
494 }
495 node = node->Next();
496 }
497
05939a81 498 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d 499
05939a81 500 return _T("");
fc008f25 501}
c801d85f 502
1144d24d
RR
503void wxToolBar::SetToolLongHelp(int toolIndex, const wxString& helpString)
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 tool->m_longHelpString = helpString;
f03fc89f 512 return;
1144d24d
RR
513 }
514 node = node->Next();
515 }
516
05939a81 517 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d
RR
518
519 return;
520}
521
522void wxToolBar::SetToolShortHelp(int toolIndex, const wxString& helpString)
523{
524 wxNode *node = m_tools.First();
525 while (node)
526 {
527 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
528 if (tool->m_index == toolIndex)
529 {
530 tool->m_shortHelpString = helpString;
f03fc89f 531 return;
1144d24d
RR
532 }
533 node = node->Next();
534 }
535
05939a81 536 wxFAIL_MSG( _T("wrong toolbar index") );
1144d24d
RR
537
538 return;
539}
540
b1da76e1
RR
541void wxToolBar::OnIdle( wxIdleEvent &WXUNUSED(ievent) )
542{
543 wxEvtHandler* evtHandler = GetEventHandler();
544
545 wxNode* node = m_tools.First();
546 while (node)
547 {
548 wxToolBarTool* tool = (wxToolBarTool*) node->Data();
549
550 wxUpdateUIEvent event( tool->m_index );
551 event.SetEventObject(this);
552
553 if (evtHandler->ProcessEvent( event ))
554 {
555 if (event.GetSetEnabled())
556 EnableTool(tool->m_index, event.GetEnabled());
557 if (event.GetSetChecked())
558 ToggleTool(tool->m_index, event.GetChecked());
559/*
560 if (event.GetSetText())
561 // Set tooltip?
562*/
563 }
564
565 node = node->Next();
566 }
567}
1144d24d 568