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