]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/tbargtk.cpp
compilation fixes for the wxListItemAttr
[wxWidgets.git] / src / gtk1 / tbargtk.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: tbargtk.cpp
3// Purpose: GTK toolbar
4// Author: Robert Roebling
5// RCS-ID: $Id$
6// Copyright: (c) Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "tbargtk.h"
12#endif
13
14#include "wx/toolbar.h"
15
16#if wxUSE_TOOLBAR
17
18#include "wx/frame.h"
19
20#include "glib.h"
21#include "gdk/gdk.h"
22#include "gtk/gtk.h"
23
24//-----------------------------------------------------------------------------
25// idle system
26//-----------------------------------------------------------------------------
27
28extern void wxapp_install_idle_handler();
29extern bool g_isIdle;
30
31//-----------------------------------------------------------------------------
32// data
33//-----------------------------------------------------------------------------
34
35extern bool g_blockEventsOnDrag;
36extern wxCursor g_globalCursor;
37
38//-----------------------------------------------------------------------------
39// "clicked" (internal from gtk_toolbar)
40//-----------------------------------------------------------------------------
41
42static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool )
43{
44 if (g_isIdle)
45 wxapp_install_idle_handler();
46
47 if (tool->m_owner->m_blockNextEvent)
48 {
49 tool->m_owner->m_blockNextEvent = FALSE;
50 return;
51 }
52
53 if (g_blockEventsOnDrag) return;
54 if (!tool->m_enabled) return;
55
56 if (tool->m_isToggle)
57 {
58 tool->m_toggleState = !tool->m_toggleState;
59
60 if (tool->m_bitmap2.Ok())
61 {
62 wxBitmap bitmap = tool->m_bitmap1;
63 if (tool->m_toggleState) bitmap = tool->m_bitmap2;
64
65 GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap );
66
67 GdkBitmap *mask = (GdkBitmap *) NULL;
68 if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap();
69
70 gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
71 }
72 }
73
74 tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState );
75}
76
77//-----------------------------------------------------------------------------
78// "enter_notify_event"
79//-----------------------------------------------------------------------------
80
81static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget),
82 GdkEventCrossing *WXUNUSED(gdk_event), wxToolBarTool *tool )
83{
84 if (g_isIdle) wxapp_install_idle_handler();
85
86 if (g_blockEventsOnDrag) return TRUE;
87
88
89 wxToolBar *tb = tool->m_owner;
90
91#if (GTK_MINOR_VERSION == 0)
92 /* we grey-out the tip text of disabled tool in GTK 1.0 */
93 if (tool->m_enabled)
94 {
95 if (tb->m_fg->red != 0)
96 {
97 tb->m_fg->red = 0;
98 tb->m_fg->green = 0;
99 tb->m_fg->blue = 0;
100 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(tb->m_toolbar) ), tb->m_fg );
101
102 gtk_tooltips_set_colors( GTK_TOOLBAR(tb->m_toolbar)->tooltips, tb->m_bg, tb->m_fg );
103 }
104 }
105 else
106 {
107 if (tb->m_fg->red == 0)
108 {
109 tb->m_fg->red = 33000;
110 tb->m_fg->green = 33000;
111 tb->m_fg->blue = 33000;
112 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(tb->m_toolbar) ), tb->m_fg );
113 gtk_tooltips_set_colors( GTK_TOOLBAR(tb->m_toolbar)->tooltips, tb->m_bg, tb->m_fg );
114 }
115 }
116#endif
117
118 /* emit the event */
119
120 tb->OnMouseEnter( tool->m_index );
121
122 return FALSE;
123}
124
125//-----------------------------------------------------------------------------
126// InsertChild callback for wxToolBar
127//-----------------------------------------------------------------------------
128
129static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent), wxWindow* WXUNUSED(child) )
130{
131 /* we don't do anything here but pray */
132}
133
134//-----------------------------------------------------------------------------
135// wxToolBar
136//-----------------------------------------------------------------------------
137
138IMPLEMENT_DYNAMIC_CLASS(wxToolBar,wxControl)
139
140BEGIN_EVENT_TABLE(wxToolBar, wxControl)
141 EVT_IDLE(wxToolBar::OnIdle)
142END_EVENT_TABLE()
143
144wxToolBar::wxToolBar()
145{
146}
147
148wxToolBar::wxToolBar( wxWindow *parent, wxWindowID id,
149 const wxPoint& pos, const wxSize& size,
150 long style, const wxString& name )
151{
152 Create( parent, id, pos, size, style, name );
153}
154
155wxToolBar::~wxToolBar()
156{
157 delete m_fg;
158 delete m_bg;
159}
160
161bool wxToolBar::Create( wxWindow *parent, wxWindowID id,
162 const wxPoint& pos, const wxSize& size,
163 long style, const wxString& name )
164{
165 m_needParent = TRUE;
166 m_blockNextEvent = FALSE;
167 m_insertCallback = (wxInsertChildFunction)wxInsertChildInToolBar;
168
169 if (!PreCreation( parent, pos, size ) ||
170 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
171 {
172 wxFAIL_MSG( wxT("wxToolBar creation failed") );
173 return FALSE;
174 }
175
176 m_tools.DeleteContents( TRUE );
177
178 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL,
179 GTK_TOOLBAR_ICONS ) );
180
181// gtk_toolbar_set_space_style( m_toolbar, GTK_TOOLBAR_SPACE_LINE );
182 m_separation = 5;
183 gtk_toolbar_set_space_size( m_toolbar, m_separation );
184 m_hasToolAlready = FALSE;
185
186 if (style & wxTB_DOCKABLE)
187 {
188 m_widget = gtk_handle_box_new();
189 gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
190 gtk_widget_show( GTK_WIDGET(m_toolbar) );
191
192#if (GTK_MINOR_VERSION > 0)
193 if (style & wxTB_FLAT)
194 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
195#endif
196 }
197 else
198 {
199 m_widget = GTK_WIDGET(m_toolbar);
200 }
201
202 gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE );
203
204#if (GTK_MINOR_VERSION > 0)
205 if (style & wxTB_FLAT)
206 gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE );
207#endif
208
209 m_fg = new GdkColor;
210 m_fg->red = 0;
211 m_fg->green = 0;
212 m_fg->blue = 0;
213 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_fg );
214
215 m_bg = new GdkColor;
216 m_bg->red = 65535;
217 m_bg->green = 65535;
218 m_bg->blue = 50000;
219 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_bg );
220
221#if (GTK_MINOR_VERSION > 0)
222 gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar)->tooltips );
223
224 GtkStyle *g_style =
225 gtk_style_copy(
226 gtk_widget_get_style(
227 GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) );
228
229 g_style->bg[GTK_STATE_NORMAL] = *m_bg;
230 gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style );
231#else
232 gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar)->tooltips, m_bg, m_fg );
233#endif
234
235 m_xMargin = 0;
236 m_yMargin = 0;
237
238 m_parent->DoAddChild( this );
239
240 PostCreation();
241
242 Show( TRUE );
243
244 return TRUE;
245}
246
247bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown )
248{
249 wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex );
250 event.SetEventObject(this);
251 event.SetInt( toolIndex );
252 event.SetExtraLong((long) toggleDown);
253
254 GetEventHandler()->ProcessEvent(event);
255
256 return TRUE;
257}
258
259void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
260{
261 wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex );
262 event.SetEventObject( this );
263 event.SetInt( toolIndex );
264
265 GetEventHandler()->ProcessEvent(event);
266}
267
268void wxToolBar::OnMouseEnter( int toolIndex )
269{
270 wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() );
271 event.SetEventObject(this);
272 event.SetInt( toolIndex );
273
274 GetEventHandler()->ProcessEvent(event);
275}
276
277wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap,
278 const wxBitmap& pushedBitmap, bool toggle,
279 wxCoord WXUNUSED(xPos), wxCoord WXUNUSED(yPos), wxObject *clientData,
280 const wxString& helpString1, const wxString& helpString2 )
281{
282 m_hasToolAlready = TRUE;
283
284 wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL,
285 wxT("invalid bitmap for wxToolBar icon") );
286
287 wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL,
288 wxT("wxToolBar doesn't support GdkBitmap") );
289
290 wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL,
291 wxT("wxToolBar::Add needs a wxBitmap") );
292
293 GtkWidget *tool_pixmap = (GtkWidget *)NULL;
294
295 GdkPixmap *pixmap = bitmap.GetPixmap();
296
297 GdkBitmap *mask = (GdkBitmap *)NULL;
298 if ( bitmap.GetMask() )
299 mask = bitmap.GetMask()->GetBitmap();
300
301 tool_pixmap = gtk_pixmap_new( pixmap, mask );
302#if (GTK_MINOR_VERSION > 0)
303 gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE );
304#endif
305
306 gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
307
308 wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap,
309 toggle, clientData,
310 helpString1, helpString2,
311 tool_pixmap );
312
313 GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
314 : GTK_TOOLBAR_CHILD_BUTTON;
315
316 GtkWidget *item = gtk_toolbar_append_element
317 (
318 m_toolbar,
319 ctype,
320 (GtkWidget *)NULL,
321 (const char *)NULL,
322 helpString1.mbc_str(),
323 "",
324 tool_pixmap,
325 (GtkSignalFunc)gtk_toolbar_callback,
326 (gpointer)tool
327 );
328
329 tool->m_item = item;
330
331 GtkRequisition req;
332 (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req );
333 m_width = req.width;
334 m_height = req.height;
335
336 gtk_signal_connect( GTK_OBJECT(tool->m_item),
337 "enter_notify_event",
338 GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback),
339 (gpointer)tool );
340
341 m_tools.Append( tool );
342
343 return tool;
344}
345
346bool wxToolBar::AddControl(wxControl *control)
347{
348 wxCHECK_MSG( control, FALSE, wxT("toolbar: can't insert NULL control") );
349
350 wxCHECK_MSG( control->GetParent() == this, FALSE,
351 wxT("control must have toolbar as parent") );
352
353 m_hasToolAlready = TRUE;
354
355 wxToolBarTool *tool = new wxToolBarTool(control);
356
357 gtk_toolbar_append_widget( m_toolbar, control->m_widget, (const char *) NULL, (const char *) NULL );
358
359 GtkRequisition req;
360 (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req );
361 m_width = req.width;
362 m_height = req.height;
363
364 m_tools.Append( tool );
365
366 return TRUE;
367}
368
369void wxToolBar::AddSeparator()
370{
371 gtk_toolbar_append_space( m_toolbar );
372}
373
374bool wxToolBar::DeleteTool(int toolIndex)
375{
376 wxNode *node = m_tools.First();
377 while (node)
378 {
379 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
380 if (tool->m_index == toolIndex)
381 {
382 if (tool->m_control)
383 tool->m_control->Destroy();
384 else
385 gtk_widget_destroy( tool->m_item );
386 m_tools.DeleteNode( node );
387
388 return TRUE;
389 }
390 node = node->Next();
391 }
392
393 return FALSE;
394}
395
396void wxToolBar::ClearTools()
397{
398 wxFAIL_MSG( wxT("wxToolBar::ClearTools not implemented") );
399}
400
401bool wxToolBar::Realize()
402{
403 m_x = 0;
404 m_y = 0;
405 m_width = 100;
406 m_height = 0;
407
408 wxNode *node = m_tools.First();
409 while (node)
410 {
411 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
412 if (tool->m_bitmap1.Ok())
413 {
414 int tool_height = tool->m_bitmap1.GetHeight();
415 if (tool_height > m_height) m_height = tool_height;
416 }
417
418 node = node->Next();
419 }
420
421 m_height += 5 + 2*m_yMargin;
422
423 return TRUE;
424}
425
426void wxToolBar::EnableTool(int toolIndex, bool enable)
427{
428 wxNode *node = m_tools.First();
429 while (node)
430 {
431 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
432 if (tool->m_index == toolIndex)
433 {
434 tool->m_enabled = enable;
435
436#if (GTK_MINOR_VERSION > 0)
437 /* we don't disable the tools for GTK 1.0 as the bitmaps don't get
438 greyed anyway and this also disables tooltips */
439 if (tool->m_item)
440 gtk_widget_set_sensitive( tool->m_item, enable );
441#endif
442
443 return;
444 }
445 node = node->Next();
446 }
447
448 wxFAIL_MSG( wxT("wrong toolbar index") );
449}
450
451void wxToolBar::ToggleTool( int toolIndex, bool toggle )
452{
453 wxNode *node = m_tools.First();
454 while (node)
455 {
456 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
457 if (tool->m_index == toolIndex)
458 {
459 if ((tool->m_item) && (GTK_IS_TOGGLE_BUTTON(tool->m_item)))
460 {
461 tool->m_toggleState = toggle;
462
463 if (tool->m_bitmap2.Ok())
464 {
465 wxBitmap bitmap = tool->m_bitmap1;
466 if (tool->m_toggleState) bitmap = tool->m_bitmap2;
467
468 GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap );
469
470 GdkBitmap *mask = (GdkBitmap *) NULL;
471 if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap();
472
473 gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
474 }
475
476 m_blockNextEvent = TRUE; // we cannot use gtk_signal_disconnect here
477
478 gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool->m_item), toggle );
479 }
480
481 return;
482 }
483 node = node->Next();
484 }
485
486 wxFAIL_MSG( wxT("wrong toolbar index") );
487}
488
489wxObject *wxToolBar::GetToolClientData( int index ) const
490{
491 wxNode *node = m_tools.First();
492 while (node)
493 {
494 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
495 if (tool->m_index == index) return tool->m_clientData;;
496 node = node->Next();
497 }
498
499 wxFAIL_MSG( wxT("wrong toolbar index") );
500
501 return (wxObject*)NULL;
502}
503
504bool wxToolBar::GetToolState(int toolIndex) const
505{
506 wxNode *node = m_tools.First();
507 while (node)
508 {
509 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
510 if (tool->m_index == toolIndex) return tool->m_toggleState;
511 node = node->Next();
512 }
513
514 wxFAIL_MSG( wxT("wrong toolbar index") );
515
516 return FALSE;
517}
518
519bool wxToolBar::GetToolEnabled(int toolIndex) const
520{
521 wxNode *node = m_tools.First();
522 while (node)
523 {
524 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
525 if (tool->m_index == toolIndex) return tool->m_enabled;
526 node = node->Next();
527 }
528
529 wxFAIL_MSG( wxT("wrong toolbar index") );
530
531 return FALSE;
532}
533
534void wxToolBar::SetMargins( int x, int y )
535{
536 wxCHECK_RET( !m_hasToolAlready, wxT("wxToolBar::SetMargins must be called before adding tool.") );
537
538 if (x > 2) gtk_toolbar_append_space( m_toolbar ); // oh well
539
540 m_xMargin = x;
541 m_yMargin = y;
542}
543
544void wxToolBar::SetToolPacking( int WXUNUSED(packing) )
545{
546 wxFAIL_MSG( wxT("wxToolBar::SetToolPacking not implemented") );
547}
548
549void wxToolBar::SetToolSeparation( int separation )
550{
551 gtk_toolbar_set_space_size( m_toolbar, separation );
552 m_separation = separation;
553}
554
555int wxToolBar::GetToolPacking()
556{
557 return 0;
558}
559
560int wxToolBar::GetToolSeparation()
561{
562 return m_separation;
563}
564
565wxString wxToolBar::GetToolLongHelp(int toolIndex)
566{
567 wxNode *node = m_tools.First();
568 while (node)
569 {
570 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
571 if (tool->m_index == toolIndex)
572 {
573 return tool->m_longHelpString;
574 }
575 node = node->Next();
576 }
577
578 wxFAIL_MSG( wxT("wrong toolbar index") );
579
580 return wxT("");
581}
582
583wxString wxToolBar::GetToolShortHelp(int toolIndex)
584{
585 wxNode *node = m_tools.First();
586 while (node)
587 {
588 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
589 if (tool->m_index == toolIndex)
590 {
591 return tool->m_shortHelpString;
592 }
593 node = node->Next();
594 }
595
596 wxFAIL_MSG( wxT("wrong toolbar index") );
597
598 return wxT("");
599}
600
601void wxToolBar::SetToolLongHelp(int toolIndex, const wxString& helpString)
602{
603 wxNode *node = m_tools.First();
604 while (node)
605 {
606 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
607 if (tool->m_index == toolIndex)
608 {
609 tool->m_longHelpString = helpString;
610 return;
611 }
612 node = node->Next();
613 }
614
615 wxFAIL_MSG( wxT("wrong toolbar index") );
616
617 return;
618}
619
620void wxToolBar::SetToolShortHelp(int toolIndex, const wxString& helpString)
621{
622 wxNode *node = m_tools.First();
623 while (node)
624 {
625 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
626 if (tool->m_index == toolIndex)
627 {
628 tool->m_shortHelpString = helpString;
629 return;
630 }
631 node = node->Next();
632 }
633
634 wxFAIL_MSG( wxT("wrong toolbar index") );
635
636 return;
637}
638
639void wxToolBar::OnIdle( wxIdleEvent &WXUNUSED(ievent) )
640{
641 wxEvtHandler* evtHandler = GetEventHandler();
642
643 wxNode* node = m_tools.First();
644 while (node)
645 {
646 wxToolBarTool* tool = (wxToolBarTool*) node->Data();
647
648 wxUpdateUIEvent event( tool->m_index );
649 event.SetEventObject(this);
650
651 if (evtHandler->ProcessEvent( event ))
652 {
653 if (event.GetSetEnabled())
654 EnableTool(tool->m_index, event.GetEnabled());
655 if (event.GetSetChecked())
656 ToggleTool(tool->m_index, event.GetChecked());
657/*
658 if (event.GetSetText())
659 // Set tooltip?
660*/
661 }
662
663 node = node->Next();
664 }
665}
666
667void wxToolBar::OnInternalIdle()
668{
669 wxCursor cursor = m_cursor;
670 if (g_globalCursor.Ok()) cursor = g_globalCursor;
671
672 if (cursor.Ok())
673 {
674 /* I now set the cursor the anew in every OnInternalIdle call
675 as setting the cursor in a parent window also effects the
676 windows above so that checking for the current cursor is
677 not possible. */
678
679 if (HasFlag(wxTB_DOCKABLE))
680 {
681 /* if the toolbar is dockable, then m_widget stands for the
682 GtkHandleBox widget, which uses its own window so that we
683 can set the cursor for it. if the toolbar is not dockable,
684 m_widget comes from m_toolbar which uses its parent's
685 window ("windowless windows") and thus we cannot set the
686 cursor. */
687 gdk_window_set_cursor( m_widget->window, cursor.GetCursor() );
688 }
689
690 wxNode *node = m_tools.First();
691 while (node)
692 {
693 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
694 node = node->Next();
695
696 if (!tool->m_item || !tool->m_item->window)
697 continue;
698 else
699 gdk_window_set_cursor( tool->m_item->window, cursor.GetCursor() );
700 }
701 }
702
703 UpdateWindowUI();
704}
705
706#endif