X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0d57be459406c2830f6abc9d99ae99166c6d133b..19e30148e18cc99296b26503c155e5cef59045f4:/src/motif/toolbar.cpp?ds=inline diff --git a/src/motif/toolbar.cpp b/src/motif/toolbar.cpp index d0db4cc532..03f2e08a9e 100644 --- a/src/motif/toolbar.cpp +++ b/src/motif/toolbar.cpp @@ -1,57 +1,205 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: toolbar.cpp +// Name: motif/toolbar.cpp // Purpose: wxToolBar // Author: Julian Smart -// Modified by: +// 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 +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "toolbar.h" + #pragma implementation "toolbar.h" +#endif + +#ifdef __VMS +#define XtDisplay XTDISPLAY #endif #include "wx/wx.h" -#include "wx/motif/toolbar.h" +#include "wx/app.h" +#include "wx/timer.h" +#include "wx/toolbar.h" +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include #include #include +#include #include #include #include +#ifdef __VMS__ +#pragma message enable nosimpint +#endif #include "wx/motif/private.h" +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) - -BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) -END_EVENT_TABLE() #endif -wxToolBar::wxToolBar(): - m_widgets(wxKEY_INTEGER) +// ---------------------------------------------------------------------------- +// 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; } + + void SetPixmap(Pixmap pixmap) { m_pixmap = pixmap; } + Pixmap GetPixmap() const { return m_pixmap; } + +protected: + void Init(); + + Widget m_widget; + Pixmap m_pixmap; +}; + +// ---------------------------------------------------------------------------- +// 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) { - m_maxWidth = -1; - m_maxHeight = -1; - m_defaultWidth = 24; - m_defaultHeight = 22; - // TODO + return new wxToolBarTool(this, control); } -bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, const wxString& name) +void wxToolBarTool::Init() +{ + m_widget = (Widget)0; + m_pixmap = (Pixmap)0; +} + +wxToolBarTool::~wxToolBarTool() +{ + if ( m_widget ) + XtDestroyWidget(m_widget); + if ( m_pixmap ) + XmDestroyPixmap(DefaultScreenOfDisplay((Display*)wxGetDisplay()), + m_pixmap); +} + +// ---------------------------------------------------------------------------- +// 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) +{ + Init(); + + m_windowId = id; + SetName(name); - m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); m_foregroundColour = parent->GetForegroundColour(); m_windowStyle = style; @@ -62,260 +210,465 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons Widget parentWidget = (Widget) parent->GetClientWidget(); Widget toolbar = XtVaCreateManagedWidget("toolbar", - xmFormWidgetClass, parentWidget, + 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; + m_font = parent->GetFont(); + ChangeFont(FALSE); + SetCanAddEventHandler(TRUE); AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y); - SetFont(* parent->GetFont()); ChangeBackgroundColour(); - + return TRUE; } wxToolBar::~wxToolBar() { - // TODO + delete wxTheToolBarTimer; + wxTheToolBarTimer = NULL; } -bool wxToolBar::CreateTools() +bool wxToolBar::Realize() { - if (m_tools.Number() == 0) - return FALSE; + if ( m_tools.GetCount() == 0 ) + { + // nothing to do + return TRUE; + } + + // 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; + + int currentSpacing = 0; - m_widgets.Clear(); - Widget prevButton = (Widget) 0; - wxNode* node = m_tools.First(); - while (node) + Widget button; + Pixmap pixmap, insensPixmap; + wxBitmap bmp; + + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while ( node ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if ((tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) && tool->m_bitmap1.Ok()) - { - Widget button = (Widget) 0; + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); - if (tool->m_isToggle) + switch ( tool->GetStyle() ) + { + case wxTOOL_STYLE_CONTROL: { - button = XtVaCreateManagedWidget("toggleButton", - xmToggleButtonWidgetClass, (Widget) m_mainWidget, - XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET, - XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton, - XmNleftOffset, 0, - XmNtopAttachment, XmATTACH_FORM, - // XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - NULL); + wxControl* control = tool->GetControl(); + wxSize sz = control->GetSize(); + wxPoint pos = control->GetPosition(); + control->Move(currentX, pos.y); + currentX += sz.x + packing; + + break; } - else - { - button = XtVaCreateManagedWidget("button", - xmPushButtonWidgetClass, (Widget) m_mainWidget, - XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET, - XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton, - XmNleftOffset, 0, - XmNtopAttachment, XmATTACH_FORM, - XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - 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. - if (tool->m_bitmap1.GetMask()) - { - wxBitmap newBitmap(tool->m_bitmap1.GetWidth(), - tool->m_bitmap1.GetHeight(), - tool->m_bitmap1.GetDepth()); - int backgroundPixel; - XtVaGetValues(button, XmNbackground, &backgroundPixel, - NULL); + case wxTOOL_STYLE_SEPARATOR: + currentX += separatorSize; + break; + case wxTOOL_STYLE_BUTTON: + button = (Widget) 0; - wxColour col; - col.SetPixel(backgroundPixel); - - wxMemoryDC destDC; - wxMemoryDC srcDC; - srcDC.SelectObject(tool->m_bitmap1); - destDC.SelectObject(newBitmap); - - wxBrush brush(col, wxSOLID); - destDC.SetOptimization(FALSE); - destDC.SetBackground(brush); - destDC.Clear(); - destDC.Blit(0, 0, tool->m_bitmap1.GetWidth(), tool->m_bitmap1.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE); - - tool->m_bitmap1 = newBitmap; - } - if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask()) - { - wxBitmap newBitmap(tool->m_bitmap2.GetWidth(), - tool->m_bitmap2.GetHeight(), - tool->m_bitmap2.GetDepth()); - int backgroundPixel; - XtVaGetValues(button, XmNbackground, &backgroundPixel, - NULL); + if ( tool->CanBeToggled() ) + { + 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 + { + 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); + } + + DoChangeBackgroundColour((WXWidget) button, m_backgroundColour, TRUE); + + tool->SetWidget(button); + + // 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(); + if ( bmp.GetMask() ) + { + int backgroundPixel; + XtVaGetValues(button, XmNbackground, &backgroundPixel, + NULL); + wxColour col; + col.SetPixel(backgroundPixel); + + bmp = wxCreateMaskedBitmap(bmp, col); + + tool->SetNormalBitmap(bmp); + } + + // 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); - - wxMemoryDC destDC; - wxMemoryDC srcDC; - srcDC.SelectObject(tool->m_bitmap2); - destDC.SelectObject(newBitmap); - - wxBrush brush(col, wxSOLID); - destDC.SetOptimization(FALSE); - destDC.SetBackground(brush); - destDC.Clear(); - destDC.Blit(0, 0, tool->m_bitmap2.GetWidth(), tool->m_bitmap2.GetHeight(), & srcDC, 0, 0, wxCOPY, TRUE); - - tool->m_bitmap2 = newBitmap; - } - Pixmap pixmap = (Pixmap) tool->m_bitmap1.GetPixmap(); - Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap(); - if (tool->m_isToggle) - { - Pixmap pixmap2 = (Pixmap) 0; - Pixmap insensPixmap2 = (Pixmap) 0; + // FIXME: we use disabled bitmap as the bitmap for the toggled + // state, we probably need a GetToggledBitmap() instead + wxBitmap bmpToggled = tool->GetDisabledBitmap(); + if ( bmpToggled.Ok() && bmpToggled.GetMask()) + { + // Use what's there + wxBitmap newBitmap = wxCreateMaskedBitmap(bmpToggled, col); + tool->SetDisabledBitmap(newBitmap); + } + else + { + // Use unselected bitmap + if ( bmp.GetMask() ) + { + wxBitmap newBitmap = wxCreateMaskedBitmap(bmp, col); + tool->SetDisabledBitmap(newBitmap); + } + else + tool->SetDisabledBitmap(bmp); + } - // If there's a bitmap for the toggled state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) + // FIXME: and here we should use GetDisabledBitmap()... + pixmap = (Pixmap) bmp.GetPixmap(); + insensPixmap = (Pixmap) bmp.GetInsensPixmap(); + + if (tool->CanBeToggled()) { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); - insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap(); + // Toggle button + Pixmap pixmap2 = (Pixmap) 0; + Pixmap insensPixmap2 = (Pixmap) 0; + + // If there's a bitmap for the toggled state, use it, + // otherwise generate one. + // + // FIXME: see above + if ( bmpToggled.Ok() ) + { + pixmap2 = (Pixmap) bmpToggled.GetPixmap(); + insensPixmap2 = (Pixmap) bmpToggled.GetInsensPixmap(); + } + else + { + pixmap2 = (Pixmap) bmp.GetArmPixmap(button); + insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); + } + + tool->SetPixmap(pixmap2); + + XtVaSetValues (button, + XmNfillOnSelect, True, + XmNlabelPixmap, pixmap, + XmNselectPixmap, pixmap2, + XmNlabelInsensitivePixmap, insensPixmap, + XmNselectInsensitivePixmap, insensPixmap2, + XmNlabelType, XmPIXMAP, + NULL); } else { - pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); - // This has to be both toggled and insensitive, but - // wxBitmap doesn't yet have a member to store & destroy - // it, so make it the same as pixmap2. Actually it's not - // used! - insensPixmap2 = pixmap2; + Pixmap pixmap2 = (Pixmap) 0; + + // If there's a bitmap for the armed state, use it, + // otherwise generate one. + if ( bmpToggled.Ok() ) + { + pixmap2 = (Pixmap) bmpToggled.GetPixmap(); + } + else + { + pixmap2 = (Pixmap) bmp.GetArmPixmap(button); + + } + + tool->SetPixmap(pixmap2); + + // Normal button + XtVaSetValues(button, + XmNlabelPixmap, pixmap, + XmNlabelInsensitivePixmap, insensPixmap, + XmNarmPixmap, pixmap2, + NULL); } - XtVaSetValues (button, - XmNlabelPixmap, pixmap, - XmNselectPixmap, pixmap, - XmNlabelInsensitivePixmap, insensPixmap, - XmNselectInsensitivePixmap, insensPixmap, - XmNarmPixmap, pixmap2, - XmNlabelType, XmPIXMAP, - NULL); - - } - else - { - XtVaSetValues(button, - XmNlabelPixmap, pixmap, - XmNlabelInsensitivePixmap, insensPixmap, - NULL); - } - m_widgets.Append(tool->m_index, (wxObject*) button); + XtManageChild(button); - prevButton = button; - + { + Dimension width, height; + XtVaGetValues(button, + XmNwidth, &width, + XmNheight, & height, + NULL); + currentX += width + packing; + buttonHeight = wxMax(buttonHeight, height); + } + + XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, + False, wxToolButtonPopupCallback, (XtPointer) this); + + currentSpacing = 0; + break; } - node = node->Next(); + + node = node->GetNext(); } + SetSize(-1, -1, currentX, buttonHeight + 2*marginY); + return TRUE; } -void wxToolBar::SetToolBitmapSize(const wxSize& size) +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y)) const { - m_defaultWidth = size.x; m_defaultHeight = size.y; - // TODO + wxFAIL_MSG( _T("TODO") ); + + return (wxToolBarToolBase *)NULL; } -wxSize wxToolBar::GetMaxSize() const +bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) { - // TODO - return wxSize(0, 0); + tool->Attach(this); + + return TRUE; } -// The button size is bigger than the bitmap size -wxSize wxToolBar::GetToolSize() const +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) { - // TODO - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); + tool->Detach(); + + return TRUE; } -void wxToolBar::EnableTool(int toolIndex, bool enable) +void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_enabled = enable; - // TODO enable button - } + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + + XtSetSensitive(tool->GetButtonWidget(), (Boolean) enable); +} + +void wxToolBar::DoToggleTool(wxToolBarToolBase *toolBase, bool toggle) +{ + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + + XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False); } -void wxToolBar::ToggleTool(int toolIndex, bool toggle) +void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) + // nothing to do +} + +// ---------------------------------------------------------------------------- +// Motif callbacks +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const +{ + wxToolBarToolsList::Node* node = m_tools.GetFirst(); + while ( node ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + if ( tool->GetButtonWidget() == w) { - tool->m_toggleState = toggle; - // TODO: set toggle state + return tool; } + + node = node->GetNext(); } + + return (wxToolBarToolBase *)NULL; } -void wxToolBar::ClearTools() +static void wxToolButtonCallback(Widget w, + XtPointer clientData, + XtPointer WXUNUSED(ptr)) { - wxNode* node = m_widgets.First(); - while (node) + 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()) ) { - Widget button = (Widget) node->Data(); - XtDestroyWidget(button); - node = node->Next(); + // revert + tool->Toggle(); } - m_widgets.Clear(); - - wxToolBarBase::ClearTools(); } -// If pushedBitmap is NULL, a reversed version of bitmap is -// created and used as the pushed/toggled image. -// If toggle is TRUE, the button toggles between the two states. -wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap, - bool toggle, long xPos, long yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2) +static void wxToolButtonPopupCallback(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *WXUNUSED(continue_to_dispatch)) { - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, (wxBitmap *)NULL, toggle, xPos, yPos, helpString1, helpString2); - tool->m_clientData = clientData; + // 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 (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; + 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; - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; + // One shot + wxTheToolBarTimer->Start(delayMilli, TRUE); - tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight()); + } + /************************************************************/ + /* 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; + } +} - m_tools.Append((long)index, tool); - return tool; +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 -= 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); }