git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39045 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
793 lines
26 KiB
C++
793 lines
26 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/motif/toolbar.cpp
|
|
// Purpose: wxToolBar
|
|
// Author: Julian Smart
|
|
// Modified by: 13.12.99 by VZ during toolbar classes reorganization
|
|
// Created: 04/01/98
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __VMS
|
|
#define XtDisplay XTDISPLAY
|
|
#endif
|
|
|
|
#include "wx/toolbar.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/app.h"
|
|
#include "wx/frame.h"
|
|
#endif
|
|
|
|
#include "wx/settings.h"
|
|
#include "wx/timer.h"
|
|
|
|
#ifdef __VMS__
|
|
#pragma message disable nosimpint
|
|
#endif
|
|
#include <Xm/Xm.h>
|
|
#include <Xm/PushBG.h>
|
|
#include <Xm/PushB.h>
|
|
#include <Xm/Label.h>
|
|
#include <Xm/ToggleB.h>
|
|
#include <Xm/ToggleBG.h>
|
|
#include <Xm/Form.h>
|
|
#ifdef __VMS__
|
|
#pragma message enable nosimpint
|
|
#endif
|
|
|
|
#include "wx/motif/private.h"
|
|
#include "wx/motif/bmpmotif.h"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxWin macros
|
|
// ----------------------------------------------------------------------------
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// private functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
static void wxToolButtonCallback (Widget w, XtPointer clientData,
|
|
XtPointer ptr);
|
|
static void wxToolButtonPopupCallback (Widget w, XtPointer client_data,
|
|
XEvent *event, Boolean *continue_to_dispatch);
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// private classes
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class wxToolBarTimer : public wxTimer
|
|
{
|
|
public:
|
|
virtual void Notify();
|
|
|
|
static Widget help_popup;
|
|
static Widget buttonWidget;
|
|
static wxString helpString;
|
|
};
|
|
|
|
class wxToolBarTool : public wxToolBarToolBase
|
|
{
|
|
public:
|
|
wxToolBarTool(wxToolBar *tbar,
|
|
int id,
|
|
const wxString& label,
|
|
const wxBitmap& bmpNormal,
|
|
const wxBitmap& bmpToggled,
|
|
wxItemKind kind,
|
|
wxObject *clientData,
|
|
const wxString& shortHelp,
|
|
const wxString& longHelp)
|
|
: wxToolBarToolBase(tbar, id, label, bmpNormal, bmpToggled, kind,
|
|
clientData, shortHelp, longHelp)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
wxToolBarTool(wxToolBar *tbar, wxControl *control)
|
|
: wxToolBarToolBase(tbar, control)
|
|
{
|
|
Init();
|
|
}
|
|
|
|
virtual ~wxToolBarTool();
|
|
|
|
// accessors
|
|
void SetWidget(Widget widget) { m_widget = widget; }
|
|
Widget GetButtonWidget() const { return m_widget; }
|
|
|
|
Pixmap GetArmPixmap()
|
|
{
|
|
m_bitmapCache.SetBitmap( GetNormalBitmap() );
|
|
return (Pixmap)m_bitmapCache.GetArmPixmap( (WXWidget)m_widget );
|
|
}
|
|
|
|
Pixmap GetInsensPixmap()
|
|
{
|
|
m_bitmapCache.SetBitmap( GetNormalBitmap() );
|
|
return (Pixmap)m_bitmapCache.GetInsensPixmap( (WXWidget)m_widget );
|
|
}
|
|
protected:
|
|
void Init();
|
|
|
|
Widget m_widget;
|
|
wxBitmapCache m_bitmapCache;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// globals
|
|
// ----------------------------------------------------------------------------
|
|
|
|
static wxToolBarTimer* wxTheToolBarTimer = (wxToolBarTimer*) NULL;
|
|
|
|
Widget wxToolBarTimer::help_popup = (Widget) 0;
|
|
Widget wxToolBarTimer::buttonWidget = (Widget) 0;
|
|
wxString wxToolBarTimer::helpString;
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxToolBarTool
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxToolBarToolBase *wxToolBar::CreateTool(int id,
|
|
const wxString& label,
|
|
const wxBitmap& bmpNormal,
|
|
const wxBitmap& bmpToggled,
|
|
wxItemKind kind,
|
|
wxObject *clientData,
|
|
const wxString& shortHelp,
|
|
const wxString& longHelp)
|
|
{
|
|
return new wxToolBarTool(this, id, label, bmpNormal, bmpToggled, kind,
|
|
clientData, shortHelp, longHelp);
|
|
}
|
|
|
|
|
|
wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
|
|
{
|
|
return new wxToolBarTool(this, control);
|
|
}
|
|
|
|
void wxToolBarTool::Init()
|
|
{
|
|
m_widget = (Widget)0;
|
|
}
|
|
|
|
wxToolBarTool::~wxToolBarTool()
|
|
{
|
|
if ( m_widget )
|
|
XtDestroyWidget(m_widget);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxToolBar construction
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxToolBar::Init()
|
|
{
|
|
m_maxWidth = -1;
|
|
m_maxHeight = -1;
|
|
m_defaultWidth = 24;
|
|
m_defaultHeight = 22;
|
|
m_toolPacking = 2;
|
|
m_toolSeparation = 8;
|
|
m_xMargin = 2;
|
|
m_yMargin = 2;
|
|
m_maxRows = 100;
|
|
m_maxCols = 100;
|
|
}
|
|
|
|
bool wxToolBar::Create(wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxString& name)
|
|
{
|
|
if( !wxControl::CreateControl( parent, id, pos, size, style,
|
|
wxDefaultValidator, name ) )
|
|
return false;
|
|
|
|
m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
|
|
|
|
Widget parentWidget = (Widget) parent->GetClientWidget();
|
|
|
|
Widget toolbar = XtVaCreateManagedWidget("toolbar",
|
|
xmBulletinBoardWidgetClass, (Widget) parentWidget,
|
|
XmNmarginWidth, 0,
|
|
XmNmarginHeight, 0,
|
|
XmNresizePolicy, XmRESIZE_NONE,
|
|
NULL);
|
|
/*
|
|
Widget toolbar = XtVaCreateManagedWidget("toolbar",
|
|
xmFormWidgetClass, (Widget) m_clientWidget,
|
|
XmNtraversalOn, False,
|
|
XmNhorizontalSpacing, 0,
|
|
XmNverticalSpacing, 0,
|
|
XmNleftOffset, 0,
|
|
XmNrightOffset, 0,
|
|
XmNmarginWidth, 0,
|
|
XmNmarginHeight, 0,
|
|
NULL);
|
|
*/
|
|
|
|
m_mainWidget = (WXWidget) toolbar;
|
|
|
|
ChangeFont(false);
|
|
|
|
wxPoint rPos = pos;
|
|
wxSize rSize = size;
|
|
|
|
if( rPos.x == -1 ) rPos.x = 0;
|
|
if( rPos.y == -1 ) rPos.y = 0;
|
|
if( rSize.x == -1 && GetParent() )
|
|
rSize.x = GetParent()->GetSize().x;
|
|
|
|
AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
|
|
rPos.x, rPos.y, rSize.x, rSize.y);
|
|
|
|
ChangeBackgroundColour();
|
|
|
|
return true;
|
|
}
|
|
|
|
wxToolBar::~wxToolBar()
|
|
{
|
|
delete wxTheToolBarTimer;
|
|
wxTheToolBarTimer = NULL;
|
|
}
|
|
|
|
bool wxToolBar::Realize()
|
|
{
|
|
if ( m_tools.GetCount() == 0 )
|
|
{
|
|
// nothing to do
|
|
return true;
|
|
}
|
|
|
|
bool isVertical = GetWindowStyle() & wxTB_VERTICAL;
|
|
|
|
// Separator spacing
|
|
const int separatorSize = GetToolSeparation(); // 8;
|
|
wxSize margins = GetToolMargins();
|
|
int packing = GetToolPacking();
|
|
int marginX = margins.x;
|
|
int marginY = margins.y;
|
|
|
|
int currentX = marginX;
|
|
int currentY = marginY;
|
|
|
|
int buttonHeight = 0, buttonWidth = 0;
|
|
|
|
Widget button;
|
|
Pixmap pixmap, insensPixmap;
|
|
wxBitmap bmp, insensBmp;
|
|
|
|
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
|
|
|
|
switch ( tool->GetStyle() )
|
|
{
|
|
case wxTOOL_STYLE_CONTROL:
|
|
{
|
|
wxControl* control = tool->GetControl();
|
|
wxSize sz = control->GetSize();
|
|
wxPoint pos = control->GetPosition();
|
|
// Allow a control to specify a y[x]-offset by setting
|
|
// its initial position, but still don't allow it to
|
|
// position itself above the top[left] margin.
|
|
int controlY = (pos.y > 0) ? pos.y : currentY;
|
|
int controlX = (pos.x > 0) ? pos.x : currentX;
|
|
control->Move( isVertical ? controlX : currentX,
|
|
isVertical ? currentY : controlY );
|
|
if ( isVertical )
|
|
currentY += sz.y + packing;
|
|
else
|
|
currentX += sz.x + packing;
|
|
|
|
break;
|
|
}
|
|
case wxTOOL_STYLE_SEPARATOR:
|
|
// skip separators for vertical toolbars
|
|
if( !isVertical )
|
|
{
|
|
currentX += separatorSize;
|
|
}
|
|
break;
|
|
|
|
case wxTOOL_STYLE_BUTTON:
|
|
button = (Widget) 0;
|
|
|
|
if ( tool->CanBeToggled() && !tool->GetButtonWidget() )
|
|
{
|
|
button = XtVaCreateWidget("toggleButton",
|
|
xmToggleButtonWidgetClass, (Widget) m_mainWidget,
|
|
XmNx, currentX, XmNy, currentY,
|
|
XmNindicatorOn, False,
|
|
XmNshadowThickness, 2,
|
|
XmNborderWidth, 0,
|
|
XmNspacing, 0,
|
|
XmNmarginWidth, 0,
|
|
XmNmarginHeight, 0,
|
|
XmNmultiClick, XmMULTICLICK_KEEP,
|
|
XmNlabelType, XmPIXMAP,
|
|
NULL);
|
|
XtAddCallback ((Widget) button,
|
|
XmNvalueChangedCallback,
|
|
(XtCallbackProc) wxToolButtonCallback,
|
|
(XtPointer) this);
|
|
|
|
XtVaSetValues ((Widget) button,
|
|
XmNselectColor,
|
|
m_backgroundColour.AllocColour
|
|
(XtDisplay((Widget) button)),
|
|
NULL);
|
|
}
|
|
else if( !tool->GetButtonWidget() )
|
|
{
|
|
button = XtVaCreateWidget("button",
|
|
xmPushButtonWidgetClass, (Widget) m_mainWidget,
|
|
XmNx, currentX, XmNy, currentY,
|
|
XmNpushButtonEnabled, True,
|
|
XmNmultiClick, XmMULTICLICK_KEEP,
|
|
XmNlabelType, XmPIXMAP,
|
|
NULL);
|
|
XtAddCallback (button,
|
|
XmNactivateCallback,
|
|
(XtCallbackProc) wxToolButtonCallback,
|
|
(XtPointer) this);
|
|
}
|
|
|
|
if( !tool->GetButtonWidget() )
|
|
{
|
|
wxDoChangeBackgroundColour((WXWidget) button,
|
|
m_backgroundColour, true);
|
|
|
|
tool->SetWidget(button);
|
|
}
|
|
else
|
|
{
|
|
button = (Widget)tool->GetButtonWidget();
|
|
XtVaSetValues( button,
|
|
XmNx, currentX, XmNy, currentY,
|
|
NULL );
|
|
}
|
|
|
|
// For each button, if there is a mask, we must create
|
|
// a new wxBitmap that has the correct background colour
|
|
// for the button. Otherwise the background will just be
|
|
// e.g. black if a transparent XPM has been loaded.
|
|
bmp = tool->GetNormalBitmap();
|
|
insensBmp = tool->GetDisabledBitmap();
|
|
if ( bmp.GetMask() || insensBmp.GetMask() )
|
|
{
|
|
int backgroundPixel;
|
|
XtVaGetValues(button, XmNbackground, &backgroundPixel,
|
|
NULL);
|
|
|
|
wxColour col;
|
|
col.SetPixel(backgroundPixel);
|
|
|
|
if( bmp.Ok() && bmp.GetMask() )
|
|
{
|
|
bmp = wxCreateMaskedBitmap(bmp, col);
|
|
tool->SetNormalBitmap(bmp);
|
|
}
|
|
|
|
if( insensBmp.Ok() && insensBmp.GetMask() )
|
|
{
|
|
insensBmp = wxCreateMaskedBitmap(insensBmp, col);
|
|
tool->SetDisabledBitmap(insensBmp);
|
|
}
|
|
}
|
|
|
|
// Create a selected/toggled bitmap. If there isn't a 2nd
|
|
// bitmap, we need to create it (with a darker, selected
|
|
// background)
|
|
int backgroundPixel;
|
|
if ( tool->CanBeToggled() )
|
|
XtVaGetValues(button, XmNselectColor, &backgroundPixel,
|
|
NULL);
|
|
else
|
|
XtVaGetValues(button, XmNarmColor, &backgroundPixel,
|
|
NULL);
|
|
wxColour col;
|
|
col.SetPixel(backgroundPixel);
|
|
|
|
pixmap = (Pixmap) bmp.GetDrawable();
|
|
{
|
|
wxBitmap tmp = tool->GetDisabledBitmap();
|
|
|
|
insensPixmap = tmp.Ok() ?
|
|
(Pixmap)tmp.GetDrawable() :
|
|
tool->GetInsensPixmap();
|
|
}
|
|
|
|
if (tool->CanBeToggled())
|
|
{
|
|
// Toggle button
|
|
Pixmap pixmap2 = tool->GetArmPixmap();
|
|
Pixmap insensPixmap2 = tool->GetInsensPixmap();
|
|
|
|
XtVaSetValues (button,
|
|
XmNfillOnSelect, True,
|
|
XmNlabelPixmap, pixmap,
|
|
XmNselectPixmap, pixmap2,
|
|
XmNlabelInsensitivePixmap, insensPixmap,
|
|
XmNselectInsensitivePixmap, insensPixmap2,
|
|
XmNlabelType, XmPIXMAP,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
Pixmap pixmap2 = tool->GetArmPixmap();
|
|
|
|
// Normal button
|
|
XtVaSetValues(button,
|
|
XmNlabelPixmap, pixmap,
|
|
XmNlabelInsensitivePixmap, insensPixmap,
|
|
XmNarmPixmap, pixmap2,
|
|
NULL);
|
|
}
|
|
|
|
XtManageChild(button);
|
|
|
|
{
|
|
Dimension width, height;
|
|
XtVaGetValues(button,
|
|
XmNwidth, &width,
|
|
XmNheight, & height,
|
|
NULL);
|
|
if ( isVertical )
|
|
currentY += height + packing;
|
|
else
|
|
currentX += width + packing;
|
|
buttonHeight = wxMax(buttonHeight, height);
|
|
buttonWidth = wxMax(buttonWidth, width);
|
|
}
|
|
|
|
XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask,
|
|
False, wxToolButtonPopupCallback, (XtPointer) this);
|
|
|
|
break;
|
|
}
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
SetSize( -1, -1,
|
|
isVertical ? buttonWidth + 2 * marginX : -1,
|
|
isVertical ? -1 : buttonHeight + 2*marginY );
|
|
|
|
return true;
|
|
}
|
|
|
|
wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x),
|
|
wxCoord WXUNUSED(y)) const
|
|
{
|
|
wxFAIL_MSG( _T("TODO") );
|
|
|
|
return (wxToolBarToolBase *)NULL;
|
|
}
|
|
|
|
bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
|
|
{
|
|
tool->Attach(this);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
|
|
{
|
|
tool->Detach();
|
|
|
|
bool isVertical = GetWindowStyle() & wxTB_VERTICAL;
|
|
const int separatorSize = GetToolSeparation(); // 8;
|
|
int packing = GetToolPacking();
|
|
int offset = 0;
|
|
|
|
for( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
node; node = node->GetNext() )
|
|
{
|
|
wxToolBarTool *t = (wxToolBarTool*)node->GetData();
|
|
|
|
if( t == tool )
|
|
{
|
|
switch ( t->GetStyle() )
|
|
{
|
|
case wxTOOL_STYLE_CONTROL:
|
|
{
|
|
wxSize size = t->GetControl()->GetSize();
|
|
offset = isVertical ? size.y : size.x;
|
|
offset += packing;
|
|
break;
|
|
}
|
|
case wxTOOL_STYLE_SEPARATOR:
|
|
offset = isVertical ? 0 : separatorSize;
|
|
break;
|
|
case wxTOOL_STYLE_BUTTON:
|
|
{
|
|
Widget w = t->GetButtonWidget();
|
|
Dimension width, height;
|
|
|
|
XtVaGetValues( w,
|
|
XmNwidth, &width,
|
|
XmNheight, &height,
|
|
NULL );
|
|
|
|
offset = isVertical ? height : width;
|
|
offset += packing;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if( offset )
|
|
{
|
|
switch ( t->GetStyle() )
|
|
{
|
|
case wxTOOL_STYLE_CONTROL:
|
|
{
|
|
wxPoint location = t->GetControl()->GetPosition();
|
|
|
|
if( isVertical )
|
|
location.y -= offset;
|
|
else
|
|
location.x -= offset;
|
|
|
|
t->GetControl()->Move( location );
|
|
break;
|
|
}
|
|
case wxTOOL_STYLE_SEPARATOR:
|
|
break;
|
|
case wxTOOL_STYLE_BUTTON:
|
|
{
|
|
Dimension x, y;
|
|
XtVaGetValues( t->GetButtonWidget(),
|
|
XmNx, &x,
|
|
XmNy, &y,
|
|
NULL );
|
|
|
|
if( isVertical )
|
|
y = (Dimension)(y - offset);
|
|
else
|
|
x = (Dimension)(x - offset);
|
|
|
|
XtVaSetValues( t->GetButtonWidget(),
|
|
XmNx, x,
|
|
XmNy, y,
|
|
NULL );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
|
|
{
|
|
wxToolBarTool *tool = (wxToolBarTool *)toolBase;
|
|
if (tool->GetButtonWidget()){
|
|
XtSetSensitive(tool->GetButtonWidget(), (Boolean) enable);
|
|
} else if (wxTOOL_STYLE_CONTROL == tool->GetStyle()){
|
|
// Controls (such as wxChoice) do not have button widgets
|
|
tool->GetControl()->Enable(enable);
|
|
}
|
|
}
|
|
|
|
void wxToolBar::DoToggleTool(wxToolBarToolBase *toolBase, bool toggle)
|
|
{
|
|
wxToolBarTool *tool = (wxToolBarTool *)toolBase;
|
|
|
|
XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False);
|
|
}
|
|
|
|
void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
|
|
bool WXUNUSED(toggle))
|
|
{
|
|
// nothing to do
|
|
}
|
|
|
|
void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
|
|
{
|
|
int old_width, old_height;
|
|
GetSize(&old_width, &old_height);
|
|
|
|
// Correct width and height if needed.
|
|
if ( width == -1 || height == -1 )
|
|
{
|
|
wxSize defaultSize = GetSize();
|
|
|
|
if ( width == -1 )
|
|
width = defaultSize.x;
|
|
if ( height == -1 )
|
|
height = defaultSize.y;
|
|
}
|
|
|
|
wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
|
|
|
|
// We must refresh the frame size when the toolbar changes size
|
|
// otherwise the toolbar can be shown incorrectly
|
|
if ( old_width != width || old_height != height )
|
|
{
|
|
// But before we send the size event check it
|
|
// we have a frame that is not being deleted.
|
|
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
|
|
if ( frame && !frame->IsBeingDeleted() )
|
|
{
|
|
frame->SendSizeEvent();
|
|
}
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Motif callbacks
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const
|
|
{
|
|
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
|
|
if ( tool->GetButtonWidget() == w)
|
|
{
|
|
return tool;
|
|
}
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
return (wxToolBarToolBase *)NULL;
|
|
}
|
|
|
|
static void wxToolButtonCallback(Widget w,
|
|
XtPointer clientData,
|
|
XtPointer WXUNUSED(ptr))
|
|
{
|
|
wxToolBar *toolBar = (wxToolBar *) clientData;
|
|
wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w);
|
|
if ( !tool )
|
|
return;
|
|
|
|
if ( tool->CanBeToggled() )
|
|
tool->Toggle();
|
|
|
|
if ( !toolBar->OnLeftClick(tool->GetId(), tool->IsToggled()) )
|
|
{
|
|
// revert
|
|
tool->Toggle();
|
|
}
|
|
}
|
|
|
|
|
|
static void wxToolButtonPopupCallback(Widget w,
|
|
XtPointer client_data,
|
|
XEvent *event,
|
|
Boolean *WXUNUSED(continue_to_dispatch))
|
|
{
|
|
// TODO: retrieve delay before popping up tooltip from wxSystemSettings.
|
|
static const int delayMilli = 800;
|
|
|
|
wxToolBar* toolBar = (wxToolBar*) client_data;
|
|
wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w);
|
|
|
|
if ( !tool )
|
|
return;
|
|
|
|
wxString tooltip = tool->GetShortHelp();
|
|
if ( !tooltip )
|
|
return;
|
|
|
|
if (!wxTheToolBarTimer)
|
|
wxTheToolBarTimer = new wxToolBarTimer;
|
|
|
|
wxToolBarTimer::buttonWidget = w;
|
|
wxToolBarTimer::helpString = tooltip;
|
|
|
|
/************************************************************/
|
|
/* Popup help label */
|
|
/************************************************************/
|
|
if (event->type == EnterNotify)
|
|
{
|
|
if (wxToolBarTimer::help_popup != (Widget) 0)
|
|
{
|
|
XtDestroyWidget (wxToolBarTimer::help_popup);
|
|
XtPopdown (wxToolBarTimer::help_popup);
|
|
}
|
|
wxToolBarTimer::help_popup = (Widget) 0;
|
|
|
|
// One shot
|
|
wxTheToolBarTimer->Start(delayMilli, true);
|
|
|
|
}
|
|
/************************************************************/
|
|
/* Popdown help label */
|
|
/************************************************************/
|
|
else if (event->type == LeaveNotify)
|
|
{
|
|
if (wxTheToolBarTimer)
|
|
wxTheToolBarTimer->Stop();
|
|
if (wxToolBarTimer::help_popup != (Widget) 0)
|
|
{
|
|
XtDestroyWidget (wxToolBarTimer::help_popup);
|
|
XtPopdown (wxToolBarTimer::help_popup);
|
|
}
|
|
wxToolBarTimer::help_popup = (Widget) 0;
|
|
}
|
|
}
|
|
|
|
void wxToolBarTimer::Notify()
|
|
{
|
|
Position x, y;
|
|
|
|
/************************************************************/
|
|
/* Create shell without window decorations */
|
|
/************************************************************/
|
|
help_popup = XtVaCreatePopupShell ("shell",
|
|
overrideShellWidgetClass, (Widget) wxTheApp->GetTopLevelWidget(),
|
|
NULL);
|
|
|
|
/************************************************************/
|
|
/* Get absolute position on display of toolbar button */
|
|
/************************************************************/
|
|
XtTranslateCoords (buttonWidget,
|
|
(Position) 0,
|
|
(Position) 0,
|
|
&x, &y);
|
|
|
|
// Move the tooltip more or less above the button
|
|
int yOffset = 20; // TODO: What should be really?
|
|
y = (Position)(y - yOffset);
|
|
if (y < yOffset) y = 0;
|
|
|
|
/************************************************************/
|
|
/* Set the position of the help popup */
|
|
/************************************************************/
|
|
XtVaSetValues (help_popup,
|
|
XmNx, (Position) x,
|
|
XmNy, (Position) y,
|
|
NULL);
|
|
|
|
/************************************************************/
|
|
/* Create help label */
|
|
/************************************************************/
|
|
XmString text = XmStringCreateSimple ((char*) (const char*) helpString);
|
|
XtVaCreateManagedWidget ("help_label",
|
|
xmLabelWidgetClass, help_popup,
|
|
XmNlabelString, text,
|
|
XtVaTypedArg,
|
|
XmNforeground, XtRString, "black",
|
|
strlen("black")+1,
|
|
XtVaTypedArg,
|
|
XmNbackground, XtRString, "LightGoldenrod",
|
|
strlen("LightGoldenrod")+1,
|
|
NULL);
|
|
XmStringFree (text);
|
|
|
|
/************************************************************/
|
|
/* Popup help label */
|
|
/************************************************************/
|
|
XtPopup (help_popup, XtGrabNone);
|
|
}
|