X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7fe7d506b191a94ce327c2a18733a4d3bc576cac..3d9b52a80816bc8f59461657bb6a6f7ea858836c:/src/motif/toolbar.cpp diff --git a/src/motif/toolbar.cpp b/src/motif/toolbar.cpp index 451b10f774..cbb8223d82 100644 --- a/src/motif/toolbar.cpp +++ b/src/motif/toolbar.cpp @@ -1,23 +1,41 @@ ///////////////////////////////////////////////////////////////////////////// -// 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/app.h" -#include "wx/timer.h" -#include "wx/motif/toolbar.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 #include #include #include @@ -25,63 +43,170 @@ #include #include #include +#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); + XtPointer ptr); static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, XEvent *event, Boolean *continue_to_dispatch); -class wxToolBarTimer: public wxTimer +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class wxToolBarTimer : public wxTimer { public: - wxToolBarTimer() { } - virtual void Notify(); + 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, const wxString& label) + : wxToolBarToolBase(tbar, control, label) + { + 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(); - static Widget help_popup; - static Widget buttonWidget; - static wxString helpString; + 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 = ""; +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, const wxString& label) +{ + return new wxToolBarTool(this, control, label); +} -wxToolBar::wxToolBar(): - m_widgets(wxKEY_INTEGER) +void wxToolBarTool::Init() { - m_maxWidth = -1; - m_maxHeight = -1; - m_defaultWidth = 24; - m_defaultHeight = 22; + m_widget = (Widget)0; } -bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, const wxString& name) +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; + PreCreation(); - if (parent) parent->AddChild(this); + FixupStyle(); Widget parentWidget = (Widget) parent->GetClientWidget(); @@ -106,593 +231,477 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, cons m_mainWidget = (WXWidget) toolbar; - m_windowFont = 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(); - - return TRUE; + PostCreation(); + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, + rPos.x, rPos.y, rSize.x, rSize.y); + + return true; } wxToolBar::~wxToolBar() { delete wxTheToolBarTimer; wxTheToolBarTimer = NULL; - ClearTools(); - DestroyPixmaps(); } -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; + int buttonHeight = 0, buttonWidth = 0; - int currentSpacing = 0; + Widget button; + Pixmap pixmap, insensPixmap; + wxBitmap bmp, insensBmp; - m_widgets.Clear(); - Widget prevButton = (Widget) 0; - wxNode* node = m_tools.First(); - while (node) + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + while ( node ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); - if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) - currentX += separatorSize; - else if (tool->m_bitmap1.Ok()) + switch ( tool->GetStyle() ) { - Widget button = (Widget) 0; - - if (tool->m_isToggle) + case wxTOOL_STYLE_CONTROL: { - button = XtVaCreateWidget("toggleButton", - xmToggleButtonWidgetClass, (Widget) m_mainWidget, - XmNx, currentX, XmNy, currentY, - // XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - NULL); - XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback, - (XtPointer) this); - } - 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); - } - - // 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. - wxBitmap originalBitmap = tool->m_bitmap1; - - if (tool->m_bitmap1.GetMask()) - { - int backgroundPixel; - XtVaGetValues(button, XmNbackground, &backgroundPixel, - NULL); - - - wxColour col; - col.SetPixel(backgroundPixel); - - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap1, col); + 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; - tool->m_bitmap1 = newBitmap; + break; } + case wxTOOL_STYLE_SEPARATOR: + // skip separators for vertical toolbars + if( !isVertical ) + { + currentX += separatorSize; + } + break; - // Create a selected/toggled bitmap. If there isn't a m_bitmap2, - // we need to create it (with a darker, selected background) - int backgroundPixel; - if (tool->m_isToggle) - XtVaGetValues(button, XmNselectColor, &backgroundPixel, - NULL); - else - XtVaGetValues(button, XmNarmColor, &backgroundPixel, - NULL); - - wxColour col; - col.SetPixel(backgroundPixel); + case wxTOOL_STYLE_BUTTON: + button = (Widget) 0; - if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask()) - { - // Use what's there - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap2, col); - tool->m_bitmap2 = newBitmap; - } - else - { - // Use unselected bitmap - if (originalBitmap.GetMask()) + if ( tool->CanBeToggled() && !tool->GetButtonWidget() ) { - wxBitmap newBitmap = wxCreateMaskedBitmap(originalBitmap, col); - tool->m_bitmap2 = newBitmap; - } - else - tool->m_bitmap2 = tool->m_bitmap1; - } + 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); + } - Pixmap pixmap = (Pixmap) tool->m_bitmap1.GetPixmap(); - Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap(); + if( !tool->GetButtonWidget() ) + { + wxDoChangeBackgroundColour((WXWidget) button, + m_backgroundColour, true); - if (tool->m_isToggle) - { - // Toggle button - Pixmap pixmap2 = (Pixmap) 0; - Pixmap insensPixmap2 = (Pixmap) 0; + tool->SetWidget(button); + } + else + { + button = (Widget)tool->GetButtonWidget(); + XtVaSetValues( button, + XmNx, currentX, XmNy, currentY, + NULL ); + } - // If there's a bitmap for the toggled state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) + // 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() ) { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); - insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap(); + WXPixel 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) + WXPixel backgroundPixel; + if ( tool->CanBeToggled() ) + XtVaGetValues(button, XmNselectColor, &backgroundPixel, + NULL); else + XtVaGetValues(button, XmNarmColor, &backgroundPixel, + NULL); + wxColour col; + col.SetPixel(backgroundPixel); + + pixmap = (Pixmap) bmp.GetDrawable(); { - pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); - insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); - m_pixmaps.Append((wxObject*) insensPixmap2); // Store for later deletion + wxBitmap tmp = tool->GetDisabledBitmap(); + + insensPixmap = tmp.Ok() ? + (Pixmap)tmp.GetDrawable() : + tool->GetInsensPixmap(); } - XtVaSetValues (button, - XmNindicatorOn, False, - XmNshadowThickness, 2, - // XmNborderWidth, 0, - // XmNspacing, 0, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNfillOnSelect, True, - XmNlabelPixmap, pixmap, - XmNselectPixmap, pixmap2, - XmNlabelInsensitivePixmap, insensPixmap, - XmNselectInsensitivePixmap, insensPixmap2, - XmNlabelType, XmPIXMAP, - NULL); - } - else - { - Pixmap pixmap2 = (Pixmap) 0; - // If there's a bitmap for the armed state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) + if (tool->CanBeToggled()) { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); + // 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); - + Pixmap pixmap2 = tool->GetArmPixmap(); + + // Normal button + XtVaSetValues(button, + XmNlabelPixmap, pixmap, + XmNlabelInsensitivePixmap, insensPixmap, + XmNarmPixmap, pixmap2, + NULL); } - // Normal button - XtVaSetValues(button, - XmNlabelPixmap, pixmap, - XmNlabelInsensitivePixmap, insensPixmap, - XmNarmPixmap, pixmap2, - NULL); - } - XtManageChild(button); - Dimension width, height; - XtVaGetValues(button, XmNwidth, & width, XmNheight, & height, - NULL); - currentX += width + marginX; - buttonHeight = wxMax(buttonHeight, height); + XtManageChild(button); - XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, - False, wxToolButtonPopupCallback, (XtPointer) this); - m_widgets.Append(tool->m_index, (wxObject*) 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); + } - prevButton = button; - currentSpacing = 0; + XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, + False, wxToolButtonPopupCallback, (XtPointer) this); + + break; } - node = node->Next(); + + 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; } -// Old version, assuming we use a form. Now we use -// a bulletin board, so we can create controls on the toolbar. -#if 0 -bool wxToolBar::CreateTools() +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y)) const { - if (m_tools.Number() == 0) - return FALSE; + wxFAIL_MSG( _T("TODO") ); - // Separator spacing - const int separatorSize = GetToolSeparation(); // 8; + return (wxToolBarToolBase *)NULL; +} - int currentSpacing = 0; +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; - m_widgets.Clear(); - Widget prevButton = (Widget) 0; - wxNode* node = m_tools.First(); - while (node) + for( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + node; node = node->GetNext() ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + wxToolBarTool *t = (wxToolBarTool*)node->GetData(); - if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) - currentSpacing = separatorSize; - else if (tool->m_bitmap1.Ok()) + if( t == tool ) { - Widget button = (Widget) 0; - - if (tool->m_isToggle) + switch ( t->GetStyle() ) { - button = XtVaCreateManagedWidget("toggleButton", - xmToggleButtonWidgetClass, (Widget) m_mainWidget, - XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET, - XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton, - XmNleftOffset, currentSpacing, - XmNtopAttachment, XmATTACH_FORM, - // XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - NULL); - XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback, - (XtPointer) this); - } - else + case wxTOOL_STYLE_CONTROL: { - button = XtVaCreateManagedWidget("button", - xmPushButtonWidgetClass, (Widget) m_mainWidget, - XmNleftAttachment, (prevButton == (Widget) 0) ? XmATTACH_FORM : XmATTACH_WIDGET, - XmNleftWidget, (prevButton == (Widget) 0) ? NULL : prevButton, - XmNleftOffset, currentSpacing, - XmNtopAttachment, XmATTACH_FORM, - XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - NULL); - XtAddCallback (button, - XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback, - (XtPointer) this); + wxSize size = t->GetControl()->GetSize(); + offset = isVertical ? size.y : size.x; + offset += packing; + break; } - - // 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. - wxBitmap originalBitmap = tool->m_bitmap1; - - if (tool->m_bitmap1.GetMask()) + case wxTOOL_STYLE_SEPARATOR: + offset = isVertical ? 0 : separatorSize; + break; + case wxTOOL_STYLE_BUTTON: { - int backgroundPixel; - XtVaGetValues(button, XmNbackground, &backgroundPixel, - NULL); + Widget w = t->GetButtonWidget(); + Dimension width, height; + XtVaGetValues( w, + XmNwidth, &width, + XmNheight, &height, + NULL ); - wxColour col; - col.SetPixel(backgroundPixel); - - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap1, col); - - tool->m_bitmap1 = newBitmap; + offset = isVertical ? height : width; + offset += packing; + break; } - - // Create a selected/toggled bitmap. If there isn't a m_bitmap2, - // we need to create it (with a darker, selected background) - int backgroundPixel; - if (tool->m_isToggle) - XtVaGetValues(button, XmNselectColor, &backgroundPixel, - NULL); - else - XtVaGetValues(button, XmNarmColor, &backgroundPixel, - NULL); - - wxColour col; - col.SetPixel(backgroundPixel); - - if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask()) - { - // Use what's there - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap2, col); - tool->m_bitmap2 = newBitmap; } - else + } + else if( offset ) + { + switch ( t->GetStyle() ) { - // Use unselected bitmap - if (originalBitmap.GetMask()) - { - wxBitmap newBitmap = wxCreateMaskedBitmap(originalBitmap, col); - tool->m_bitmap2 = newBitmap; - } - else - tool->m_bitmap2 = tool->m_bitmap1; - } - - Pixmap pixmap = (Pixmap) tool->m_bitmap1.GetPixmap(); - Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap(); - - if (tool->m_isToggle) + case wxTOOL_STYLE_CONTROL: { - // Toggle button - Pixmap pixmap2 = (Pixmap) 0; - Pixmap insensPixmap2 = (Pixmap) 0; + wxPoint location = t->GetControl()->GetPosition(); - // If there's a bitmap for the toggled state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) - { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); - insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap(); - } + if( isVertical ) + location.y -= offset; else - { - pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); - insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); - m_pixmaps.Append((wxObject*) insensPixmap2); // Store for later deletion - } - XtVaSetValues (button, - XmNindicatorOn, False, - XmNshadowThickness, 2, - // XmNborderWidth, 0, - // XmNspacing, 0, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNfillOnSelect, True, - XmNlabelPixmap, pixmap, - XmNselectPixmap, pixmap2, - XmNlabelInsensitivePixmap, insensPixmap, - XmNselectInsensitivePixmap, insensPixmap2, - XmNlabelType, XmPIXMAP, - NULL); + location.x -= offset; + + t->GetControl()->Move( location ); + break; } - else + case wxTOOL_STYLE_SEPARATOR: + break; + case wxTOOL_STYLE_BUTTON: { - Pixmap pixmap2 = (Pixmap) 0; - - // If there's a bitmap for the armed state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) - { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); - } + Dimension x, y; + XtVaGetValues( t->GetButtonWidget(), + XmNx, &x, + XmNy, &y, + NULL ); + + if( isVertical ) + y = (Dimension)(y - offset); else - { - pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); + x = (Dimension)(x - offset); - } - // Normal button - XtVaSetValues(button, - XmNlabelPixmap, pixmap, - XmNlabelInsensitivePixmap, insensPixmap, - XmNarmPixmap, pixmap2, - NULL); + XtVaSetValues( t->GetButtonWidget(), + XmNx, x, + XmNy, y, + NULL ); + break; + } } - - XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, - False, wxToolButtonPopupCallback, (XtPointer) this); - m_widgets.Append(tool->m_index, (wxObject*) button); - - prevButton = button; - currentSpacing = 0; } - node = node->Next(); } - return TRUE; + return true; } -#endif -void wxToolBar::SetToolBitmapSize(const wxSize& size) +void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable) { - // TODO not necessary? - m_defaultWidth = size.x; m_defaultHeight = size.y; + 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) { - int w, h; - GetSize(& w, & h); + wxToolBarTool *tool = (wxToolBarTool *)toolBase; - return wxSize(w, h); + 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 not necessary? - 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) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_enabled = enable; + int old_width, old_height; + GetSize(&old_width, &old_height); - WXWidget widget = FindWidgetForIndex(tool->m_index); - if (widget == (WXWidget) 0) - return; + // Correct width and height if needed. + if ( width == -1 || height == -1 ) + { + wxSize defaultSize = GetSize(); - XtSetSensitive((Widget) widget, (Boolean) enable); + if ( width == -1 ) + width = defaultSize.x; + if ( height == -1 ) + height = defaultSize.y; } -} -void wxToolBar::ToggleTool(int toolIndex, bool toggle) -{ - wxNode *node = m_tools.Find((long)toolIndex); - if (node) + 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(); - if (tool->m_isToggle) + // 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() ) { - tool->m_toggleState = toggle; - - WXWidget widget = FindWidgetForIndex(tool->m_index); - if (widget == (WXWidget) 0) - return; - - XmToggleButtonSetState((Widget) widget, (Boolean) toggle, False); + frame->SendSizeEvent(); } } } -void wxToolBar::ClearTools() -{ - wxNode* node = m_widgets.First(); - while (node) - { - Widget button = (Widget) node->Data(); - XtDestroyWidget(button); - node = node->Next(); - } - m_widgets.Clear(); - DestroyPixmaps(); - - wxToolBarBase::ClearTools(); -} +// ---------------------------------------------------------------------------- +// Motif callbacks +// ---------------------------------------------------------------------------- -void wxToolBar::DestroyPixmaps() +wxToolBarToolBase *wxToolBar::FindToolByWidget(WXWidget w) const { - wxNode* node = m_pixmaps.First(); - while (node) + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + while ( node ) { - Pixmap pixmap = (Pixmap) node->Data(); - XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) GetXDisplay()), pixmap); - node = node->Next(); - } - m_pixmaps.Clear(); -} - -// 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) -{ - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, (wxBitmap *)NULL, toggle, xPos, yPos, helpString1, helpString2); - tool->m_clientData = clientData; - - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; - - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; - - tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight()); - - m_tools.Append((long)index, tool); - return tool; -} + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + if ( tool->GetButtonWidget() == w) + { + return tool; + } -int wxToolBar::FindIndexForWidget(WXWidget w) -{ - wxNode* node = m_widgets.First(); - while (node) - { - WXWidget widget = (WXWidget) node->Data(); - if (widget == w) - return (int) node->key.integer; - node = node->Next(); + node = node->GetNext(); } - return -1; -} -WXWidget wxToolBar::FindWidgetForIndex(int index) -{ - wxNode* node = m_widgets.Find((long) index); - if (!node) - return (WXWidget) 0; - else - return (WXWidget) node->Data(); -} - -WXWidget wxToolBar::GetTopWidget() const -{ - return m_mainWidget; + return (wxToolBarToolBase *)NULL; } -WXWidget wxToolBar::GetClientWidget() const -{ - return m_mainWidget; -} - -WXWidget wxToolBar::GetMainWidget() const -{ - return m_mainWidget; -} - - -void wxToolButtonCallback (Widget w, XtPointer clientData, - XtPointer ptr) +static void wxToolButtonCallback(Widget w, + XtPointer clientData, + XtPointer WXUNUSED(ptr)) { wxToolBar *toolBar = (wxToolBar *) clientData; - int index = toolBar->FindIndexForWidget((WXWidget) w); + wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w); + if ( !tool ) + return; - if (index != -1) + if ( tool->CanBeToggled() ) + tool->Toggle(); + + if ( !toolBar->OnLeftClick(tool->GetId(), tool->IsToggled()) ) { - wxNode *node = toolBar->GetTools().Find((long)index); - if (!node) - return; - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) - tool->m_toggleState = toolBar->GetToolState(index); - - (void) toolBar->OnLeftClick(index, tool->m_toggleState); + // revert + tool->Toggle(); } - } -static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, - XEvent *event, Boolean *continue_to_dispatch) +static void wxToolButtonPopupCallback(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *WXUNUSED(continue_to_dispatch)) { // TODO: retrieve delay before popping up tooltip from wxSystemSettings. - int delayMilli = 800; - wxToolBar* toolBar = (wxToolBar*) client_data; + static const int delayMilli = 800; - int index = toolBar->FindIndexForWidget((WXWidget) w); + wxToolBar* toolBar = (wxToolBar*) client_data; + wxToolBarToolBase *tool = toolBar->FindToolByWidget((WXWidget) w); - if (index != -1) - { - wxNode *node = toolBar->GetTools().Find((long)index); - if (!node) - return; - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - wxString str(toolBar->GetToolShortHelp(index)); - if (str.IsNull() || str == "") - return; + if ( !tool ) + return; - if (!wxTheToolBarTimer) - wxTheToolBarTimer = new wxToolBarTimer; + wxString tooltip = tool->GetShortHelp(); + if ( !tooltip ) + return; - wxToolBarTimer::buttonWidget = w; - wxToolBarTimer::helpString = str; + if (!wxTheToolBarTimer) + wxTheToolBarTimer = new wxToolBarTimer; + wxToolBarTimer::buttonWidget = w; + wxToolBarTimer::helpString = tooltip; /************************************************************/ /* Popup help label */ @@ -703,11 +712,11 @@ static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, { XtDestroyWidget (wxToolBarTimer::help_popup); XtPopdown (wxToolBarTimer::help_popup); - } + } wxToolBarTimer::help_popup = (Widget) 0; // One shot - wxTheToolBarTimer->Start(delayMilli, TRUE); + wxTheToolBarTimer->Start(delayMilli, true); } /************************************************************/ @@ -721,10 +730,9 @@ static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, { XtDestroyWidget (wxToolBarTimer::help_popup); XtPopdown (wxToolBarTimer::help_popup); - } + } wxToolBarTimer::help_popup = (Widget) 0; } - } } void wxToolBarTimer::Notify() @@ -734,44 +742,44 @@ void wxToolBarTimer::Notify() /************************************************************/ /* Create shell without window decorations */ /************************************************************/ - help_popup = XtVaCreatePopupShell ("shell", - overrideShellWidgetClass, (Widget) wxTheApp->GetTopLevelWidget(), + help_popup = XtVaCreatePopupShell ("shell", + overrideShellWidgetClass, (Widget) wxTheApp->GetTopLevelWidget(), NULL); /************************************************************/ /* Get absolute position on display of toolbar button */ /************************************************************/ XtTranslateCoords (buttonWidget, - (Position) 0, - (Position) 0, + (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; + 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, + 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, + XtVaCreateManagedWidget ("help_label", + xmLabelWidgetClass, help_popup, XmNlabelString, text, - XtVaTypedArg, - XmNforeground, XtRString, "black", - strlen("black")+1, - XtVaTypedArg, - XmNbackground, XtRString, "LightGoldenrod", - strlen("LightGoldenrod")+1, + XtVaTypedArg, + XmNforeground, XtRString, "black", + strlen("black")+1, + XtVaTypedArg, + XmNbackground, XtRString, "LightGoldenrod", + strlen("LightGoldenrod")+1, NULL); XmStringFree (text); @@ -780,4 +788,3 @@ void wxToolBarTimer::Notify() /************************************************************/ XtPopup (help_popup, XtGrabNone); } -