]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/tbargtk.cpp
wxWindow split into wxWindowBase and wxWindow (wxGTK part)
[wxWidgets.git] / src / gtk / 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 #include "wx/frame.h"
16
17 #include "glib.h"
18 #include "gdk/gdk.h"
19 #include "gtk/gtk.h"
20
21 //-----------------------------------------------------------------------------
22 // idle system
23 //-----------------------------------------------------------------------------
24
25 extern void wxapp_install_idle_handler();
26 extern bool g_isIdle;
27
28 //-----------------------------------------------------------------------------
29 // data
30 //-----------------------------------------------------------------------------
31
32 extern bool g_blockEventsOnDrag;
33
34 //-----------------------------------------------------------------------------
35 // "clicked" (internal from gtk_toolbar)
36 //-----------------------------------------------------------------------------
37
38 static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool )
39 {
40 if (g_isIdle) wxapp_install_idle_handler();
41
42 if (g_blockEventsOnDrag) return;
43 if (!tool->m_enabled) return;
44
45 if (tool->m_isToggle) tool->m_toggleState = !tool->m_toggleState;
46
47 tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState );
48 }
49
50 //-----------------------------------------------------------------------------
51 // "enter_notify_event"
52 //-----------------------------------------------------------------------------
53
54 static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget),
55 GdkEventCrossing *WXUNUSED(gdk_event), wxToolBarTool *tool )
56 {
57 if (g_isIdle) wxapp_install_idle_handler();
58
59 if (g_blockEventsOnDrag) return TRUE;
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)
68 {
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 );
73
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 ) );
79
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
83 gtk_tooltips_set_colors( GTK_TOOLBAR(tb->m_toolbar)->tooltips, tb->m_bg, tb->m_fg );
84 #endif
85 }
86 }
87 else
88 {
89 if (tb->m_fg->red == 0)
90 {
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 );
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 ) );
100
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
104 gtk_tooltips_set_colors( GTK_TOOLBAR(tb->m_toolbar)->tooltips, tb->m_bg, tb->m_fg );
105 #endif
106 }
107 }
108
109 /* emit the event */
110
111 tb->OnMouseEnter( tool->m_index );
112
113 return FALSE;
114 }
115
116 //-----------------------------------------------------------------------------
117 // wxToolBar
118 //-----------------------------------------------------------------------------
119
120 IMPLEMENT_DYNAMIC_CLASS(wxToolBar,wxControl)
121
122 BEGIN_EVENT_TABLE(wxToolBar, wxControl)
123 EVT_IDLE(wxToolBar::OnIdle)
124 END_EVENT_TABLE()
125
126 wxToolBar::wxToolBar()
127 {
128 }
129
130 wxToolBar::wxToolBar( wxWindow *parent, wxWindowID id,
131 const wxPoint& pos, const wxSize& size,
132 long style, const wxString& name )
133 {
134 Create( parent, id, pos, size, style, name );
135 }
136
137 wxToolBar::~wxToolBar()
138 {
139 delete m_fg;
140 delete m_bg;
141 }
142
143 bool wxToolBar::Create( wxWindow *parent, wxWindowID id,
144 const wxPoint& pos, const wxSize& size,
145 long style, const wxString& name )
146 {
147 m_needParent = TRUE;
148
149 PreCreation( parent, id, pos, size, style, name );
150
151 m_tools.DeleteContents( TRUE );
152
153 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL,
154 GTK_TOOLBAR_ICONS ) );
155
156 m_separation = 5;
157 gtk_toolbar_set_space_size( m_toolbar, m_separation );
158 m_hasToolAlready = FALSE;
159
160 if (style & wxTB_DOCKABLE)
161 {
162 m_widget = gtk_handle_box_new();
163 gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
164 gtk_widget_show( GTK_WIDGET(m_toolbar) );
165
166 #if (GTK_MINOR_VERSION > 0)
167 if (style & wxTB_FLAT)
168 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
169 #endif
170 }
171 else
172 {
173 m_widget = GTK_WIDGET(m_toolbar);
174 }
175
176 gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE );
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
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 );
188
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 );
194
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 ) );
202
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
206 gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar)->tooltips, m_bg, m_fg );
207 #endif
208
209 m_xMargin = 0;
210 m_yMargin = 0;
211
212 m_parent->DoAddChild( this );
213
214 PostCreation();
215
216 Show( TRUE );
217
218 return TRUE;
219 }
220
221 bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown )
222 {
223 wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex );
224 event.SetEventObject(this);
225 event.SetInt( toolIndex );
226 event.SetExtraLong((long) toggleDown);
227
228 GetEventHandler()->ProcessEvent(event);
229
230 return TRUE;
231 }
232
233 void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
234 {
235 wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex );
236 event.SetEventObject( this );
237 event.SetInt( toolIndex );
238
239 GetEventHandler()->ProcessEvent(event);
240 }
241
242 void wxToolBar::OnMouseEnter( int toolIndex )
243 {
244 wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() );
245 event.SetEventObject(this);
246 event.SetInt( toolIndex );
247
248 GetEventHandler()->ProcessEvent(event);
249 }
250
251 wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap,
252 const wxBitmap& pushedBitmap, bool toggle,
253 float WXUNUSED(xPos), float WXUNUSED(yPos), wxObject *clientData,
254 const wxString& helpString1, const wxString& helpString2 )
255 {
256 m_hasToolAlready = TRUE;
257
258 wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL,
259 _T("invalid bitmap for wxToolBar icon") );
260
261 wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL,
262 _T("wxToolBar doesn't support GdkBitmap") );
263
264 wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL,
265 _T("wxToolBar::Add needs a wxBitmap") );
266
267 GtkWidget *tool_pixmap = (GtkWidget *)NULL;
268
269 GdkPixmap *pixmap = bitmap.GetPixmap();
270
271 GdkBitmap *mask = (GdkBitmap *)NULL;
272 if ( bitmap.GetMask() )
273 mask = bitmap.GetMask()->GetBitmap();
274
275 tool_pixmap = gtk_pixmap_new( pixmap, mask );
276
277 gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
278
279 wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap,
280 toggle, clientData,
281 helpString1, helpString2,
282 tool_pixmap );
283
284 GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
285 : GTK_TOOLBAR_CHILD_BUTTON;
286
287 GtkWidget *item = gtk_toolbar_append_element
288 (
289 GTK_TOOLBAR(m_toolbar),
290 ctype,
291 (GtkWidget *)NULL,
292 (const char *)NULL,
293 helpString1.mbc_str(),
294 "",
295 tool_pixmap,
296 (GtkSignalFunc)gtk_toolbar_callback,
297 (gpointer)tool
298 );
299
300 tool->m_item = item;
301
302 gtk_signal_connect( GTK_OBJECT(tool->m_item),
303 "enter_notify_event",
304 GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback),
305 (gpointer)tool );
306
307 m_tools.Append( tool );
308
309 return tool;
310 }
311
312 void wxToolBar::AddSeparator()
313 {
314 gtk_toolbar_append_space( m_toolbar );
315 }
316
317 void wxToolBar::ClearTools()
318 {
319 wxFAIL_MSG( _T("wxToolBar::ClearTools not implemented") );
320 }
321
322 bool wxToolBar::Realize()
323 {
324 m_x = 0;
325 m_y = 0;
326 m_width = 100;
327 m_height = 0;
328
329 wxNode *node = m_tools.First();
330 while (node)
331 {
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 }
338
339 node = node->Next();
340 }
341
342 m_height += 5 + 2*m_yMargin;
343
344 return TRUE;
345 }
346
347 void wxToolBar::EnableTool(int toolIndex, bool enable)
348 {
349 wxNode *node = m_tools.First();
350 while (node)
351 {
352 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
353 if (tool->m_index == toolIndex)
354 {
355 tool->m_enabled = enable;
356
357 /* we don't disable the tools for now as the bitmaps don't get
358 greyed anyway and this also disables tooltips
359
360 if (tool->m_item)
361 gtk_widget_set_sensitive( tool->m_item, enable );
362 */
363
364 return;
365 }
366 node = node->Next();
367 }
368
369 wxFAIL_MSG( _T("wrong toolbar index") );
370 }
371
372 void wxToolBar::ToggleTool( int toolIndex, bool toggle )
373 {
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();
386 }
387
388 wxFAIL_MSG( _T("wrong toolbar index") );
389 }
390
391 wxObject *wxToolBar::GetToolClientData( int index ) const
392 {
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 }
400
401 wxFAIL_MSG( _T("wrong toolbar index") );
402
403 return (wxObject*)NULL;
404 }
405
406 bool wxToolBar::GetToolState(int toolIndex) const
407 {
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 }
415
416 wxFAIL_MSG( _T("wrong toolbar index") );
417
418 return FALSE;
419 }
420
421 bool wxToolBar::GetToolEnabled(int toolIndex) const
422 {
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 }
430
431 wxFAIL_MSG( _T("wrong toolbar index") );
432
433 return FALSE;
434 }
435
436 void wxToolBar::SetMargins( int x, int y )
437 {
438 wxCHECK_RET( !m_hasToolAlready, _T("wxToolBar::SetMargins must be called before adding tool.") );
439
440 if (x > 2) gtk_toolbar_append_space( m_toolbar ); // oh well
441
442 m_xMargin = x;
443 m_yMargin = y;
444 }
445
446 void wxToolBar::SetToolPacking( int WXUNUSED(packing) )
447 {
448 wxFAIL_MSG( _T("wxToolBar::SetToolPacking not implemented") );
449 }
450
451 void wxToolBar::SetToolSeparation( int separation )
452 {
453 gtk_toolbar_set_space_size( m_toolbar, separation );
454 m_separation = separation;
455 }
456
457 int wxToolBar::GetToolPacking()
458 {
459 return 0;
460 }
461
462 int wxToolBar::GetToolSeparation()
463 {
464 return m_separation;
465 }
466
467 wxString 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
480 wxFAIL_MSG( _T("wrong toolbar index") );
481
482 return _T("");
483 }
484
485 wxString 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
498 wxFAIL_MSG( _T("wrong toolbar index") );
499
500 return _T("");
501 }
502
503 void 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;
512 return;
513 }
514 node = node->Next();
515 }
516
517 wxFAIL_MSG( _T("wrong toolbar index") );
518
519 return;
520 }
521
522 void 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;
531 return;
532 }
533 node = node->Next();
534 }
535
536 wxFAIL_MSG( _T("wrong toolbar index") );
537
538 return;
539 }
540
541 void 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 }
568