X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8a0681f9338345d0ef32b2ad809d49fd20861119..b5ec0c78b521cfa0f276e4d5d830f35b4fa26e91:/src/motif/toolbar.cpp diff --git a/src/motif/toolbar.cpp b/src/motif/toolbar.cpp index 56c79abbcc..c8ae30e002 100644 --- a/src/motif/toolbar.cpp +++ b/src/motif/toolbar.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: motif/toolbar.cpp +// Name: src/motif/toolbar.cpp // Purpose: wxToolBar // Author: Julian Smart // Modified by: 13.12.99 by VZ during toolbar classes reorganization @@ -17,15 +17,18 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "toolbar.h" -#endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" -#include "wx/wx.h" -#include "wx/app.h" -#include "wx/timer.h" #include "wx/toolbar.h" +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/frame.h" + #include "wx/timer.h" + #include "wx/settings.h" +#endif + #ifdef __VMS__ #pragma message disable nosimpint #endif @@ -41,14 +44,13 @@ #endif #include "wx/motif/private.h" +#include "wx/motif/bmpmotif.h" // ---------------------------------------------------------------------------- // wxWin macros // ---------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) -#endif // ---------------------------------------------------------------------------- // private functions @@ -78,20 +80,21 @@ class wxToolBarTool : public wxToolBarToolBase public: wxToolBarTool(wxToolBar *tbar, int id, - const wxBitmap& bitmap1, - const wxBitmap& bitmap2, - bool toggle, + const wxString& label, + const wxBitmap& bmpNormal, + const wxBitmap& bmpToggled, + wxItemKind kind, wxObject *clientData, - const wxString& shortHelpString, - const wxString& longHelpString) - : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, - clientData, shortHelpString, longHelpString) + 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) + wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label) + : wxToolBarToolBase(tbar, control, label) { Init(); } @@ -102,21 +105,29 @@ public: 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; } + 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; - Pixmap m_pixmap; + wxBitmapCache m_bitmapCache; }; // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- -static wxToolBarTimer* wxTheToolBarTimer = (wxToolBarTimer*) NULL; +static wxToolBarTimer* wxTheToolBarTimer = NULL; Widget wxToolBarTimer::help_popup = (Widget) 0; Widget wxToolBarTimer::buttonWidget = (Widget) 0; @@ -130,34 +141,35 @@ wxString wxToolBarTimer::helpString; // wxToolBarTool // ---------------------------------------------------------------------------- -wxToolBarToolBase *wxToolBarToolBase::New(wxToolBar *tbar, - int id, - const wxBitmap& bitmap1, - const wxBitmap& bitmap2, - bool toggle, - wxObject *clientData, - const wxString& shortHelpString, - const wxString& longHelpString) +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(tbar, id, bitmap1, bitmap2, toggle, - clientData, shortHelpString, longHelpString); + return new wxToolBarTool(this, id, label, bmpNormal, bmpToggled, kind, + clientData, shortHelp, longHelp); } -wxToolBarToolBase *wxToolBarToolBase::New(wxToolBar *tbar, wxControl *control) + +wxToolBarToolBase * +wxToolBar::CreateTool(wxControl *control, const wxString& label) { - return new wxToolBarTool(tbar, control); + return new wxToolBarTool(this, control, label); } void wxToolBarTool::Init() { m_widget = (Widget)0; - m_pixmap = (Pixmap)0; } wxToolBarTool::~wxToolBarTool() { - XtDestroyWidget(m_widget); - XmDestroyPixmap(DefaultScreenOfDisplay((Display*)wxGetDisplay()), m_pixmap); + if ( m_widget ) + XtDestroyWidget(m_widget); } // ---------------------------------------------------------------------------- @@ -170,6 +182,12 @@ void wxToolBar::Init() 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, @@ -179,18 +197,12 @@ bool wxToolBar::Create(wxWindow *parent, long style, const wxString& name) { - Init(); - - m_windowId = id; - - SetName(name); - m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); - m_foregroundColour = parent->GetForegroundColour(); - m_windowStyle = style; - - SetParent(parent); + if( !wxControl::CreateControl( parent, id, pos, size, style, + wxDefaultValidator, name ) ) + return false; + PreCreation(); - if (parent) parent->AddChild(this); + FixupStyle(); Widget parentWidget = (Widget) parent->GetClientWidget(); @@ -215,21 +227,24 @@ bool wxToolBar::Create(wxWindow *parent, m_mainWidget = (WXWidget) toolbar; - m_font = parent->GetFont(); - ChangeFont(FALSE); + wxPoint rPos = pos; + wxSize rSize = size; - SetCanAddEventHandler(TRUE); - AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y); + if( rPos.x == -1 ) rPos.x = 0; + if( rPos.y == -1 ) rPos.y = 0; + if( rSize.x == -1 && GetParent() ) + rSize.x = GetParent()->GetSize().x; - ChangeBackgroundColour(); + PostCreation(); + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, + rPos.x, rPos.y, rSize.x, rSize.y); - return TRUE; + return true; } wxToolBar::~wxToolBar() { - delete wxTheToolBarTimer; - wxTheToolBarTimer = NULL; + wxDELETE(wxTheToolBarTimer); } bool wxToolBar::Realize() @@ -237,27 +252,28 @@ bool wxToolBar::Realize() if ( m_tools.GetCount() == 0 ) { // nothing to do - return TRUE; + 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; - - int currentSpacing = 0; + int buttonHeight = 0, buttonWidth = 0; Widget button; Pixmap pixmap, insensPixmap; - wxBitmap bmp; + wxBitmap bmp, insensBmp; - wxToolBarToolsList::Node *node = m_tools.GetFirst(); + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); while ( node ) { wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); @@ -265,33 +281,61 @@ bool wxToolBar::Realize() switch ( tool->GetStyle() ) { case wxTOOL_STYLE_CONTROL: - wxFAIL_MSG( _T("not implemented") ); - break; + { + 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: - currentX += separatorSize; + // skip separators for vertical toolbars + if( !isVertical ) + { + currentX += separatorSize; + } break; case wxTOOL_STYLE_BUTTON: button = (Widget) 0; - if ( tool->CanBeToggled() ) + if ( tool->CanBeToggled() && !tool->GetButtonWidget() ) { button = XtVaCreateWidget("toggleButton", xmToggleButtonWidgetClass, (Widget) m_mainWidget, XmNx, currentX, XmNy, currentY, - // XmNpushButtonEnabled, True, + 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); + XtAddCallback ((Widget) button, + XmNvalueChangedCallback, + (XtCallbackProc) wxToolButtonCallback, + (XtPointer) this); XtVaSetValues ((Widget) button, - XmNselectColor, m_backgroundColour.AllocColour(XtDisplay((Widget) button)), - NULL); + XmNselectColor, + m_backgroundColour.AllocColour + (XtDisplay((Widget) button)), + NULL); } - else + else if( !tool->GetButtonWidget() ) { button = XtVaCreateWidget("button", xmPushButtonWidgetClass, (Widget) m_mainWidget, @@ -301,95 +345,83 @@ bool wxToolBar::Realize() XmNlabelType, XmPIXMAP, NULL); XtAddCallback (button, - XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback, - (XtPointer) this); + XmNactivateCallback, + (XtCallbackProc) wxToolButtonCallback, + (XtPointer) this); } - DoChangeBackgroundColour((WXWidget) button, m_backgroundColour, TRUE); + if( !tool->GetButtonWidget() ) + { + wxDoChangeBackgroundColour((WXWidget) button, + m_backgroundColour, true); - tool->SetWidget(button); + 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->GetBitmap1(); - if ( bmp.GetMask() ) + bmp = tool->GetNormalBitmap(); + insensBmp = tool->GetDisabledBitmap(); + if ( bmp.GetMask() || insensBmp.GetMask() ) { - int backgroundPixel; + WXPixel backgroundPixel; XtVaGetValues(button, XmNbackground, &backgroundPixel, - NULL); + NULL); wxColour col; col.SetPixel(backgroundPixel); - wxBitmap newBitmap = wxCreateMaskedBitmap(bmp, col); + if( bmp.IsOk() && bmp.GetMask() ) + { + bmp = wxCreateMaskedBitmap(bmp, col); + tool->SetNormalBitmap(bmp); + } - tool->SetBitmap1(newBitmap); + if( insensBmp.IsOk() && 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; + WXPixel backgroundPixel; if ( tool->CanBeToggled() ) XtVaGetValues(button, XmNselectColor, &backgroundPixel, - NULL); + NULL); else XtVaGetValues(button, XmNarmColor, &backgroundPixel, - NULL); - + NULL); wxColour col; col.SetPixel(backgroundPixel); - if (tool->GetBitmap2().Ok() && tool->GetBitmap2().GetMask()) - { - // Use what's there - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->GetBitmap2(), col); - tool->SetBitmap2(newBitmap); - } - else + pixmap = (Pixmap) bmp.GetDrawable(); { - // Use unselected bitmap - if ( bmp.GetMask() ) - { - wxBitmap newBitmap = wxCreateMaskedBitmap(bmp, col); - tool->SetBitmap2(newBitmap); - } - else - tool->SetBitmap2(bmp); - } + wxBitmap tmp = tool->GetDisabledBitmap(); - pixmap = (Pixmap) bmp.GetPixmap(); - insensPixmap = (Pixmap) bmp.GetInsensPixmap(); + insensPixmap = tmp.IsOk() ? + (Pixmap)tmp.GetDrawable() : + tool->GetInsensPixmap(); + } if (tool->CanBeToggled()) { // Toggle button - Pixmap pixmap2 = (Pixmap) 0; - Pixmap insensPixmap2 = (Pixmap) 0; - - // If there's a bitmap for the toggled state, use it, - // otherwise generate one. - if (tool->GetBitmap2().Ok()) - { - wxBitmap bmp2 = tool->GetBitmap2(); - pixmap2 = (Pixmap) bmp2.GetPixmap(); - insensPixmap2 = (Pixmap) bmp2.GetInsensPixmap(); - } - else - { - pixmap2 = (Pixmap) bmp.GetArmPixmap(button); - insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); - } + Pixmap pixmap2 = tool->GetArmPixmap(); + Pixmap insensPixmap2 = tool->GetInsensPixmap(); XtVaSetValues (button, - XmNindicatorOn, False, - XmNshadowThickness, 2, - // XmNborderWidth, 0, - // XmNspacing, 0, - XmNmarginWidth, 0, - XmNmarginHeight, 0, XmNfillOnSelect, True, XmNlabelPixmap, pixmap, XmNselectPixmap, pixmap2, @@ -400,19 +432,8 @@ bool wxToolBar::Realize() } else { - Pixmap pixmap2 = (Pixmap) 0; - - // If there's a bitmap for the armed state, use it, - // otherwise generate one. - if (tool->GetBitmap2().Ok()) - { - pixmap2 = (Pixmap) tool->GetBitmap2().GetPixmap(); - } - else - { - pixmap2 = (Pixmap) bmp.GetArmPixmap(button); + Pixmap pixmap2 = tool->GetArmPixmap(); - } // Normal button XtVaSetValues(button, XmNlabelPixmap, pixmap, @@ -420,6 +441,7 @@ bool wxToolBar::Realize() XmNarmPixmap, pixmap2, NULL); } + XtManageChild(button); { @@ -428,69 +450,196 @@ bool wxToolBar::Realize() XmNwidth, &width, XmNheight, & height, NULL); - currentX += width + marginX; + 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); - currentSpacing = 0; break; } node = node->GetNext(); } - SetSize(-1, -1, currentX, buttonHeight + 2*marginY); + SetSize( -1, -1, + isVertical ? buttonWidth + 2 * marginX : -1, + isVertical ? -1 : buttonHeight + 2*marginY ); - return TRUE; + return true; } -wxToolBarTool *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), - wxCoord WXUNUSED(y)) const +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y)) const { - wxFAIL_MSG( _T("TODO") ); + wxFAIL_MSG( wxT("TODO") ); - return (wxToolBarTool *)NULL; + return NULL; } -bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarTool *tool) +bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) { tool->Attach(this); - return TRUE; + return true; } -bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarTool *tool) +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) { tool->Detach(); - return TRUE; + 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(wxToolBarTool *tool, bool enable) +void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable) { - XtSetSensitive(tool->GetButtonWidget(), (Boolean) 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(wxToolBarTool *tool, bool toggle) +void wxToolBar::DoToggleTool(wxToolBarToolBase *toolBase, bool toggle) { + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False); } -void wxToolBar::DoSetToggle(wxToolBarTool *tool, bool toggle) +void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) { - wxFAIL_MSG( _T("TODO") ); + // 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 // ---------------------------------------------------------------------------- -wxToolBarTool *wxToolBar::FindToolByWidget(WXWidget w) const +wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const { - wxToolBarToolsList::Node* node = m_tools.GetFirst(); + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); while ( node ) { wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); @@ -502,7 +651,7 @@ wxToolBarTool *wxToolBar::FindToolByWidget(WXWidget w) const node = node->GetNext(); } - return (wxToolBarTool *)NULL; + return NULL; } static void wxToolButtonCallback(Widget w, @@ -510,7 +659,7 @@ static void wxToolButtonCallback(Widget w, XtPointer WXUNUSED(ptr)) { wxToolBar *toolBar = (wxToolBar *) clientData; - wxToolBarTool *tool = toolBar->FindToolByWidget((WXWidget) w); + wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w); if ( !tool ) return; @@ -534,7 +683,7 @@ static void wxToolButtonPopupCallback(Widget w, static const int delayMilli = 800; wxToolBar* toolBar = (wxToolBar*) client_data; - wxToolBarTool *tool = toolBar->FindToolByWidget((WXWidget) w); + wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w); if ( !tool ) return; @@ -562,7 +711,7 @@ static void wxToolButtonPopupCallback(Widget w, wxToolBarTimer::help_popup = (Widget) 0; // One shot - wxTheToolBarTimer->Start(delayMilli, TRUE); + wxTheToolBarTimer->Start(delayMilli, true); } /************************************************************/ @@ -602,7 +751,7 @@ void wxToolBarTimer::Notify() // Move the tooltip more or less above the button int yOffset = 20; // TODO: What should be really? - y -= yOffset; + y = (Position)(y - yOffset); if (y < yOffset) y = 0; /************************************************************/ @@ -634,4 +783,3 @@ void wxToolBarTimer::Notify() /************************************************************/ XtPopup (help_popup, XtGrabNone); } -