]> git.saurik.com Git - wxWidgets.git/blame - src/motif/toolbar.cpp
warning about standard controls
[wxWidgets.git] / src / motif / toolbar.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
8a0681f9 2// Name: motif/toolbar.cpp
4bb6408c
JS
3// Purpose: wxToolBar
4// Author: Julian Smart
8a0681f9 5// Modified by: 13.12.99 by VZ during toolbar classes reorganization
4bb6408c
JS
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
8a0681f9
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
8a0681f9 21 #pragma implementation "toolbar.h"
4bb6408c
JS
22#endif
23
1248b41f
MB
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
4dff3400
JJ
27#ifdef __VMS
28#define XtDisplay XTDISPLAY
29#endif
30
00dd3b18 31#include "wx/settings.h"
1a3ac83f
JS
32#include "wx/app.h"
33#include "wx/timer.h"
1ccbb61a 34#include "wx/toolbar.h"
46675b46 35#include "wx/frame.h"
0d57be45 36
338dd992
JJ
37#ifdef __VMS__
38#pragma message disable nosimpint
39#endif
0d57be45
JS
40#include <Xm/Xm.h>
41#include <Xm/PushBG.h>
42#include <Xm/PushB.h>
1a3ac83f 43#include <Xm/Label.h>
0d57be45
JS
44#include <Xm/ToggleB.h>
45#include <Xm/ToggleBG.h>
46#include <Xm/Form.h>
338dd992
JJ
47#ifdef __VMS__
48#pragma message enable nosimpint
49#endif
0d57be45
JS
50
51#include "wx/motif/private.h"
aae91497 52#include "wx/motif/bmpmotif.h"
4bb6408c 53
8a0681f9
VZ
54// ----------------------------------------------------------------------------
55// wxWin macros
56// ----------------------------------------------------------------------------
57
2eb10e2a 58IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
4bb6408c 59
8a0681f9
VZ
60// ----------------------------------------------------------------------------
61// private functions
62// ----------------------------------------------------------------------------
4bb6408c 63
1a3ac83f 64static void wxToolButtonCallback (Widget w, XtPointer clientData,
bf6c2b35 65 XtPointer ptr);
1a3ac83f
JS
66static void wxToolButtonPopupCallback (Widget w, XtPointer client_data,
67 XEvent *event, Boolean *continue_to_dispatch);
68
8a0681f9
VZ
69// ----------------------------------------------------------------------------
70// private classes
71// ----------------------------------------------------------------------------
72
73class wxToolBarTimer : public wxTimer
1a3ac83f
JS
74{
75public:
8a0681f9 76 virtual void Notify();
1a3ac83f 77
8a0681f9
VZ
78 static Widget help_popup;
79 static Widget buttonWidget;
80 static wxString helpString;
1a3ac83f
JS
81};
82
8a0681f9
VZ
83class wxToolBarTool : public wxToolBarToolBase
84{
85public:
86 wxToolBarTool(wxToolBar *tbar,
87 int id,
fcb35b5f
VZ
88 const wxString& label,
89 const wxBitmap& bmpNormal,
90 const wxBitmap& bmpToggled,
91 wxItemKind kind,
8a0681f9 92 wxObject *clientData,
fcb35b5f
VZ
93 const wxString& shortHelp,
94 const wxString& longHelp)
95 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpToggled, kind,
96 clientData, shortHelp, longHelp)
8a0681f9
VZ
97 {
98 Init();
99 }
100
101 wxToolBarTool(wxToolBar *tbar, wxControl *control)
102 : wxToolBarToolBase(tbar, control)
103 {
104 Init();
105 }
106
107 virtual ~wxToolBarTool();
108
109 // accessors
110 void SetWidget(Widget widget) { m_widget = widget; }
111 Widget GetButtonWidget() const { return m_widget; }
112
aae91497
MB
113 Pixmap GetArmPixmap()
114 {
115 m_bitmapCache.SetBitmap( GetNormalBitmap() );
116 return (Pixmap)m_bitmapCache.GetArmPixmap( (WXWidget)m_widget );
117 }
8a0681f9 118
aae91497
MB
119 Pixmap GetInsensPixmap()
120 {
121 m_bitmapCache.SetBitmap( GetNormalBitmap() );
122 return (Pixmap)m_bitmapCache.GetInsensPixmap( (WXWidget)m_widget );
123 }
8a0681f9
VZ
124protected:
125 void Init();
126
127 Widget m_widget;
aae91497 128 wxBitmapCache m_bitmapCache;
8a0681f9
VZ
129};
130
131// ----------------------------------------------------------------------------
132// globals
133// ----------------------------------------------------------------------------
134
1a3ac83f
JS
135static wxToolBarTimer* wxTheToolBarTimer = (wxToolBarTimer*) NULL;
136
137Widget wxToolBarTimer::help_popup = (Widget) 0;
138Widget wxToolBarTimer::buttonWidget = (Widget) 0;
8a0681f9
VZ
139wxString wxToolBarTimer::helpString;
140
141// ============================================================================
142// implementation
143// ============================================================================
144
145// ----------------------------------------------------------------------------
146// wxToolBarTool
147// ----------------------------------------------------------------------------
148
982b2cfc 149wxToolBarToolBase *wxToolBar::CreateTool(int id,
fcb35b5f
VZ
150 const wxString& label,
151 const wxBitmap& bmpNormal,
152 const wxBitmap& bmpToggled,
153 wxItemKind kind,
982b2cfc 154 wxObject *clientData,
fcb35b5f
VZ
155 const wxString& shortHelp,
156 const wxString& longHelp)
8a0681f9 157{
fcb35b5f
VZ
158 return new wxToolBarTool(this, id, label, bmpNormal, bmpToggled, kind,
159 clientData, shortHelp, longHelp);
8a0681f9 160}
1a3ac83f 161
fcb35b5f 162
982b2cfc 163wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
4bb6408c 164{
982b2cfc 165 return new wxToolBarTool(this, control);
4bb6408c
JS
166}
167
8a0681f9
VZ
168void wxToolBarTool::Init()
169{
170 m_widget = (Widget)0;
8a0681f9
VZ
171}
172
173wxToolBarTool::~wxToolBarTool()
174{
982b2cfc
VZ
175 if ( m_widget )
176 XtDestroyWidget(m_widget);
8a0681f9
VZ
177}
178
179// ----------------------------------------------------------------------------
180// wxToolBar construction
181// ----------------------------------------------------------------------------
182
183void wxToolBar::Init()
4bb6408c
JS
184{
185 m_maxWidth = -1;
186 m_maxHeight = -1;
4bb6408c
JS
187 m_defaultWidth = 24;
188 m_defaultHeight = 22;
7b28757f
JS
189 m_toolPacking = 2;
190 m_toolSeparation = 8;
191 m_xMargin = 2;
192 m_yMargin = 2;
193 m_maxRows = 100;
194 m_maxCols = 100;
8a0681f9
VZ
195}
196
197bool wxToolBar::Create(wxWindow *parent,
198 wxWindowID id,
199 const wxPoint& pos,
200 const wxSize& size,
201 long style,
202 const wxString& name)
203{
46675b46
MB
204 if( !wxControl::CreateControl( parent, id, pos, size, style,
205 wxDefaultValidator, name ) )
96be256b 206 return false;
8a0681f9 207
a756f210 208 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
4bb6408c 209
0d57be45
JS
210 Widget parentWidget = (Widget) parent->GetClientWidget();
211
212 Widget toolbar = XtVaCreateManagedWidget("toolbar",
7fe7d506
JS
213 xmBulletinBoardWidgetClass, (Widget) parentWidget,
214 XmNmarginWidth, 0,
215 XmNmarginHeight, 0,
216 XmNresizePolicy, XmRESIZE_NONE,
217 NULL);
218/*
219 Widget toolbar = XtVaCreateManagedWidget("toolbar",
220 xmFormWidgetClass, (Widget) m_clientWidget,
0d57be45
JS
221 XmNtraversalOn, False,
222 XmNhorizontalSpacing, 0,
223 XmNverticalSpacing, 0,
1a3ac83f
JS
224 XmNleftOffset, 0,
225 XmNrightOffset, 0,
226 XmNmarginWidth, 0,
227 XmNmarginHeight, 0,
0d57be45 228 NULL);
7fe7d506 229*/
0d57be45
JS
230
231 m_mainWidget = (WXWidget) toolbar;
232
96be256b 233 ChangeFont(false);
4b5f3fe6 234
46675b46
MB
235 wxPoint rPos = pos;
236 wxSize rSize = size;
237
238 if( rPos.x == -1 ) rPos.x = 0;
239 if( rPos.y == -1 ) rPos.y = 0;
240 if( rSize.x == -1 && GetParent() )
241 rSize.x = GetParent()->GetSize().x;
242
46675b46
MB
243 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
244 rPos.x, rPos.y, rSize.x, rSize.y);
0d57be45 245
0d57be45 246 ChangeBackgroundColour();
bf6c2b35 247
96be256b 248 return true;
4bb6408c
JS
249}
250
251wxToolBar::~wxToolBar()
252{
1a3ac83f
JS
253 delete wxTheToolBarTimer;
254 wxTheToolBarTimer = NULL;
4bb6408c
JS
255}
256
8a0681f9 257bool wxToolBar::Realize()
7fe7d506 258{
8a0681f9
VZ
259 if ( m_tools.GetCount() == 0 )
260 {
261 // nothing to do
96be256b 262 return true;
8a0681f9 263 }
7fe7d506 264
46675b46
MB
265 bool isVertical = GetWindowStyle() & wxTB_VERTICAL;
266
7fe7d506
JS
267 // Separator spacing
268 const int separatorSize = GetToolSeparation(); // 8;
269 wxSize margins = GetToolMargins();
f3979fcc 270 int packing = GetToolPacking();
7fe7d506
JS
271 int marginX = margins.x;
272 int marginY = margins.y;
273
274 int currentX = marginX;
275 int currentY = marginY;
276
46675b46 277 int buttonHeight = 0, buttonWidth = 0;
7fe7d506 278
8a0681f9
VZ
279 Widget button;
280 Pixmap pixmap, insensPixmap;
aae91497 281 wxBitmap bmp, insensBmp;
8a0681f9 282
ac32ba44 283 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
8a0681f9 284 while ( node )
7fe7d506 285 {
8a0681f9 286 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
7fe7d506 287
8a0681f9 288 switch ( tool->GetStyle() )
7fe7d506 289 {
8a0681f9 290 case wxTOOL_STYLE_CONTROL:
f3979fcc 291 {
66f55ec6
JS
292 wxControl* control = tool->GetControl();
293 wxSize sz = control->GetSize();
f3979fcc 294 wxPoint pos = control->GetPosition();
46675b46
MB
295 // Allow a control to specify a y[x]-offset by setting
296 // its initial position, but still don't allow it to
297 // position itself above the top[left] margin.
aae91497
MB
298 int controlY = (pos.y > 0) ? pos.y : currentY;
299 int controlX = (pos.x > 0) ? pos.x : currentX;
46675b46
MB
300 control->Move( isVertical ? controlX : currentX,
301 isVertical ? currentY : controlY );
302 if ( isVertical )
303 currentY += sz.y + packing;
304 else
305 currentX += sz.x + packing;
66f55ec6 306
8a0681f9 307 break;
f3979fcc 308 }
8a0681f9 309 case wxTOOL_STYLE_SEPARATOR:
aae91497
MB
310 // skip separators for vertical toolbars
311 if( !isVertical )
312 {
313 currentX += separatorSize;
314 }
8a0681f9 315 break;
7fe7d506 316
8a0681f9
VZ
317 case wxTOOL_STYLE_BUTTON:
318 button = (Widget) 0;
bf6c2b35 319
aae91497 320 if ( tool->CanBeToggled() && !tool->GetButtonWidget() )
7fe7d506 321 {
8a0681f9
VZ
322 button = XtVaCreateWidget("toggleButton",
323 xmToggleButtonWidgetClass, (Widget) m_mainWidget,
324 XmNx, currentX, XmNy, currentY,
e838cc14
VZ
325 XmNindicatorOn, False,
326 XmNshadowThickness, 2,
327 XmNborderWidth, 0,
328 XmNspacing, 0,
329 XmNmarginWidth, 0,
330 XmNmarginHeight, 0,
8a0681f9
VZ
331 XmNmultiClick, XmMULTICLICK_KEEP,
332 XmNlabelType, XmPIXMAP,
333 NULL);
aae91497
MB
334 XtAddCallback ((Widget) button,
335 XmNvalueChangedCallback,
336 (XtCallbackProc) wxToolButtonCallback,
337 (XtPointer) this);
8a0681f9
VZ
338
339 XtVaSetValues ((Widget) button,
aae91497
MB
340 XmNselectColor,
341 m_backgroundColour.AllocColour
342 (XtDisplay((Widget) button)),
343 NULL);
bf6c2b35 344 }
aae91497 345 else if( !tool->GetButtonWidget() )
8a0681f9
VZ
346 {
347 button = XtVaCreateWidget("button",
348 xmPushButtonWidgetClass, (Widget) m_mainWidget,
349 XmNx, currentX, XmNy, currentY,
350 XmNpushButtonEnabled, True,
351 XmNmultiClick, XmMULTICLICK_KEEP,
352 XmNlabelType, XmPIXMAP,
353 NULL);
354 XtAddCallback (button,
aae91497
MB
355 XmNactivateCallback,
356 (XtCallbackProc) wxToolButtonCallback,
357 (XtPointer) this);
8a0681f9 358 }
7fe7d506 359
aae91497
MB
360 if( !tool->GetButtonWidget() )
361 {
a8680e3e 362 wxDoChangeBackgroundColour((WXWidget) button,
96be256b 363 m_backgroundColour, true);
7fe7d506 364
aae91497
MB
365 tool->SetWidget(button);
366 }
367 else
368 {
369 button = (Widget)tool->GetButtonWidget();
370 XtVaSetValues( button,
371 XmNx, currentX, XmNy, currentY,
372 NULL );
373 }
7fe7d506 374
8a0681f9
VZ
375 // For each button, if there is a mask, we must create
376 // a new wxBitmap that has the correct background colour
377 // for the button. Otherwise the background will just be
378 // e.g. black if a transparent XPM has been loaded.
fcb35b5f 379 bmp = tool->GetNormalBitmap();
aae91497
MB
380 insensBmp = tool->GetDisabledBitmap();
381 if ( bmp.GetMask() || insensBmp.GetMask() )
7fe7d506 382 {
8a0681f9
VZ
383 int backgroundPixel;
384 XtVaGetValues(button, XmNbackground, &backgroundPixel,
aae91497 385 NULL);
8a0681f9
VZ
386
387 wxColour col;
388 col.SetPixel(backgroundPixel);
8a0681f9 389
aae0472b 390 if( bmp.Ok() && bmp.GetMask() )
aae91497
MB
391 {
392 bmp = wxCreateMaskedBitmap(bmp, col);
393 tool->SetNormalBitmap(bmp);
394 }
395
aae0472b 396 if( insensBmp.Ok() && insensBmp.GetMask() )
aae91497
MB
397 {
398 insensBmp = wxCreateMaskedBitmap(insensBmp, col);
399 tool->SetDisabledBitmap(insensBmp);
400 }
7fe7d506 401 }
8a0681f9
VZ
402
403 // Create a selected/toggled bitmap. If there isn't a 2nd
404 // bitmap, we need to create it (with a darker, selected
405 // background)
406 int backgroundPixel;
407 if ( tool->CanBeToggled() )
408 XtVaGetValues(button, XmNselectColor, &backgroundPixel,
aae91497 409 NULL);
7fe7d506 410 else
8a0681f9 411 XtVaGetValues(button, XmNarmColor, &backgroundPixel,
aae91497 412 NULL);
8a0681f9
VZ
413 wxColour col;
414 col.SetPixel(backgroundPixel);
415
aae0472b 416 pixmap = (Pixmap) bmp.GetDrawable();
aae91497
MB
417 {
418 wxBitmap tmp = tool->GetDisabledBitmap();
8a0681f9 419
aae91497 420 insensPixmap = tmp.Ok() ?
aae0472b 421 (Pixmap)tmp.GetDrawable() :
aae91497
MB
422 tool->GetInsensPixmap();
423 }
424
8a0681f9
VZ
425 if (tool->CanBeToggled())
426 {
427 // Toggle button
aae91497
MB
428 Pixmap pixmap2 = tool->GetArmPixmap();
429 Pixmap insensPixmap2 = tool->GetInsensPixmap();
982b2cfc 430
8a0681f9 431 XtVaSetValues (button,
8a0681f9
VZ
432 XmNfillOnSelect, True,
433 XmNlabelPixmap, pixmap,
434 XmNselectPixmap, pixmap2,
435 XmNlabelInsensitivePixmap, insensPixmap,
436 XmNselectInsensitivePixmap, insensPixmap2,
437 XmNlabelType, XmPIXMAP,
438 NULL);
7fe7d506
JS
439 }
440 else
441 {
aae91497 442 Pixmap pixmap2 = tool->GetArmPixmap();
982b2cfc 443
8a0681f9
VZ
444 // Normal button
445 XtVaSetValues(button,
446 XmNlabelPixmap, pixmap,
447 XmNlabelInsensitivePixmap, insensPixmap,
448 XmNarmPixmap, pixmap2,
449 NULL);
450 }
982b2cfc 451
8a0681f9 452 XtManageChild(button);
7fe7d506 453
8a0681f9
VZ
454 {
455 Dimension width, height;
456 XtVaGetValues(button,
457 XmNwidth, &width,
458 XmNheight, & height,
459 NULL);
46675b46
MB
460 if ( isVertical )
461 currentY += height + packing;
462 else
463 currentX += width + packing;
8a0681f9 464 buttonHeight = wxMax(buttonHeight, height);
46675b46 465 buttonWidth = wxMax(buttonWidth, width);
7fe7d506 466 }
8a0681f9
VZ
467
468 XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask,
469 False, wxToolButtonPopupCallback, (XtPointer) this);
470
8a0681f9 471 break;
7fe7d506 472 }
8a0681f9
VZ
473
474 node = node->GetNext();
7fe7d506
JS
475 }
476
46675b46 477 SetSize( -1, -1,
aae91497
MB
478 isVertical ? buttonWidth + 2 * marginX : -1,
479 isVertical ? -1 : buttonHeight + 2*marginY );
7fe7d506 480
96be256b 481 return true;
7fe7d506
JS
482}
483
982b2cfc
VZ
484wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x),
485 wxCoord WXUNUSED(y)) const
4bb6408c 486{
8a0681f9 487 wxFAIL_MSG( _T("TODO") );
4b5f3fe6 488
982b2cfc 489 return (wxToolBarToolBase *)NULL;
4bb6408c
JS
490}
491
982b2cfc 492bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
4bb6408c 493{
8a0681f9 494 tool->Attach(this);
4bb6408c 495
96be256b 496 return true;
4bb6408c
JS
497}
498
aae91497 499bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
4bb6408c 500{
8a0681f9 501 tool->Detach();
0d57be45 502
aae91497
MB
503 bool isVertical = GetWindowStyle() & wxTB_VERTICAL;
504 const int separatorSize = GetToolSeparation(); // 8;
505 int packing = GetToolPacking();
506 int offset = 0;
507
ac32ba44 508 for( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
aae91497
MB
509 node; node = node->GetNext() )
510 {
511 wxToolBarTool *t = (wxToolBarTool*)node->GetData();
512
513 if( t == tool )
514 {
515 switch ( t->GetStyle() )
516 {
517 case wxTOOL_STYLE_CONTROL:
518 {
519 wxSize size = t->GetControl()->GetSize();
520 offset = isVertical ? size.y : size.x;
521 offset += packing;
522 break;
523 }
524 case wxTOOL_STYLE_SEPARATOR:
525 offset = isVertical ? 0 : separatorSize;
526 break;
527 case wxTOOL_STYLE_BUTTON:
528 {
529 Widget w = t->GetButtonWidget();
530 Dimension width, height;
531
532 XtVaGetValues( w,
533 XmNwidth, &width,
534 XmNheight, &height,
535 NULL );
536
537 offset = isVertical ? height : width;
538 offset += packing;
539 break;
540 }
541 }
542 }
543 else if( offset )
544 {
545 switch ( t->GetStyle() )
546 {
547 case wxTOOL_STYLE_CONTROL:
548 {
549 wxPoint pos = t->GetControl()->GetPosition();
550
551 if( isVertical )
552 pos.y -= offset;
553 else
554 pos.x -= offset;
555
556 t->GetControl()->Move( pos );
557 break;
558 }
559 case wxTOOL_STYLE_SEPARATOR:
560 break;
561 case wxTOOL_STYLE_BUTTON:
562 {
563 Dimension x, y;
564 XtVaGetValues( t->GetButtonWidget(),
565 XmNx, &x,
566 XmNy, &y,
567 NULL );
568
569 if( isVertical )
570 y -= offset;
571 else
572 x -= offset;
573
574 XtVaSetValues( t->GetButtonWidget(),
575 XmNx, x,
576 XmNy, y,
577 NULL );
578 break;
579 }
580 }
581 }
582 }
583
96be256b 584 return true;
4bb6408c
JS
585}
586
982b2cfc 587void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
1a3ac83f 588{
982b2cfc 589 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
6707bb94
MB
590 if (tool->GetButtonWidget()){
591 XtSetSensitive(tool->GetButtonWidget(), (Boolean) enable);
592 } else if (wxTOOL_STYLE_CONTROL == tool->GetStyle()){
593 // Controls (such as wxChoice) do not have button widgets
594 tool->GetControl()->Enable(enable);
595 }
1a3ac83f
JS
596}
597
982b2cfc 598void wxToolBar::DoToggleTool(wxToolBarToolBase *toolBase, bool toggle)
4bb6408c 599{
982b2cfc
VZ
600 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
601
8a0681f9 602 XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False);
4bb6408c
JS
603}
604
982b2cfc
VZ
605void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
606 bool WXUNUSED(toggle))
1a3ac83f 607{
982b2cfc 608 // nothing to do
1a3ac83f
JS
609}
610
46675b46
MB
611void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
612{
613 int old_width, old_height;
614 GetSize(&old_width, &old_height);
615
46675b46
MB
616 // Correct width and height if needed.
617 if ( width == -1 || height == -1 )
618 {
aae91497 619 wxSize defaultSize = GetSize();
46675b46
MB
620
621 if ( width == -1 )
aae91497 622 width = defaultSize.x;
46675b46 623 if ( height == -1 )
aae91497 624 height = defaultSize.y;
46675b46 625 }
aae91497
MB
626
627 wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
46675b46
MB
628
629 // We must refresh the frame size when the toolbar changes size
630 // otherwise the toolbar can be shown incorrectly
631 if ( old_width != width || old_height != height )
632 {
633 // But before we send the size event check it
634 // we have a frame that is not being deleted.
635 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
636 if ( frame && !frame->IsBeingDeleted() )
637 {
638 frame->SendSizeEvent();
639 }
640 }
641}
642
8a0681f9
VZ
643// ----------------------------------------------------------------------------
644// Motif callbacks
645// ----------------------------------------------------------------------------
1a3ac83f 646
982b2cfc 647wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const
7fe7d506 648{
ac32ba44 649 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
8a0681f9
VZ
650 while ( node )
651 {
652 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
653 if ( tool->GetButtonWidget() == w)
654 {
655 return tool;
656 }
7fe7d506 657
8a0681f9
VZ
658 node = node->GetNext();
659 }
7fe7d506 660
982b2cfc 661 return (wxToolBarToolBase *)NULL;
7fe7d506
JS
662}
663
8a0681f9
VZ
664static void wxToolButtonCallback(Widget w,
665 XtPointer clientData,
666 XtPointer WXUNUSED(ptr))
1a3ac83f
JS
667{
668 wxToolBar *toolBar = (wxToolBar *) clientData;
982b2cfc 669 wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w);
8a0681f9
VZ
670 if ( !tool )
671 return;
1a3ac83f 672
8a0681f9
VZ
673 if ( tool->CanBeToggled() )
674 tool->Toggle();
675
676 if ( !toolBar->OnLeftClick(tool->GetId(), tool->IsToggled()) )
1a3ac83f 677 {
8a0681f9
VZ
678 // revert
679 tool->Toggle();
1a3ac83f 680 }
1a3ac83f
JS
681}
682
1a3ac83f 683
8a0681f9
VZ
684static void wxToolButtonPopupCallback(Widget w,
685 XtPointer client_data,
686 XEvent *event,
687 Boolean *WXUNUSED(continue_to_dispatch))
1a3ac83f
JS
688{
689 // TODO: retrieve delay before popping up tooltip from wxSystemSettings.
8a0681f9 690 static const int delayMilli = 800;
1a3ac83f 691
8a0681f9 692 wxToolBar* toolBar = (wxToolBar*) client_data;
982b2cfc 693 wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w);
1a3ac83f 694
8a0681f9
VZ
695 if ( !tool )
696 return;
1a3ac83f 697
8a0681f9
VZ
698 wxString tooltip = tool->GetShortHelp();
699 if ( !tooltip )
700 return;
1a3ac83f 701
8a0681f9
VZ
702 if (!wxTheToolBarTimer)
703 wxTheToolBarTimer = new wxToolBarTimer;
1a3ac83f 704
8a0681f9
VZ
705 wxToolBarTimer::buttonWidget = w;
706 wxToolBarTimer::helpString = tooltip;
1a3ac83f
JS
707
708 /************************************************************/
709 /* Popup help label */
710 /************************************************************/
711 if (event->type == EnterNotify)
712 {
713 if (wxToolBarTimer::help_popup != (Widget) 0)
714 {
715 XtDestroyWidget (wxToolBarTimer::help_popup);
716 XtPopdown (wxToolBarTimer::help_popup);
bf6c2b35 717 }
1a3ac83f
JS
718 wxToolBarTimer::help_popup = (Widget) 0;
719
720 // One shot
96be256b 721 wxTheToolBarTimer->Start(delayMilli, true);
1a3ac83f
JS
722
723 }
724 /************************************************************/
725 /* Popdown help label */
726 /************************************************************/
727 else if (event->type == LeaveNotify)
728 {
729 if (wxTheToolBarTimer)
730 wxTheToolBarTimer->Stop();
731 if (wxToolBarTimer::help_popup != (Widget) 0)
732 {
733 XtDestroyWidget (wxToolBarTimer::help_popup);
734 XtPopdown (wxToolBarTimer::help_popup);
bf6c2b35 735 }
1a3ac83f
JS
736 wxToolBarTimer::help_popup = (Widget) 0;
737 }
1a3ac83f
JS
738}
739
740void wxToolBarTimer::Notify()
741{
742 Position x, y;
743
744 /************************************************************/
745 /* Create shell without window decorations */
746 /************************************************************/
bf6c2b35
VZ
747 help_popup = XtVaCreatePopupShell ("shell",
748 overrideShellWidgetClass, (Widget) wxTheApp->GetTopLevelWidget(),
1a3ac83f
JS
749 NULL);
750
751 /************************************************************/
752 /* Get absolute position on display of toolbar button */
753 /************************************************************/
754 XtTranslateCoords (buttonWidget,
bf6c2b35
VZ
755 (Position) 0,
756 (Position) 0,
1a3ac83f
JS
757 &x, &y);
758
759 // Move the tooltip more or less above the button
760 int yOffset = 20; // TODO: What should be really?
761 y -= yOffset;
762 if (y < yOffset) y = 0;
763
764 /************************************************************/
765 /* Set the position of the help popup */
766 /************************************************************/
bf6c2b35
VZ
767 XtVaSetValues (help_popup,
768 XmNx, (Position) x,
769 XmNy, (Position) y,
1a3ac83f 770 NULL);
bf6c2b35 771
1a3ac83f
JS
772 /************************************************************/
773 /* Create help label */
774 /************************************************************/
775 XmString text = XmStringCreateSimple ((char*) (const char*) helpString);
bf6c2b35
VZ
776 XtVaCreateManagedWidget ("help_label",
777 xmLabelWidgetClass, help_popup,
1a3ac83f 778 XmNlabelString, text,
bf6c2b35
VZ
779 XtVaTypedArg,
780 XmNforeground, XtRString, "black",
781 strlen("black")+1,
782 XtVaTypedArg,
783 XmNbackground, XtRString, "LightGoldenrod",
784 strlen("LightGoldenrod")+1,
1a3ac83f
JS
785 NULL);
786 XmStringFree (text);
787
788 /************************************************************/
789 /* Popup help label */
790 /************************************************************/
791 XtPopup (help_popup, XtGrabNone);
792}
793