/////////////////////////////////////////////////////////////////////////////
-// Name: toolbar.cpp
+// Name: src/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
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "toolbar.h"
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __VMS
+#define XtDisplay XTDISPLAY
#endif
-#include "wx/wx.h"
-#include "wx/motif/toolbar.h"
+#include "wx/settings.h"
+#include "wx/app.h"
+#include "wx/timer.h"
+#include "wx/toolbar.h"
+#include "wx/frame.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"
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
-BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
-END_EVENT_TABLE()
-#endif
+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();
-wxToolBar::wxToolBar():
- m_widgets(wxKEY_INTEGER)
+ // 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)
{
- 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;
+}
+
+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;
- SetName(name);
- m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
- m_foregroundColour = parent->GetForegroundColour();
- m_windowStyle = style;
+ m_toolPacking = 2;
+ m_toolSeparation = 8;
+ m_xMargin = 2;
+ m_yMargin = 2;
+ m_maxRows = 100;
+ m_maxCols = 100;
+}
- SetParent(parent);
+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;
- if (parent) parent->AddChild(this);
+ m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
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;
- SetCanAddEventHandler(TRUE);
- AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y);
+ 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);
- SetFont(* parent->GetFont());
ChangeBackgroundColour();
-
- return TRUE;
+
+ 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;
+ }
+
+ 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;
- m_widgets.Clear();
- Widget prevButton = (Widget) 0;
- wxNode* node = m_tools.First();
- while (node)
+ Widget button;
+ Pixmap pixmap, insensPixmap;
+ wxBitmap bmp, insensBmp;
+
+ wxToolBarToolsList::compatibility_iterator 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();
+ // 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;
}
- 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:
+ // skip separators for vertical toolbars
+ if( !isVertical )
+ {
+ 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() && !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);
-
- 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;
+ pixmap = (Pixmap) bmp.GetDrawable();
+ {
+ wxBitmap tmp = tool->GetDisabledBitmap();
+
+ insensPixmap = tmp.Ok() ?
+ (Pixmap)tmp.GetDrawable() :
+ tool->GetInsensPixmap();
+ }
- // If there's a bitmap for the toggled state, use it,
- // otherwise generate one.
- if (tool->m_bitmap2.Ok())
+ if (tool->CanBeToggled())
{
- pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap();
- insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap();
+ // 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
{
- 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 = tool->GetArmPixmap();
+
+ // 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
+
+ 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:
{
- XtVaSetValues(button,
- XmNlabelPixmap, pixmap,
- XmNlabelInsensitivePixmap, insensPixmap,
- NULL);
+ 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();
- m_widgets.Append(tool->m_index, (wxObject*) button);
+ 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);
- prevButton = button;
-
+ XtVaSetValues( t->GetButtonWidget(),
+ XmNx, x,
+ XmNy, y,
+ NULL );
+ break;
+ }
+ }
}
- node = node->Next();
}
- return TRUE;
+ return true;
}
-void wxToolBar::SetToolBitmapSize(const wxSize& size)
+void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable)
{
- m_defaultWidth = size.x; m_defaultHeight = size.y;
- // TODO
+ 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);
+ }
}
-wxSize wxToolBar::GetMaxSize() const
+void wxToolBar::DoToggleTool(wxToolBarToolBase *toolBase, bool toggle)
{
- // TODO
- return wxSize(0, 0);
+ wxToolBarTool *tool = (wxToolBarTool *)toolBase;
+
+ XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False);
}
-// The button size is bigger than the bitmap size
-wxSize wxToolBar::GetToolSize() const
+void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool),
+ bool WXUNUSED(toggle))
{
- // TODO
- return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
+ // nothing to do
}
-void wxToolBar::EnableTool(int toolIndex, bool enable)
+void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
- wxNode *node = m_tools.Find((long)toolIndex);
- if (node)
+ 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 )
{
- wxToolBarTool *tool = (wxToolBarTool *)node->Data();
- tool->m_enabled = enable;
- // TODO enable button
+ // 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();
+ }
}
}
-void wxToolBar::ToggleTool(int toolIndex, bool toggle)
+// ----------------------------------------------------------------------------
+// Motif callbacks
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const
{
- wxNode *node = m_tools.Find((long)toolIndex);
- if (node)
+ wxToolBarToolsList::compatibility_iterator 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 (!wxTheToolBarTimer)
+ wxTheToolBarTimer = new wxToolBarTimer;
+
+ wxToolBarTimer::buttonWidget = w;
+ wxToolBarTimer::helpString = tooltip;
- if (xPos > -1)
- tool->m_x = xPos;
- else
- tool->m_x = m_xMargin;
+ /************************************************************/
+ /* 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 = (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);
}