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