]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/tbargtk.cpp
fixed compilation under Unix where SQL_DATETIME is not defined
[wxWidgets.git] / src / gtk1 / tbargtk.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: tbargtk.cpp
3// Purpose: GTK toolbar
4// Author: Robert Roebling
5// Modified: 13.12.99 by VZ to derive from wxToolBarBase
6// RCS-ID: $Id$
7// Copyright: (c) Robert Roebling
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19#ifdef __GNUG__
20 #pragma implementation "tbargtk.h"
21#endif
22
23#include "wx/toolbar.h"
24
25#if wxUSE_TOOLBAR_NATIVE
26
27#include "wx/frame.h"
28
29#include <glib.h>
30#include "wx/gtk/private.h"
31
32extern GdkFont *GtkGetDefaultGuiFont();
33
34// ----------------------------------------------------------------------------
35// globals
36// ----------------------------------------------------------------------------
37
38// idle system
39extern void wxapp_install_idle_handler();
40extern bool g_isIdle;
41
42// data
43extern bool g_blockEventsOnDrag;
44extern wxCursor g_globalCursor;
45
46// ----------------------------------------------------------------------------
47// wxToolBarTool
48// ----------------------------------------------------------------------------
49
50class wxToolBarTool : public wxToolBarToolBase
51{
52public:
53 wxToolBarTool(wxToolBar *tbar,
54 int id,
55 const wxBitmap& bitmap1,
56 const wxBitmap& bitmap2,
57 bool toggle,
58 wxObject *clientData,
59 const wxString& shortHelpString,
60 const wxString& longHelpString)
61 : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle,
62 clientData, shortHelpString, longHelpString)
63 {
64 Init();
65 }
66
67 wxToolBarTool(wxToolBar *tbar, wxControl *control)
68 : wxToolBarToolBase(tbar, control)
69 {
70 Init();
71 }
72
73 GtkWidget *m_item;
74 GtkWidget *m_pixmap;
75
76protected:
77 void Init();
78};
79
80// ----------------------------------------------------------------------------
81// wxWin macros
82// ----------------------------------------------------------------------------
83
84IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
85
86// ============================================================================
87// implementation
88// ============================================================================
89
90//-----------------------------------------------------------------------------
91// "clicked" (internal from gtk_toolbar)
92//-----------------------------------------------------------------------------
93
94static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget),
95 wxToolBarTool *tool )
96{
97 if (g_isIdle)
98 wxapp_install_idle_handler();
99
100 wxToolBar *tbar = (wxToolBar *)tool->GetToolBar();
101
102 if (tbar->m_blockEvent) return;
103
104 if (g_blockEventsOnDrag) return;
105 if (!tool->IsEnabled()) return;
106
107 if (tool->CanBeToggled())
108 {
109 tool->Toggle();
110
111 wxBitmap bitmap = tool->GetBitmap();
112 if ( bitmap.Ok() )
113 {
114 GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap );
115
116 GdkBitmap *mask = bitmap.GetMask() ? bitmap.GetMask()->GetBitmap()
117 : (GdkBitmap *)NULL;
118
119 gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
120 }
121 }
122
123 tbar->OnLeftClick( tool->GetId(), tool->IsToggled() );
124}
125
126//-----------------------------------------------------------------------------
127// "enter_notify_event" / "leave_notify_event"
128//-----------------------------------------------------------------------------
129
130static gint gtk_toolbar_tool_callback( GtkWidget *WXUNUSED(widget),
131 GdkEventCrossing *gdk_event,
132 wxToolBarTool *tool )
133{
134 if (g_isIdle) wxapp_install_idle_handler();
135
136 if (g_blockEventsOnDrag) return TRUE;
137
138 wxToolBar *tb = (wxToolBar *)tool->GetToolBar();
139
140 // emit the event
141 if( gdk_event->type == GDK_ENTER_NOTIFY )
142 tb->OnMouseEnter( tool->GetId() );
143 else
144 tb->OnMouseEnter( -1 );
145
146 return FALSE;
147}
148
149//-----------------------------------------------------------------------------
150// InsertChild callback for wxToolBar
151//-----------------------------------------------------------------------------
152
153static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent),
154 wxWindow* WXUNUSED(child) )
155{
156 // we don't do anything here
157}
158
159// ----------------------------------------------------------------------------
160// wxToolBarTool
161// ----------------------------------------------------------------------------
162
163void wxToolBarTool::Init()
164{
165 m_item =
166 m_pixmap = (GtkWidget *)NULL;
167}
168
169wxToolBarToolBase *wxToolBar::CreateTool(int id,
170 const wxBitmap& bitmap1,
171 const wxBitmap& bitmap2,
172 bool toggle,
173 wxObject *clientData,
174 const wxString& shortHelpString,
175 const wxString& longHelpString)
176{
177 return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle,
178 clientData, shortHelpString, longHelpString);
179}
180
181wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
182{
183 return new wxToolBarTool(this, control);
184}
185
186//-----------------------------------------------------------------------------
187// wxToolBar construction
188//-----------------------------------------------------------------------------
189
190void wxToolBar::Init()
191{
192 m_fg =
193 m_bg = (GdkColor *)NULL;
194 m_toolbar = (GtkToolbar *)NULL;
195 m_blockEvent = FALSE;
196}
197
198wxToolBar::~wxToolBar()
199{
200 delete m_fg;
201 delete m_bg;
202}
203
204bool wxToolBar::Create( wxWindow *parent,
205 wxWindowID id,
206 const wxPoint& pos,
207 const wxSize& size,
208 long style,
209 const wxString& name )
210{
211 m_needParent = TRUE;
212 m_insertCallback = (wxInsertChildFunction)wxInsertChildInToolBar;
213
214 if ( !PreCreation( parent, pos, size ) ||
215 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
216 {
217 wxFAIL_MSG( wxT("wxToolBar creation failed") );
218
219 return FALSE;
220 }
221
222 GtkOrientation orient = style & wxTB_VERTICAL ? GTK_ORIENTATION_VERTICAL
223 : GTK_ORIENTATION_HORIZONTAL;
224
225#ifdef __WXGTK20__
226 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
227 gtk_toolbar_set_orientation(m_toolbar, orient);
228 gtk_toolbar_set_style(m_toolbar, GTK_TOOLBAR_ICONS);
229#else
230 m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( orient, GTK_TOOLBAR_ICONS ) );
231#endif
232
233 SetToolSeparation(7);
234
235 if (style & wxTB_DOCKABLE)
236 {
237 m_widget = gtk_handle_box_new();
238 gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) );
239 gtk_widget_show( GTK_WIDGET(m_toolbar) );
240
241 if (style & wxTB_FLAT)
242 gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE );
243 }
244 else
245 {
246 m_widget = GTK_WIDGET(m_toolbar);
247 }
248
249 gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE );
250
251 // FIXME: there is no such function for toolbars in 2.0
252#ifndef __WXGTK20__
253 if (style & wxTB_FLAT)
254 gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE );
255#endif
256
257
258 m_fg = new GdkColor;
259 m_fg->red = 0;
260 m_fg->green = 0;
261 m_fg->blue = 0;
262 wxColour fg(0,0,0);
263 fg.CalcPixel( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ) );
264 m_fg->pixel = fg.GetPixel();
265
266 m_bg = new GdkColor;
267 m_bg->red = 65535;
268 m_bg->green = 65535;
269 m_bg->blue = 49980;
270 wxColour bg(255,255,196);
271 bg.CalcPixel( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ) );
272 m_bg->pixel = bg.GetPixel();
273
274 gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar)->tooltips );
275
276 GtkStyle *g_style =
277 gtk_style_copy(
278 gtk_widget_get_style(
279 GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) );
280
281 g_style->bg[GTK_STATE_NORMAL] = *m_bg;
282
283 SET_STYLE_FONT(g_style, GtkGetDefaultGuiFont());
284
285 gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style );
286
287 m_parent->DoAddChild( this );
288
289 PostCreation();
290
291 Show( TRUE );
292
293 return TRUE;
294}
295
296bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
297{
298 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
299
300 // we have inserted a space before all the tools
301 if (m_xMargin > 1) pos++;
302
303 if ( tool->IsButton() )
304 {
305 wxBitmap bitmap = tool->GetNormalBitmap();
306
307 wxCHECK_MSG( bitmap.Ok(), FALSE,
308 wxT("invalid bitmap for wxToolBar icon") );
309
310 wxCHECK_MSG( bitmap.GetBitmap() == NULL, FALSE,
311 wxT("wxToolBar doesn't support GdkBitmap") );
312
313 wxCHECK_MSG( bitmap.GetPixmap() != NULL, FALSE,
314 wxT("wxToolBar::Add needs a wxBitmap") );
315
316 GtkWidget *tool_pixmap = (GtkWidget *)NULL;
317
318 GdkPixmap *pixmap = bitmap.GetPixmap();
319
320 GdkBitmap *mask = (GdkBitmap *)NULL;
321 if ( bitmap.GetMask() )
322 mask = bitmap.GetMask()->GetBitmap();
323
324 tool_pixmap = gtk_pixmap_new( pixmap, mask );
325#if (GTK_MINOR_VERSION > 0)
326 gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE );
327#endif
328
329 gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 );
330
331 tool->m_pixmap = tool_pixmap;
332 }
333
334 switch ( tool->GetStyle() )
335 {
336 case wxTOOL_STYLE_BUTTON:
337 tool->m_item = gtk_toolbar_insert_element
338 (
339 m_toolbar,
340 tool->CanBeToggled()
341 ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
342 : GTK_TOOLBAR_CHILD_BUTTON,
343 (GtkWidget *)NULL,
344 (const char *)NULL,
345 tool->GetShortHelp().mbc_str(),
346 "", // tooltip_private_text (?)
347 tool->m_pixmap,
348 (GtkSignalFunc)gtk_toolbar_callback,
349 (gpointer)tool,
350 pos
351 );
352
353 if ( !tool->m_item )
354 {
355 wxFAIL_MSG( _T("gtk_toolbar_insert_element() failed") );
356
357 return FALSE;
358 }
359
360 gtk_signal_connect( GTK_OBJECT(tool->m_item),
361 "enter_notify_event",
362 GTK_SIGNAL_FUNC(gtk_toolbar_tool_callback),
363 (gpointer)tool );
364 gtk_signal_connect( GTK_OBJECT(tool->m_item),
365 "leave_notify_event",
366 GTK_SIGNAL_FUNC(gtk_toolbar_tool_callback),
367 (gpointer)tool );
368 break;
369
370 case wxTOOL_STYLE_SEPARATOR:
371 gtk_toolbar_insert_space( m_toolbar, pos );
372
373 // skip the rest
374 return TRUE;
375
376 case wxTOOL_STYLE_CONTROL:
377 gtk_toolbar_insert_widget(
378 m_toolbar,
379 tool->GetControl()->m_widget,
380 (const char *) NULL,
381 (const char *) NULL,
382 pos
383 );
384 break;
385 }
386
387 GtkRequisition req;
388 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
389 (m_widget, &req );
390 m_width = req.width + m_xMargin;
391 m_height = req.height + 2*m_yMargin;
392
393 return TRUE;
394}
395
396bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
397{
398 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
399
400 switch ( tool->GetStyle() )
401 {
402 case wxTOOL_STYLE_CONTROL:
403 tool->GetControl()->Destroy();
404 break;
405
406 case wxTOOL_STYLE_BUTTON:
407 gtk_widget_destroy( tool->m_item );
408 break;
409
410 //case wxTOOL_STYLE_SEPARATOR: -- nothing to do
411 }
412
413 return TRUE;
414}
415
416// ----------------------------------------------------------------------------
417// wxToolBar tools state
418// ----------------------------------------------------------------------------
419
420void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
421{
422#if (GTK_MINOR_VERSION > 0)
423 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
424
425 /* we don't disable the tools for GTK 1.0 as the bitmaps don't get
426 greyed anyway and this also disables tooltips */
427 if (tool->m_item)
428 gtk_widget_set_sensitive( tool->m_item, enable );
429#endif
430}
431
432void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle )
433{
434 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
435
436 GtkWidget *item = tool->m_item;
437 if ( item && GTK_IS_TOGGLE_BUTTON(item) )
438 {
439 wxBitmap bitmap = tool->GetBitmap();
440 if ( bitmap.Ok() )
441 {
442 GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap );
443
444 GdkBitmap *mask = bitmap.GetMask() ? bitmap.GetMask()->GetBitmap()
445 : (GdkBitmap *)NULL;
446
447 gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
448 }
449
450 m_blockEvent = TRUE;
451
452 gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(item), toggle );
453
454 m_blockEvent = FALSE;
455 }
456}
457
458void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
459 bool WXUNUSED(toggle))
460{
461 // VZ: absolutely no idea about how to do it
462 wxFAIL_MSG( _T("not implemented") );
463}
464
465// ----------------------------------------------------------------------------
466// wxToolBar geometry
467// ----------------------------------------------------------------------------
468
469wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x),
470 wxCoord WXUNUSED(y)) const
471{
472 // VZ: GTK+ doesn't seem to have such thing
473 wxFAIL_MSG( _T("wxToolBar::FindToolForPosition() not implemented") );
474
475 return (wxToolBarToolBase *)NULL;
476}
477
478void wxToolBar::SetMargins( int x, int y )
479{
480 wxCHECK_RET( GetToolsCount() == 0,
481 wxT("wxToolBar::SetMargins must be called before adding tools.") );
482
483 if (x > 1) gtk_toolbar_append_space( m_toolbar ); // oh well
484
485 m_xMargin = x;
486 m_yMargin = y;
487}
488
489void wxToolBar::SetToolSeparation( int separation )
490{
491 // FIXME: this function disappeared
492#ifndef __WXGTK20__
493 gtk_toolbar_set_space_size( m_toolbar, separation );
494#endif
495
496 m_toolSeparation = separation;
497}
498
499void wxToolBar::SetToolShortHelp( int id, const wxString& helpString )
500{
501 wxToolBarTool *tool = (wxToolBarTool *)FindById(id);
502
503 if ( tool )
504 {
505 (void)tool->SetShortHelp(helpString);
506 gtk_tooltips_set_tip(m_toolbar->tooltips, tool->m_item,
507 helpString.mbc_str(), "");
508 }
509}
510
511// ----------------------------------------------------------------------------
512// wxToolBar idle handling
513// ----------------------------------------------------------------------------
514
515void wxToolBar::OnInternalIdle()
516{
517 wxCursor cursor = m_cursor;
518 if (g_globalCursor.Ok()) cursor = g_globalCursor;
519
520 if (cursor.Ok())
521 {
522 /* I now set the cursor the anew in every OnInternalIdle call
523 as setting the cursor in a parent window also effects the
524 windows above so that checking for the current cursor is
525 not possible. */
526
527 if (HasFlag(wxTB_DOCKABLE) && (m_widget->window))
528 {
529 /* if the toolbar is dockable, then m_widget stands for the
530 GtkHandleBox widget, which uses its own window so that we
531 can set the cursor for it. if the toolbar is not dockable,
532 m_widget comes from m_toolbar which uses its parent's
533 window ("windowless windows") and thus we cannot set the
534 cursor. */
535 gdk_window_set_cursor( m_widget->window, cursor.GetCursor() );
536 }
537
538 wxToolBarToolsList::Node *node = m_tools.GetFirst();
539 while ( node )
540 {
541 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
542 node = node->GetNext();
543
544 GtkWidget *item = tool->m_item;
545 if ( item )
546 {
547 GdkWindow *window = item->window;
548
549 if ( window )
550 {
551 gdk_window_set_cursor( window, cursor.GetCursor() );
552 }
553 }
554 }
555 }
556
557 UpdateWindowUI();
558}
559
560#endif // wxUSE_TOOLBAR_NATIVE