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