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