]> git.saurik.com Git - wxWidgets.git/blame - src/motif/toolbar.cpp
compilation fix for wxUSE_INTL == 0 (patch 646466)
[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
8a0681f9 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
8a0681f9
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
4bb6408c 20#ifdef __GNUG__
8a0681f9 21 #pragma implementation "toolbar.h"
4bb6408c
JS
22#endif
23
4dff3400
JJ
24#ifdef __VMS
25#define XtDisplay XTDISPLAY
26#endif
27
4bb6408c 28#include "wx/wx.h"
1a3ac83f
JS
29#include "wx/app.h"
30#include "wx/timer.h"
1ccbb61a 31#include "wx/toolbar.h"
0d57be45 32
338dd992
JJ
33#ifdef __VMS__
34#pragma message disable nosimpint
35#endif
0d57be45
JS
36#include <Xm/Xm.h>
37#include <Xm/PushBG.h>
38#include <Xm/PushB.h>
1a3ac83f 39#include <Xm/Label.h>
0d57be45
JS
40#include <Xm/ToggleB.h>
41#include <Xm/ToggleBG.h>
42#include <Xm/Form.h>
338dd992
JJ
43#ifdef __VMS__
44#pragma message enable nosimpint
45#endif
0d57be45
JS
46
47#include "wx/motif/private.h"
4bb6408c 48
8a0681f9
VZ
49// ----------------------------------------------------------------------------
50// wxWin macros
51// ----------------------------------------------------------------------------
52
53#if !USE_SHARED_LIBRARY
12ed316d 54IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
8a0681f9 55#endif
4bb6408c 56
8a0681f9
VZ
57// ----------------------------------------------------------------------------
58// private functions
59// ----------------------------------------------------------------------------
4bb6408c 60
1a3ac83f 61static void wxToolButtonCallback (Widget w, XtPointer clientData,
bf6c2b35 62 XtPointer ptr);
1a3ac83f
JS
63static void wxToolButtonPopupCallback (Widget w, XtPointer client_data,
64 XEvent *event, Boolean *continue_to_dispatch);
65
8a0681f9
VZ
66// ----------------------------------------------------------------------------
67// private classes
68// ----------------------------------------------------------------------------
69
70class wxToolBarTimer : public wxTimer
1a3ac83f
JS
71{
72public:
8a0681f9 73 virtual void Notify();
1a3ac83f 74
8a0681f9
VZ
75 static Widget help_popup;
76 static Widget buttonWidget;
77 static wxString helpString;
1a3ac83f
JS
78};
79
8a0681f9
VZ
80class wxToolBarTool : public wxToolBarToolBase
81{
82public:
83 wxToolBarTool(wxToolBar *tbar,
84 int id,
fcb35b5f
VZ
85 const wxString& label,
86 const wxBitmap& bmpNormal,
87 const wxBitmap& bmpToggled,
88 wxItemKind kind,
8a0681f9 89 wxObject *clientData,
fcb35b5f
VZ
90 const wxString& shortHelp,
91 const wxString& longHelp)
92 : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpToggled, kind,
93 clientData, shortHelp, longHelp)
8a0681f9
VZ
94 {
95 Init();
96 }
97
98 wxToolBarTool(wxToolBar *tbar, wxControl *control)
99 : wxToolBarToolBase(tbar, control)
100 {
101 Init();
102 }
103
104 virtual ~wxToolBarTool();
105
106 // accessors
107 void SetWidget(Widget widget) { m_widget = widget; }
108 Widget GetButtonWidget() const { return m_widget; }
109
110 void SetPixmap(Pixmap pixmap) { m_pixmap = pixmap; }
111 Pixmap GetPixmap() const { return m_pixmap; }
112
113protected:
114 void Init();
115
116 Widget m_widget;
117 Pixmap m_pixmap;
118};
119
120// ----------------------------------------------------------------------------
121// globals
122// ----------------------------------------------------------------------------
123
1a3ac83f
JS
124static wxToolBarTimer* wxTheToolBarTimer = (wxToolBarTimer*) NULL;
125
126Widget wxToolBarTimer::help_popup = (Widget) 0;
127Widget wxToolBarTimer::buttonWidget = (Widget) 0;
8a0681f9
VZ
128wxString wxToolBarTimer::helpString;
129
130// ============================================================================
131// implementation
132// ============================================================================
133
134// ----------------------------------------------------------------------------
135// wxToolBarTool
136// ----------------------------------------------------------------------------
137
982b2cfc 138wxToolBarToolBase *wxToolBar::CreateTool(int id,
fcb35b5f
VZ
139 const wxString& label,
140 const wxBitmap& bmpNormal,
141 const wxBitmap& bmpToggled,
142 wxItemKind kind,
982b2cfc 143 wxObject *clientData,
fcb35b5f
VZ
144 const wxString& shortHelp,
145 const wxString& longHelp)
8a0681f9 146{
fcb35b5f
VZ
147 return new wxToolBarTool(this, id, label, bmpNormal, bmpToggled, kind,
148 clientData, shortHelp, longHelp);
8a0681f9 149}
1a3ac83f 150
fcb35b5f 151
982b2cfc 152wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
4bb6408c 153{
982b2cfc 154 return new wxToolBarTool(this, control);
4bb6408c
JS
155}
156
8a0681f9
VZ
157void wxToolBarTool::Init()
158{
159 m_widget = (Widget)0;
160 m_pixmap = (Pixmap)0;
161}
162
163wxToolBarTool::~wxToolBarTool()
164{
982b2cfc
VZ
165 if ( m_widget )
166 XtDestroyWidget(m_widget);
2b5f62a0
VZ
167 // note: do not delete m_pixmap here because it will be deleted
168 // by the base class when the bitmap is destroyed.
8a0681f9
VZ
169}
170
171// ----------------------------------------------------------------------------
172// wxToolBar construction
173// ----------------------------------------------------------------------------
174
175void wxToolBar::Init()
4bb6408c
JS
176{
177 m_maxWidth = -1;
178 m_maxHeight = -1;
4bb6408c
JS
179 m_defaultWidth = 24;
180 m_defaultHeight = 22;
7b28757f
JS
181 m_toolPacking = 2;
182 m_toolSeparation = 8;
183 m_xMargin = 2;
184 m_yMargin = 2;
185 m_maxRows = 100;
186 m_maxCols = 100;
8a0681f9
VZ
187}
188
189bool wxToolBar::Create(wxWindow *parent,
190 wxWindowID id,
191 const wxPoint& pos,
192 const wxSize& size,
193 long style,
194 const wxString& name)
195{
196 Init();
197
198 m_windowId = id;
199
4bb6408c 200 SetName(name);
a756f210 201 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
0d57be45 202 m_foregroundColour = parent->GetForegroundColour();
4bb6408c
JS
203 m_windowStyle = style;
204
205 SetParent(parent);
206
207 if (parent) parent->AddChild(this);
208
0d57be45
JS
209 Widget parentWidget = (Widget) parent->GetClientWidget();
210
211 Widget toolbar = XtVaCreateManagedWidget("toolbar",
7fe7d506
JS
212 xmBulletinBoardWidgetClass, (Widget) parentWidget,
213 XmNmarginWidth, 0,
214 XmNmarginHeight, 0,
215 XmNresizePolicy, XmRESIZE_NONE,
216 NULL);
217/*
218 Widget toolbar = XtVaCreateManagedWidget("toolbar",
219 xmFormWidgetClass, (Widget) m_clientWidget,
0d57be45
JS
220 XmNtraversalOn, False,
221 XmNhorizontalSpacing, 0,
222 XmNverticalSpacing, 0,
1a3ac83f
JS
223 XmNleftOffset, 0,
224 XmNrightOffset, 0,
225 XmNmarginWidth, 0,
226 XmNmarginHeight, 0,
0d57be45 227 NULL);
7fe7d506 228*/
0d57be45
JS
229
230 m_mainWidget = (WXWidget) toolbar;
231
da175b2c 232 m_font = parent->GetFont();
4b5f3fe6
JS
233 ChangeFont(FALSE);
234
0d57be45
JS
235 SetCanAddEventHandler(TRUE);
236 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y);
237
0d57be45 238 ChangeBackgroundColour();
bf6c2b35 239
0d57be45 240 return TRUE;
4bb6408c
JS
241}
242
243wxToolBar::~wxToolBar()
244{
1a3ac83f
JS
245 delete wxTheToolBarTimer;
246 wxTheToolBarTimer = NULL;
4bb6408c
JS
247}
248
8a0681f9 249bool wxToolBar::Realize()
7fe7d506 250{
8a0681f9
VZ
251 if ( m_tools.GetCount() == 0 )
252 {
253 // nothing to do
254 return TRUE;
255 }
7fe7d506
JS
256
257 // Separator spacing
258 const int separatorSize = GetToolSeparation(); // 8;
259 wxSize margins = GetToolMargins();
f3979fcc 260 int packing = GetToolPacking();
7fe7d506
JS
261 int marginX = margins.x;
262 int marginY = margins.y;
263
264 int currentX = marginX;
265 int currentY = marginY;
266
267 int buttonHeight = 0;
268
269 int currentSpacing = 0;
270
8a0681f9
VZ
271 Widget button;
272 Pixmap pixmap, insensPixmap;
273 wxBitmap bmp;
274
275 wxToolBarToolsList::Node *node = m_tools.GetFirst();
276 while ( node )
7fe7d506 277 {
8a0681f9 278 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
7fe7d506 279
8a0681f9 280 switch ( tool->GetStyle() )
7fe7d506 281 {
8a0681f9 282 case wxTOOL_STYLE_CONTROL:
f3979fcc 283 {
66f55ec6
JS
284 wxControl* control = tool->GetControl();
285 wxSize sz = control->GetSize();
f3979fcc 286 wxPoint pos = control->GetPosition();
96c3039d
JS
287 // Allow a control to specify a y-offset by setting its initial position,
288 // but still don't allow it to position itself above the top margin.
289 int controlY = (pos.y > 0) ? currentY + pos.y : currentY;
290 control->Move(currentX, controlY);
f3979fcc 291 currentX += sz.x + packing;
66f55ec6 292
8a0681f9 293 break;
f3979fcc 294 }
8a0681f9
VZ
295 case wxTOOL_STYLE_SEPARATOR:
296 currentX += separatorSize;
297 break;
7fe7d506 298
8a0681f9
VZ
299 case wxTOOL_STYLE_BUTTON:
300 button = (Widget) 0;
bf6c2b35 301
8a0681f9 302 if ( tool->CanBeToggled() )
7fe7d506 303 {
8a0681f9
VZ
304 button = XtVaCreateWidget("toggleButton",
305 xmToggleButtonWidgetClass, (Widget) m_mainWidget,
306 XmNx, currentX, XmNy, currentY,
e838cc14
VZ
307 XmNindicatorOn, False,
308 XmNshadowThickness, 2,
309 XmNborderWidth, 0,
310 XmNspacing, 0,
311 XmNmarginWidth, 0,
312 XmNmarginHeight, 0,
8a0681f9
VZ
313 XmNmultiClick, XmMULTICLICK_KEEP,
314 XmNlabelType, XmPIXMAP,
315 NULL);
316 XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback,
317 (XtPointer) this);
318
319 XtVaSetValues ((Widget) button,
320 XmNselectColor, m_backgroundColour.AllocColour(XtDisplay((Widget) button)),
321 NULL);
bf6c2b35 322 }
7fe7d506 323 else
8a0681f9
VZ
324 {
325 button = XtVaCreateWidget("button",
326 xmPushButtonWidgetClass, (Widget) m_mainWidget,
327 XmNx, currentX, XmNy, currentY,
328 XmNpushButtonEnabled, True,
329 XmNmultiClick, XmMULTICLICK_KEEP,
330 XmNlabelType, XmPIXMAP,
331 NULL);
332 XtAddCallback (button,
333 XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback,
334 (XtPointer) this);
335 }
7fe7d506 336
8a0681f9 337 DoChangeBackgroundColour((WXWidget) button, m_backgroundColour, TRUE);
7fe7d506 338
8a0681f9 339 tool->SetWidget(button);
7fe7d506 340
8a0681f9
VZ
341 // For each button, if there is a mask, we must create
342 // a new wxBitmap that has the correct background colour
343 // for the button. Otherwise the background will just be
344 // e.g. black if a transparent XPM has been loaded.
fcb35b5f 345 bmp = tool->GetNormalBitmap();
8a0681f9 346 if ( bmp.GetMask() )
7fe7d506 347 {
8a0681f9
VZ
348 int backgroundPixel;
349 XtVaGetValues(button, XmNbackground, &backgroundPixel,
350 NULL);
351
352 wxColour col;
353 col.SetPixel(backgroundPixel);
354
e838cc14 355 bmp = wxCreateMaskedBitmap(bmp, col);
8a0681f9 356
fcb35b5f 357 tool->SetNormalBitmap(bmp);
7fe7d506 358 }
8a0681f9
VZ
359
360 // Create a selected/toggled bitmap. If there isn't a 2nd
361 // bitmap, we need to create it (with a darker, selected
362 // background)
363 int backgroundPixel;
364 if ( tool->CanBeToggled() )
365 XtVaGetValues(button, XmNselectColor, &backgroundPixel,
366 NULL);
7fe7d506 367 else
8a0681f9
VZ
368 XtVaGetValues(button, XmNarmColor, &backgroundPixel,
369 NULL);
370
371 wxColour col;
372 col.SetPixel(backgroundPixel);
373
fcb35b5f
VZ
374 // FIXME: we use disabled bitmap as the bitmap for the toggled
375 // state, we probably need a GetToggledBitmap() instead
376 wxBitmap bmpToggled = tool->GetDisabledBitmap();
377 if ( bmpToggled.Ok() && bmpToggled.GetMask())
7fe7d506 378 {
8a0681f9 379 // Use what's there
fcb35b5f
VZ
380 wxBitmap newBitmap = wxCreateMaskedBitmap(bmpToggled, col);
381 tool->SetDisabledBitmap(newBitmap);
7fe7d506 382 }
8a0681f9 383 else
7fe7d506 384 {
8a0681f9
VZ
385 // Use unselected bitmap
386 if ( bmp.GetMask() )
387 {
388 wxBitmap newBitmap = wxCreateMaskedBitmap(bmp, col);
fcb35b5f 389 tool->SetDisabledBitmap(newBitmap);
8a0681f9
VZ
390 }
391 else
fcb35b5f 392 tool->SetDisabledBitmap(bmp);
8a0681f9
VZ
393 }
394
fcb35b5f 395 // FIXME: and here we should use GetDisabledBitmap()...
8a0681f9
VZ
396 pixmap = (Pixmap) bmp.GetPixmap();
397 insensPixmap = (Pixmap) bmp.GetInsensPixmap();
398
399 if (tool->CanBeToggled())
400 {
401 // Toggle button
402 Pixmap pixmap2 = (Pixmap) 0;
403 Pixmap insensPixmap2 = (Pixmap) 0;
404
405 // If there's a bitmap for the toggled state, use it,
406 // otherwise generate one.
fcb35b5f
VZ
407 //
408 // FIXME: see above
409 if ( bmpToggled.Ok() )
8a0681f9 410 {
fcb35b5f
VZ
411 pixmap2 = (Pixmap) bmpToggled.GetPixmap();
412 insensPixmap2 = (Pixmap) bmpToggled.GetInsensPixmap();
8a0681f9
VZ
413 }
414 else
415 {
416 pixmap2 = (Pixmap) bmp.GetArmPixmap(button);
417 insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2);
418 }
419
982b2cfc
VZ
420 tool->SetPixmap(pixmap2);
421
8a0681f9 422 XtVaSetValues (button,
8a0681f9
VZ
423 XmNfillOnSelect, True,
424 XmNlabelPixmap, pixmap,
425 XmNselectPixmap, pixmap2,
426 XmNlabelInsensitivePixmap, insensPixmap,
427 XmNselectInsensitivePixmap, insensPixmap2,
428 XmNlabelType, XmPIXMAP,
429 NULL);
7fe7d506
JS
430 }
431 else
432 {
8a0681f9
VZ
433 Pixmap pixmap2 = (Pixmap) 0;
434
435 // If there's a bitmap for the armed state, use it,
436 // otherwise generate one.
fcb35b5f 437 if ( bmpToggled.Ok() )
8a0681f9 438 {
fcb35b5f 439 pixmap2 = (Pixmap) bmpToggled.GetPixmap();
8a0681f9
VZ
440 }
441 else
442 {
443 pixmap2 = (Pixmap) bmp.GetArmPixmap(button);
444
445 }
982b2cfc
VZ
446
447 tool->SetPixmap(pixmap2);
448
8a0681f9
VZ
449 // Normal button
450 XtVaSetValues(button,
451 XmNlabelPixmap, pixmap,
452 XmNlabelInsensitivePixmap, insensPixmap,
453 XmNarmPixmap, pixmap2,
454 NULL);
455 }
982b2cfc 456
8a0681f9 457 XtManageChild(button);
7fe7d506 458
8a0681f9
VZ
459 {
460 Dimension width, height;
461 XtVaGetValues(button,
462 XmNwidth, &width,
463 XmNheight, & height,
464 NULL);
f3979fcc 465 currentX += width + packing;
8a0681f9 466 buttonHeight = wxMax(buttonHeight, height);
7fe7d506 467 }
8a0681f9
VZ
468
469 XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask,
470 False, wxToolButtonPopupCallback, (XtPointer) this);
471
472 currentSpacing = 0;
473 break;
7fe7d506 474 }
8a0681f9
VZ
475
476 node = node->GetNext();
7fe7d506
JS
477 }
478
479 SetSize(-1, -1, currentX, buttonHeight + 2*marginY);
480
481 return TRUE;
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
8a0681f9 496 return TRUE;
4bb6408c
JS
497}
498
982b2cfc 499bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
4bb6408c 500{
8a0681f9 501 tool->Detach();
0d57be45 502
8a0681f9 503 return TRUE;
4bb6408c
JS
504}
505
982b2cfc 506void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
1a3ac83f 507{
982b2cfc
VZ
508 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
509
8a0681f9 510 XtSetSensitive(tool->GetButtonWidget(), (Boolean) enable);
1a3ac83f
JS
511}
512
982b2cfc 513void wxToolBar::DoToggleTool(wxToolBarToolBase *toolBase, bool toggle)
4bb6408c 514{
982b2cfc
VZ
515 wxToolBarTool *tool = (wxToolBarTool *)toolBase;
516
8a0681f9 517 XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False);
4bb6408c
JS
518}
519
982b2cfc
VZ
520void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
521 bool WXUNUSED(toggle))
1a3ac83f 522{
982b2cfc 523 // nothing to do
1a3ac83f
JS
524}
525
8a0681f9
VZ
526// ----------------------------------------------------------------------------
527// Motif callbacks
528// ----------------------------------------------------------------------------
1a3ac83f 529
982b2cfc 530wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const
7fe7d506 531{
8a0681f9
VZ
532 wxToolBarToolsList::Node* node = m_tools.GetFirst();
533 while ( node )
534 {
535 wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
536 if ( tool->GetButtonWidget() == w)
537 {
538 return tool;
539 }
7fe7d506 540
8a0681f9
VZ
541 node = node->GetNext();
542 }
7fe7d506 543
982b2cfc 544 return (wxToolBarToolBase *)NULL;
7fe7d506
JS
545}
546
8a0681f9
VZ
547static void wxToolButtonCallback(Widget w,
548 XtPointer clientData,
549 XtPointer WXUNUSED(ptr))
1a3ac83f
JS
550{
551 wxToolBar *toolBar = (wxToolBar *) clientData;
982b2cfc 552 wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w);
8a0681f9
VZ
553 if ( !tool )
554 return;
1a3ac83f 555
8a0681f9
VZ
556 if ( tool->CanBeToggled() )
557 tool->Toggle();
558
559 if ( !toolBar->OnLeftClick(tool->GetId(), tool->IsToggled()) )
1a3ac83f 560 {
8a0681f9
VZ
561 // revert
562 tool->Toggle();
1a3ac83f 563 }
1a3ac83f
JS
564}
565
1a3ac83f 566
8a0681f9
VZ
567static void wxToolButtonPopupCallback(Widget w,
568 XtPointer client_data,
569 XEvent *event,
570 Boolean *WXUNUSED(continue_to_dispatch))
1a3ac83f
JS
571{
572 // TODO: retrieve delay before popping up tooltip from wxSystemSettings.
8a0681f9 573 static const int delayMilli = 800;
1a3ac83f 574
8a0681f9 575 wxToolBar* toolBar = (wxToolBar*) client_data;
982b2cfc 576 wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w);
1a3ac83f 577
8a0681f9
VZ
578 if ( !tool )
579 return;
1a3ac83f 580
8a0681f9
VZ
581 wxString tooltip = tool->GetShortHelp();
582 if ( !tooltip )
583 return;
1a3ac83f 584
8a0681f9
VZ
585 if (!wxTheToolBarTimer)
586 wxTheToolBarTimer = new wxToolBarTimer;
1a3ac83f 587
8a0681f9
VZ
588 wxToolBarTimer::buttonWidget = w;
589 wxToolBarTimer::helpString = tooltip;
1a3ac83f
JS
590
591 /************************************************************/
592 /* Popup help label */
593 /************************************************************/
594 if (event->type == EnterNotify)
595 {
596 if (wxToolBarTimer::help_popup != (Widget) 0)
597 {
598 XtDestroyWidget (wxToolBarTimer::help_popup);
599 XtPopdown (wxToolBarTimer::help_popup);
bf6c2b35 600 }
1a3ac83f
JS
601 wxToolBarTimer::help_popup = (Widget) 0;
602
603 // One shot
604 wxTheToolBarTimer->Start(delayMilli, TRUE);
605
606 }
607 /************************************************************/
608 /* Popdown help label */
609 /************************************************************/
610 else if (event->type == LeaveNotify)
611 {
612 if (wxTheToolBarTimer)
613 wxTheToolBarTimer->Stop();
614 if (wxToolBarTimer::help_popup != (Widget) 0)
615 {
616 XtDestroyWidget (wxToolBarTimer::help_popup);
617 XtPopdown (wxToolBarTimer::help_popup);
bf6c2b35 618 }
1a3ac83f
JS
619 wxToolBarTimer::help_popup = (Widget) 0;
620 }
1a3ac83f
JS
621}
622
623void wxToolBarTimer::Notify()
624{
625 Position x, y;
626
627 /************************************************************/
628 /* Create shell without window decorations */
629 /************************************************************/
bf6c2b35
VZ
630 help_popup = XtVaCreatePopupShell ("shell",
631 overrideShellWidgetClass, (Widget) wxTheApp->GetTopLevelWidget(),
1a3ac83f
JS
632 NULL);
633
634 /************************************************************/
635 /* Get absolute position on display of toolbar button */
636 /************************************************************/
637 XtTranslateCoords (buttonWidget,
bf6c2b35
VZ
638 (Position) 0,
639 (Position) 0,
1a3ac83f
JS
640 &x, &y);
641
642 // Move the tooltip more or less above the button
643 int yOffset = 20; // TODO: What should be really?
644 y -= yOffset;
645 if (y < yOffset) y = 0;
646
647 /************************************************************/
648 /* Set the position of the help popup */
649 /************************************************************/
bf6c2b35
VZ
650 XtVaSetValues (help_popup,
651 XmNx, (Position) x,
652 XmNy, (Position) y,
1a3ac83f 653 NULL);
bf6c2b35 654
1a3ac83f
JS
655 /************************************************************/
656 /* Create help label */
657 /************************************************************/
658 XmString text = XmStringCreateSimple ((char*) (const char*) helpString);
bf6c2b35
VZ
659 XtVaCreateManagedWidget ("help_label",
660 xmLabelWidgetClass, help_popup,
1a3ac83f 661 XmNlabelString, text,
bf6c2b35
VZ
662 XtVaTypedArg,
663 XmNforeground, XtRString, "black",
664 strlen("black")+1,
665 XtVaTypedArg,
666 XmNbackground, XtRString, "LightGoldenrod",
667 strlen("LightGoldenrod")+1,
1a3ac83f
JS
668 NULL);
669 XmStringFree (text);
670
671 /************************************************************/
672 /* Popup help label */
673 /************************************************************/
674 XtPopup (help_popup, XtGrabNone);
675}
676