]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/tbargtk.cpp
mini-bugs in wxMenu (it now converts / to \ in
[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 #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 else
167 {
168 m_widget = GTK_WIDGET(m_toolbar);
169 }
170
171 gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE );
172
173 m_fg = new GdkColor;
174 m_fg->red = 0;
175 m_fg->green = 0;
176 m_fg->blue = 0;
177 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_fg );
178
179 m_bg = new GdkColor;
180 m_bg->red = 65535;
181 m_bg->green = 65535;
182 m_bg->blue = 50000;
183 gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_bg );
184
185 #if (GTK_MINOR_VERSION > 0)
186 gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar)->tooltips );
187
188 GtkStyle *g_style =
189 gtk_style_copy(
190 gtk_widget_get_style(
191 GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) );
192
193 g_style->bg[GTK_STATE_NORMAL] = *m_bg;
194 gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style );
195 #else
196 gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar)->tooltips, m_bg, m_fg );
197 #endif
198
199 m_xMargin = 0;
200 m_yMargin = 0;
201
202 m_parent->AddChild( this );
203
204 (m_parent->m_insertCallback)( m_parent, this );
205
206 PostCreation();
207
208 Show( TRUE );
209
210 return TRUE;
211 }
212
213 bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown )
214 {
215 wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex );
216 event.SetEventObject(this);
217 event.SetInt( toolIndex );
218 event.SetExtraLong((long) toggleDown);
219
220 GetEventHandler()->ProcessEvent(event);
221
222 return TRUE;
223 }
224
225 void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) )
226 {
227 wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex );
228 event.SetEventObject( this );
229 event.SetInt( toolIndex );
230
231 GetEventHandler()->ProcessEvent(event);
232 }
233
234 void wxToolBar::OnMouseEnter( int toolIndex )
235 {
236 wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() );
237 event.SetEventObject(this);
238 event.SetInt( toolIndex );
239
240 GetEventHandler()->ProcessEvent(event);
241 }
242
243 wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap,
244 const wxBitmap& pushedBitmap, bool toggle,
245 float WXUNUSED(xPos), float WXUNUSED(yPos), wxObject *clientData,
246 const wxString& helpString1, const wxString& helpString2 )
247 {
248 m_hasToolAlready = TRUE;
249
250 wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL,
251 _T("invalid bitmap for wxToolBar icon") );
252
253 wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL,
254 _T("wxToolBar doesn't support GdkBitmap") );
255
256 wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL,
257 _T("wxToolBar::Add needs a wxBitmap") );
258
259 GtkWidget *tool_pixmap = (GtkWidget *)NULL;
260
261 GdkPixmap *pixmap = bitmap.GetPixmap();
262
263 GdkBitmap *mask = (GdkBitmap *)NULL;
264 if ( bitmap.GetMask() )
265 mask = bitmap.GetMask()->GetBitmap();
266
267 tool_pixmap = gtk_pixmap_new( pixmap, mask );
268
269 gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
270
271 wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap,
272 toggle, clientData,
273 helpString1, helpString2,
274 tool_pixmap );
275
276 GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
277 : GTK_TOOLBAR_CHILD_BUTTON;
278
279 GtkWidget *item = gtk_toolbar_append_element
280 (
281 GTK_TOOLBAR(m_toolbar),
282 ctype,
283 (GtkWidget *)NULL,
284 (const char *)NULL,
285 helpString1.mbc_str(),
286 "",
287 tool_pixmap,
288 (GtkSignalFunc)gtk_toolbar_callback,
289 (gpointer)tool
290 );
291
292 tool->m_item = item;
293
294 gtk_signal_connect( GTK_OBJECT(tool->m_item),
295 "enter_notify_event",
296 GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback),
297 (gpointer)tool );
298
299 m_tools.Append( tool );
300
301 return tool;
302 }
303
304 void wxToolBar::AddSeparator()
305 {
306 gtk_toolbar_append_space( m_toolbar );
307 }
308
309 void wxToolBar::ClearTools()
310 {
311 wxFAIL_MSG( _T("wxToolBar::ClearTools not implemented") );
312 }
313
314 bool wxToolBar::Realize()
315 {
316 m_x = 0;
317 m_y = 0;
318 m_width = 100;
319 m_height = 0;
320
321 wxNode *node = m_tools.First();
322 while (node)
323 {
324 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
325 if (tool->m_bitmap1.Ok())
326 {
327 int tool_height = tool->m_bitmap1.GetHeight();
328 if (tool_height > m_height) m_height = tool_height;
329 }
330
331 node = node->Next();
332 }
333
334 m_height += 5 + 2*m_yMargin;
335
336 return TRUE;
337 }
338
339 void wxToolBar::EnableTool(int toolIndex, bool enable)
340 {
341 wxNode *node = m_tools.First();
342 while (node)
343 {
344 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
345 if (tool->m_index == toolIndex)
346 {
347 tool->m_enabled = enable;
348
349 /* we don't disable the tools for now as the bitmaps don't get
350 greyed anyway and this also disables tooltips
351
352 if (tool->m_item)
353 gtk_widget_set_sensitive( tool->m_item, enable );
354 */
355
356 return;
357 }
358 node = node->Next();
359 }
360
361 wxFAIL_MSG( _T("wrong toolbar index") );
362 }
363
364 void wxToolBar::ToggleTool( int toolIndex, bool toggle )
365 {
366 wxNode *node = m_tools.First();
367 while (node)
368 {
369 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
370 if (tool->m_index == toolIndex)
371 {
372 tool->m_toggleState = toggle;
373 if ((tool->m_item) && (GTK_IS_TOGGLE_BUTTON(tool->m_item)))
374 gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool->m_item), toggle );
375 return;
376 }
377 node = node->Next();
378 }
379
380 wxFAIL_MSG( _T("wrong toolbar index") );
381 }
382
383 wxObject *wxToolBar::GetToolClientData( int index ) const
384 {
385 wxNode *node = m_tools.First();
386 while (node)
387 {
388 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
389 if (tool->m_index == index) return tool->m_clientData;;
390 node = node->Next();
391 }
392
393 wxFAIL_MSG( _T("wrong toolbar index") );
394
395 return (wxObject*)NULL;
396 }
397
398 bool wxToolBar::GetToolState(int toolIndex) const
399 {
400 wxNode *node = m_tools.First();
401 while (node)
402 {
403 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
404 if (tool->m_index == toolIndex) return tool->m_toggleState;
405 node = node->Next();
406 }
407
408 wxFAIL_MSG( _T("wrong toolbar index") );
409
410 return FALSE;
411 }
412
413 bool wxToolBar::GetToolEnabled(int toolIndex) const
414 {
415 wxNode *node = m_tools.First();
416 while (node)
417 {
418 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
419 if (tool->m_index == toolIndex) return tool->m_enabled;
420 node = node->Next();
421 }
422
423 wxFAIL_MSG( _T("wrong toolbar index") );
424
425 return FALSE;
426 }
427
428 void wxToolBar::SetMargins( int x, int y )
429 {
430 wxCHECK_RET( !m_hasToolAlready, _T("wxToolBar::SetMargins must be called before adding tool.") );
431
432 if (x > 2) gtk_toolbar_append_space( m_toolbar ); // oh well
433
434 m_xMargin = x;
435 m_yMargin = y;
436 }
437
438 void wxToolBar::SetToolPacking( int WXUNUSED(packing) )
439 {
440 wxFAIL_MSG( _T("wxToolBar::SetToolPacking not implemented") );
441 }
442
443 void wxToolBar::SetToolSeparation( int separation )
444 {
445 gtk_toolbar_set_space_size( m_toolbar, separation );
446 m_separation = separation;
447 }
448
449 int wxToolBar::GetToolPacking()
450 {
451 return 0;
452 }
453
454 int wxToolBar::GetToolSeparation()
455 {
456 return m_separation;
457 }
458
459 wxString wxToolBar::GetToolLongHelp(int toolIndex)
460 {
461 wxNode *node = m_tools.First();
462 while (node)
463 {
464 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
465 if (tool->m_index == toolIndex)
466 {
467 return tool->m_longHelpString;
468 }
469 node = node->Next();
470 }
471
472 wxFAIL_MSG( _T("wrong toolbar index") );
473
474 return _T("");
475 }
476
477 wxString wxToolBar::GetToolShortHelp(int toolIndex)
478 {
479 wxNode *node = m_tools.First();
480 while (node)
481 {
482 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
483 if (tool->m_index == toolIndex)
484 {
485 return tool->m_shortHelpString;
486 }
487 node = node->Next();
488 }
489
490 wxFAIL_MSG( _T("wrong toolbar index") );
491
492 return _T("");
493 }
494
495 void wxToolBar::SetToolLongHelp(int toolIndex, const wxString& helpString)
496 {
497 wxNode *node = m_tools.First();
498 while (node)
499 {
500 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
501 if (tool->m_index == toolIndex)
502 {
503 tool->m_longHelpString = helpString;
504 return;
505 }
506 node = node->Next();
507 }
508
509 wxFAIL_MSG( _T("wrong toolbar index") );
510
511 return;
512 }
513
514 void wxToolBar::SetToolShortHelp(int toolIndex, const wxString& helpString)
515 {
516 wxNode *node = m_tools.First();
517 while (node)
518 {
519 wxToolBarTool *tool = (wxToolBarTool*)node->Data();
520 if (tool->m_index == toolIndex)
521 {
522 tool->m_shortHelpString = helpString;
523 return;
524 }
525 node = node->Next();
526 }
527
528 wxFAIL_MSG( _T("wrong toolbar index") );
529
530 return;
531 }
532
533 void wxToolBar::OnIdle( wxIdleEvent &WXUNUSED(ievent) )
534 {
535 wxEvtHandler* evtHandler = GetEventHandler();
536
537 wxNode* node = m_tools.First();
538 while (node)
539 {
540 wxToolBarTool* tool = (wxToolBarTool*) node->Data();
541
542 wxUpdateUIEvent event( tool->m_index );
543 event.SetEventObject(this);
544
545 if (evtHandler->ProcessEvent( event ))
546 {
547 if (event.GetSetEnabled())
548 EnableTool(tool->m_index, event.GetEnabled());
549 if (event.GetSetChecked())
550 ToggleTool(tool->m_index, event.GetChecked());
551 /*
552 if (event.GetSetText())
553 // Set tooltip?
554 */
555 }
556
557 node = node->Next();
558 }
559 }
560