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