/////////////////////////////////////////////////////////////////////////////
// Name: toolbar.cpp
// Purpose: wxToolBar
-// Author: AUTHOR
+// Author: David Webster
// Modified by:
-// Created: 04/01/98
+// Created: 06/30/02
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) David Webster
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "toolbar.h"
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
+
+#ifndef WX_PRECOMP
+ #include "wx/settings.h"
+ #include "wx/window.h"
+ #include "wx/frame.h"
+ #include "wx/app.h"
+ #include "wx/dcclient.h"
+ #include "wx/dcmemory.h"
#endif
-#include "wx/wx.h"
+#include "wx/tooltip.h"
#include "wx/toolbar.h"
-#if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
+bool wxToolBar::m_bInitialized = FALSE;
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class wxToolBarTool : public wxToolBarToolBase
+{
+public:
+ inline wxToolBarTool( wxToolBar* pTbar
+ ,int vId
+ ,const wxString& rsLabel
+ ,const wxBitmap& rBitmap1
+ ,const wxBitmap& rBitmap2
+ ,wxItemKind vKind
+ ,wxObject* pClientData
+ ,const wxString& rsShortHelpString
+ ,const wxString& rsLongHelpString
+ ) : wxToolBarToolBase( pTbar
+ ,vId
+ ,rsLabel
+ ,rBitmap1
+ ,rBitmap2
+ ,vKind
+ ,pClientData
+ ,rsShortHelpString
+ ,rsLongHelpString
+ )
+ {
+ }
+
+ inline wxToolBarTool( wxToolBar* pTbar
+ ,wxControl* pControl
+ ) : wxToolBarToolBase( pTbar
+ ,pControl
+ )
+ {
+ }
+
+ void SetSize(const wxSize& rSize)
+ {
+ m_vWidth = rSize.x;
+ m_vHeight = rSize.y;
+ }
+
+ wxCoord GetWidth(void) const { return m_vWidth; }
+ wxCoord GetHeight(void) const { return m_vHeight; }
+
+ wxCoord m_vX;
+ wxCoord m_vY;
+ wxCoord m_vWidth;
+ wxCoord m_vHeight;
+}; // end of CLASS wxToolBarTool
+
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
+ EVT_SIZE(wxToolBar::OnSize)
+ EVT_PAINT(wxToolBar::OnPaint)
+ EVT_KILL_FOCUS(wxToolBar::OnKillFocus)
+ EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
+ EVT_TIMER(-1, wxToolBar::OnTimer)
END_EVENT_TABLE()
-#endif
-wxToolBar::wxToolBar()
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// tool bar tools creation
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase* wxToolBar::CreateTool(
+ int nId
+, const wxString& rsLabel
+, const wxBitmap& rBmpNormal
+, const wxBitmap& rBmpDisabled
+, wxItemKind eKind
+, wxObject* pClientData
+, const wxString& rsShortHelp
+, const wxString& rsLongHelp
+)
{
- m_maxWidth = -1;
- m_maxHeight = -1;
- m_defaultWidth = 24;
- m_defaultHeight = 22;
- // TODO
-}
+ return new wxToolBarTool( this
+ ,nId
+ ,rsLabel
+ ,rBmpNormal
+ ,rBmpDisabled
+ ,eKind
+ ,pClientData
+ ,rsShortHelp
+ ,rsLongHelp
+ );
+} // end of wxToolBarSimple::CreateTool
-bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
- long style, const wxString& name)
+wxToolBarToolBase *wxToolBar::CreateTool(
+ wxControl* pControl
+)
{
- m_maxWidth = -1;
- m_maxHeight = -1;
-
- m_defaultWidth = 24;
- m_defaultHeight = 22;
- SetName(name);
+ return new wxToolBarTool( this
+ ,pControl
+ );
+} // end of wxToolBarSimple::CreateTool
- m_windowStyle = style;
+// ----------------------------------------------------------------------------
+// wxToolBarSimple creation
+// ----------------------------------------------------------------------------
- SetParent(parent);
+void wxToolBar::Init()
+{
+ m_nCurrentRowsOrColumns = 0;
- if (parent) parent->AddChild(this);
+ m_vLastX = m_vLastY = 0;
+ m_vMaxWidth = m_vMaxHeight = 0;
+ m_nPressedTool = m_nCurrentTool = -1;
+ m_vXPos = m_vYPos = -1;
+ m_vTextX = m_vTextY = 0;
- // TODO create toolbar
-
- return FALSE;
-}
+ m_toolPacking = 1;
+ m_toolSeparation = 5;
-wxToolBar::~wxToolBar()
+ m_defaultWidth = 16;
+ m_defaultHeight = 15;
+
+ m_pToolTip = NULL;
+} // end of wxToolBar::Init
+
+wxToolBarToolBase* wxToolBar::DoAddTool(
+ int vId
+, const wxString& rsLabel
+, const wxBitmap& rBitmap
+, const wxBitmap& rBmpDisabled
+, wxItemKind eKind
+, const wxString& rsShortHelp
+, const wxString& rsLongHelp
+, wxObject* pClientData
+, wxCoord vXPos
+, wxCoord vYPos
+)
{
- // TODO
-}
+ //
+ // Rememeber the position for DoInsertTool()
+ //
+ m_vXPos = vXPos;
+ m_vYPos = vYPos;
-bool wxToolBar::CreateTools()
+ return wxToolBarBase::DoAddTool( vId
+ ,rsLabel
+ ,rBitmap
+ ,rBmpDisabled
+ ,eKind
+ ,rsShortHelp
+ ,rsLongHelp
+ ,pClientData
+ ,vXPos
+ ,vYPos
+ );
+} // end of wxToolBar::DoAddTool
+
+bool wxToolBar::DeleteTool(
+ int nId
+)
+{
+ bool bOk = wxToolBarBase::DeleteTool(nId);
+
+ if (bOk)
+ {
+ Realize();
+ }
+ return bOk;
+} // end of wxToolBar::DeleteTool
+
+bool wxToolBar::DeleteToolByPos(
+ size_t nPos
+)
{
- if (m_tools.Number() == 0)
+ bool bOk = wxToolBarBase::DeleteToolByPos(nPos);
+
+ if (bOk)
+ {
+ Realize();
+ }
+ return bOk;
+} // end of wxToolBar::DeleteTool
+
+wxToolBarToolBase* wxToolBar::InsertControl(
+ size_t nPos
+, wxControl* pControl
+)
+{
+ wxToolBarToolBase* pTool = wxToolBarBase::InsertControl( nPos
+ ,pControl
+ );
+ if (m_bInitialized)
+ {
+ Realize();
+ Refresh();
+ }
+ return pTool;
+} // end of wxToolBar::InsertControl
+
+wxToolBarToolBase* wxToolBar::InsertSeparator(
+ size_t nPos
+)
+{
+ wxToolBarToolBase* pTool = wxToolBarBase::InsertSeparator(nPos);
+
+ if (m_bInitialized)
+ {
+ Realize();
+ Refresh();
+ }
+ return pTool;
+} // end of wxToolBar::InsertSeparator
+
+wxToolBarToolBase* wxToolBar::InsertTool(
+ size_t nPos
+, int nId
+, const wxString& rsLabel
+, const wxBitmap& rBitmap
+, const wxBitmap& rBmpDisabled
+, wxItemKind eKind
+, const wxString& rsShortHelp
+, const wxString& rsLongHelp
+, wxObject* pClientData
+)
+{
+ wxToolBarToolBase* pTool = wxToolBarBase::InsertTool( nPos
+ ,nId
+ ,rsLabel
+ ,rBitmap
+ ,rBmpDisabled
+ ,eKind
+ ,rsShortHelp
+ ,rsLongHelp
+ ,pClientData
+ );
+ if (m_bInitialized)
+ {
+ Realize();
+ Refresh();
+ }
+ return pTool;
+} // end of wxToolBar::InsertTool
+
+bool wxToolBar::DoInsertTool(
+ size_t WXUNUSED(nPos)
+, wxToolBarToolBase* pToolBase
+)
+{
+ wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
+
+ pTool->m_vX = m_vXPos;
+ if (pTool->m_vX == -1)
+ pTool->m_vX = m_xMargin;
+
+ pTool->m_vY = m_vYPos;
+ if (pTool->m_vY == -1)
+ pTool->m_vX = m_yMargin;
+
+ pTool->SetSize(GetToolSize());
+
+ if (pTool->IsButton())
+ {
+ //
+ // Calculate reasonable max size in case Layout() not called
+ //
+ if ((pTool->m_vX + pTool->GetNormalBitmap().GetWidth() + m_xMargin) > m_vMaxWidth)
+ m_vMaxWidth = (wxCoord)((pTool->m_vX + pTool->GetWidth() + m_xMargin));
+
+ if ((pTool->m_vY + pTool->GetNormalBitmap().GetHeight() + m_yMargin) > m_vMaxHeight)
+ m_vMaxHeight = (wxCoord)((pTool->m_vY + pTool->GetHeight() + m_yMargin));
+ }
+ return TRUE;
+} // end of wxToolBar::DoInsertTool
+
+bool wxToolBar::DoDeleteTool(
+ size_t WXUNUSED(nPos)
+, wxToolBarToolBase* pTool
+)
+{
+ pTool->Detach();
+ Refresh();
+ return TRUE;
+} // end of wxToolBar::DoDeleteTool
+
+bool wxToolBar::Create(
+ wxWindow* pParent
+, wxWindowID vId
+, const wxPoint& rPos
+, const wxSize& rSize
+, long lStyle
+, const wxString& rsName
+)
+{
+ if ( !wxWindow::Create( pParent
+ ,vId
+ ,rPos
+ ,rSize
+ ,lStyle
+ ,rsName
+ ))
return FALSE;
- // TODO
- return FALSE;
-}
+ // Set it to grey (or other 3D face colour)
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
+ SetFont(*wxSMALL_FONT);
+
+ if (GetWindowStyleFlag() & wxTB_VERTICAL)
+ {
+ m_vLastX = 7;
+ m_vLastY = 3;
+
+ m_maxRows = 32000; // a lot
+ m_maxCols = 1;
+ }
+ else
+ {
+ m_vLastX = 3;
+ m_vLastY = 7;
+
+ m_maxRows = 1;
+ m_maxCols = 32000; // a lot
+ }
+ SetCursor(*wxSTANDARD_CURSOR);
+
+ //
+ // The toolbar's tools, if they have labels and the winTB_TEXT
+ // style is set, then we need to take into account the size of
+ // the text when drawing tool bitmaps and the text
+ //
+ if (HasFlag(wxTB_TEXT))
+ {
+ wxClientDC vDC(this);
+
+ vDC.SetFont(GetFont());
+ vDC.GetTextExtent( wxT("XXXX")
+ ,&m_vTextX
+ ,&m_vTextY
+ );
+ }
+
+ //
+ // Position it
+ //
+ int nX = rPos.x;
+ int nY = rPos.y;
+ int nWidth = rSize.x;
+ int nHeight = rSize.y;
+
+ if (lStyle & wxTB_HORIZONTAL)
+ {
+ if (nWidth <= 0)
+ {
+ nWidth = pParent->GetClientSize().x;
+ }
+ if (nHeight <= 0)
+ {
+ if (lStyle & wxTB_TEXT)
+ nHeight = m_defaultHeight + m_vTextY;
+ else
+ nHeight = m_defaultHeight;
+ }
+ }
+ else
+ {
+ if (nHeight <= 0)
+ {
+ nHeight = pParent->GetClientSize().y;
+ }
+ if (nWidth <= 0)
+ {
+ if (lStyle & wxTB_TEXT)
+ nWidth = m_vTextX + (int)(m_vTextX/2); // a little margin
+ else
+ nWidth = m_defaultWidth + (int)(m_defaultWidth/2); // a little margin
+ }
+ }
+ if (nX < 0)
+ nX = 0;
+ if (nY < 0)
+ nY = 0;
+
+ SetSize( nX
+ ,nY
+ ,nWidth
+ ,nHeight
+ );
+ return TRUE;
+} // end of wxToolBar::Create
+
+wxToolBar::~wxToolBar()
+{
+ if (m_pToolTip)
+ {
+ delete m_pToolTip;
+ m_pToolTip = NULL;
+ }
+} // end of wxToolBar::~wxToolBar
+
+bool wxToolBar::Realize()
+{
+ int nMaxToolWidth = 0;
+ int nMaxToolHeight = 0;
+
+ m_nCurrentRowsOrColumns = 0;
+ m_vLastX = m_xMargin;
+ m_vLastY = m_yMargin;
+ m_vMaxWidth = 0;
+ m_vMaxHeight = 0;
+
+
+ //
+ // Find the maximum tool width and height
+ //
+ wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+
+ while (node )
+ {
+ wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
+
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
+ {
+ //
+ // Set the height according to the font and the border size
+ //
+ if (pTool->GetWidth() > m_vTextX)
+ nMaxToolWidth = pTool->GetWidth() + 4;
+ else
+ nMaxToolWidth = m_vTextX;
+ if (pTool->GetHeight() + m_vTextY > nMaxToolHeight)
+ nMaxToolHeight = pTool->GetHeight() + m_vTextY;
+ }
+ else
+ {
+ if (pTool->GetWidth() > nMaxToolWidth )
+ nMaxToolWidth = pTool->GetWidth() + 4;
+ if (pTool->GetHeight() > nMaxToolHeight)
+ nMaxToolHeight = pTool->GetHeight();
+ }
+ node = node->GetNext();
+ }
+
+ wxCoord vTbWidth = 0L;
+ wxCoord vTbHeight = 0L;
+
+ GetSize( &vTbWidth
+ ,&vTbHeight
+ );
+ if (vTbHeight < nMaxToolHeight)
+ {
+ SetSize( -1L
+ ,-1L
+ ,vTbWidth
+ ,nMaxToolHeight + 4
+ );
+ if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
+
+ if (pFrame)
+ pFrame->PositionToolBar();
+ }
+ }
+
+ int nSeparatorSize = m_toolSeparation;
+
+ node = m_tools.GetFirst();
+ while (node)
+ {
+ wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
+
+ if (pTool->IsSeparator())
+ {
+ if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
+ {
+ pTool->m_vX = m_vLastX + nSeparatorSize;
+ pTool->m_vHeight = m_defaultHeight + m_vTextY;
+ if (m_nCurrentRowsOrColumns >= m_maxCols)
+ m_vLastY += nSeparatorSize;
+ else
+ m_vLastX += nSeparatorSize * 4;
+ }
+ else
+ {
+ pTool->m_vY = m_vLastY + nSeparatorSize;
+ pTool->m_vHeight = m_defaultHeight + m_vTextY;
+ if (m_nCurrentRowsOrColumns >= m_maxRows)
+ m_vLastX += nSeparatorSize;
+ else
+ m_vLastY += nSeparatorSize * 4;
+ }
+ }
+ else if (pTool->IsButton())
+ {
+ if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
+ {
+ if (m_nCurrentRowsOrColumns >= m_maxCols)
+ {
+ m_nCurrentRowsOrColumns = 0;
+ m_vLastX = m_xMargin;
+ m_vLastY += nMaxToolHeight + m_toolPacking;
+ }
+ pTool->m_vX = m_vLastX + (nMaxToolWidth - ((int)(nMaxToolWidth/2) + (int)(pTool->GetWidth()/2)));
+ if (HasFlag(wxTB_TEXT))
+ pTool->m_vY = m_vLastY + nSeparatorSize - 2; // just bit of adjustment
+ else
+ pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
+ m_vLastX += nMaxToolWidth + m_toolPacking + m_toolSeparation;
+ }
+ else
+ {
+ if (m_nCurrentRowsOrColumns >= m_maxRows)
+ {
+ m_nCurrentRowsOrColumns = 0;
+ m_vLastX += (nMaxToolWidth + m_toolPacking);
+ m_vLastY = m_yMargin;
+ }
+ pTool->m_vX = m_vLastX + pTool->GetWidth();
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+ pTool->m_vY = m_vLastY + (nMaxToolHeight - m_vTextY) + m_toolPacking;
+ else
+ pTool->m_vY = m_vLastY + (nMaxToolHeight - (int)(pTool->GetHeight()/2));
+ m_vLastY += nMaxToolHeight + m_toolPacking + m_toolSeparation;
+ }
+ m_nCurrentRowsOrColumns++;
+ }
+ else
+ {
+ // TODO: support the controls
+ }
+
+ if (m_vLastX > m_maxWidth)
+ m_maxWidth = m_vLastX;
+ if (m_vLastY > m_maxHeight)
+ m_maxHeight = m_vLastY;
+
+ node = node->GetNext();
+ }
+
+ if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+ m_maxWidth += nMaxToolWidth;
+ else
+ m_maxHeight += nMaxToolHeight;
+
+ m_maxWidth += m_xMargin;
+ m_maxHeight += m_yMargin;
+ m_bInitialized = TRUE;
+ return TRUE;
+} // end of wxToolBar::Realize
+
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
-void wxToolBar::SetToolBitmapSize(const wxSize& size)
+void wxToolBar::OnPaint (
+ wxPaintEvent& WXUNUSED(rEvent)
+)
{
- m_defaultWidth = size.x; m_defaultHeight = size.y;
- // TODO
-}
+ wxPaintDC vDc(this);
-wxSize wxToolBar::GetMaxSize() const
+ PrepareDC(vDc);
+
+ static int nCount = 0;
+
+ //
+ // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
+ //
+ if (nCount > 0)
+ return;
+ nCount++;
+
+ ::WinFillRect(vDc.GetHPS(), &vDc.m_vRclPaint, GetBackgroundColour().GetPixel());
+ for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ wxToolBarTool* pTool = (wxToolBarTool*)node->GetData();
+
+ if (pTool->IsButton() )
+ DrawTool(vDc, pTool);
+ if (pTool->IsSeparator())
+ {
+ wxPen vDarkGreyPen( wxColour(85, 85, 85)
+ ,1
+ ,wxSOLID
+ );
+ int nX;
+ int nY;
+ int nHeight = 0;
+ int nWidth = 0;
+
+ vDc.SetPen(vDarkGreyPen);
+ if (HasFlag(wxTB_TEXT))
+ {
+ if (HasFlag(wxTB_HORIZONTAL))
+ {
+ nX = pTool->m_vX;
+ nY = pTool->m_vY - (m_vTextY - 6);
+ nHeight = (m_vTextY - 2) + pTool->GetHeight();
+ }
+ else
+ {
+ nX = pTool->m_vX + m_xMargin + 10;
+ nY = pTool->m_vY + m_vTextY + m_toolSeparation;
+ nWidth = pTool->GetWidth() > m_vTextX ? pTool->GetWidth() : m_vTextX;
+ }
+ }
+ else
+ {
+ nX = pTool->m_vX;
+ nY = pTool->m_vY;
+ if (HasFlag(wxTB_HORIZONTAL))
+ nHeight = pTool->GetHeight() - 2;
+ else
+ {
+ nX += m_xMargin + 10;
+ nY += m_yMargin + m_toolSeparation;
+ nWidth = pTool->GetWidth();
+ }
+ }
+ vDc.DrawLine(nX, nY, nX + nWidth, nY + nHeight);
+ }
+ }
+ nCount--;
+} // end of wxToolBar::OnPaint
+
+void wxToolBar::OnSize (
+ wxSizeEvent& WXUNUSED(rEvent)
+)
{
- // TODO
- return wxSize(0, 0);
-}
+#if wxUSE_CONSTRAINTS
+ if (GetAutoLayout())
+ Layout();
+#endif
+} // end of wxToolBar::OnSize
-// The button size is bigger than the bitmap size
-wxSize wxToolBar::GetToolSize() const
+void wxToolBar::OnKillFocus(
+ wxFocusEvent& WXUNUSED(rEvent)
+)
{
- // TODO
- return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
-}
+ OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
+} // end of wxToolBar::OnKillFocus
-void wxToolBar::EnableTool(int toolIndex, bool enable)
+void wxToolBar::OnMouseEvent(
+ wxMouseEvent& rEvent
+)
{
- wxNode *node = m_tools.Find((long)toolIndex);
- if (node)
+ POINTL vPoint;
+ HWND hWnd;
+ wxCoord vX;
+ wxCoord vY;
+ HPOINTER hPtr = ::WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
+
+ ::WinSetPointer(HWND_DESKTOP, hPtr);
+ ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
+ hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
+ if (hWnd != (HWND)GetHwnd())
+ {
+ m_vToolTimer.Stop();
+ return;
+ }
+
+ rEvent.GetPosition(&vX, &vY);
+
+ wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
+ ,vY
+ );
+
+ if (rEvent.LeftDown())
+ {
+ CaptureMouse();
+ }
+ if (rEvent.LeftUp())
+ {
+ ReleaseMouse();
+ }
+
+ if (!pTool)
+ {
+ m_vToolTimer.Stop();
+ if (m_nCurrentTool > -1)
+ {
+ if (rEvent.LeftIsDown())
+ SpringUpButton(m_nCurrentTool);
+ pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
+ if (pTool && !pTool->IsToggled())
+ {
+ RaiseTool( pTool
+ ,FALSE
+ );
+ }
+ m_nCurrentTool = -1;
+ OnMouseEnter(-1);
+ }
+ return;
+ }
+ if (!rEvent.IsButton())
+ {
+ if (pTool->GetId() != m_nCurrentTool)
+ {
+ //
+ // If the left button is kept down and moved over buttons,
+ // press those buttons.
+ //
+ if (rEvent.LeftIsDown() && pTool->IsEnabled())
+ {
+ SpringUpButton(m_nCurrentTool);
+ if (pTool->CanBeToggled())
+ {
+ pTool->Toggle();
+ }
+ DrawTool(pTool);
+ }
+ wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
+
+ if (pOldTool && !pTool->IsToggled())
+ RaiseTool( pOldTool
+ ,FALSE
+ );
+ m_nCurrentTool = pTool->GetId();
+ OnMouseEnter(m_nCurrentTool);
+ if (!pTool->GetShortHelp().IsEmpty())
+ {
+ if (m_pToolTip)
+ delete m_pToolTip;
+ m_pToolTip = new wxToolTip(pTool->GetShortHelp());
+ m_vXMouse = (wxCoord)vPoint.x;
+ m_vYMouse = (wxCoord)vPoint.y;
+ m_vToolTimer.Start(1000L, TRUE);
+ }
+ if (!pTool->IsToggled())
+ RaiseTool(pTool);
+ }
+ return;
+ }
+
+ // Left button pressed.
+ if (rEvent.LeftDown() && pTool->IsEnabled())
+ {
+ if (pTool->CanBeToggled())
+ {
+ pTool->Toggle();
+ }
+ DrawTool(pTool);
+ }
+ else if (rEvent.RightDown())
+ {
+ OnRightClick( pTool->GetId()
+ ,vX
+ ,vY
+ );
+ }
+
+ //
+ // Left Button Released. Only this action confirms selection.
+ // If the button is enabled and it is not a toggle tool and it is
+ // in the pressed state, then raise the button and call OnLeftClick.
+ //
+ if (rEvent.LeftUp() && pTool->IsEnabled() )
+ {
+ //
+ // Pass the OnLeftClick event to tool
+ //
+ if (!OnLeftClick( pTool->GetId()
+ ,pTool->IsToggled()) &&
+ pTool->CanBeToggled())
+ {
+ //
+ // If it was a toggle, and OnLeftClick says No Toggle allowed,
+ // then change it back
+ //
+ pTool->Toggle();
+ }
+ DrawTool(pTool);
+ }
+} // end of wxToolBar::OnMouseEvent
+
+// ----------------------------------------------------------------------------
+// drawing
+// ----------------------------------------------------------------------------
+
+void wxToolBar::DrawTool(
+ wxToolBarToolBase* pTool
+)
+{
+ wxClientDC vDc(this);
+
+ DrawTool( vDc
+ ,pTool
+ );
+} // end of wxToolBar::DrawTool
+
+void wxToolBar::DrawTool(
+ wxDC& rDc
+, wxToolBarToolBase* pToolBase
+)
+{
+ wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
+ wxPen vDarkGreyPen( wxColour( 85,85,85 )
+ ,1
+ ,wxSOLID
+ );
+ wxPen vWhitePen( wxT("WHITE")
+ ,1
+ ,wxSOLID
+ );
+ wxPen vBlackPen( wxT("BLACK")
+ ,1
+ ,wxSOLID
+ );
+ wxBitmap vBitmap = pTool->GetNormalBitmap();
+ bool bUseMask = FALSE;
+ wxMask* pMask = NULL;
+
+ PrepareDC(rDc);
+
+ if (!vBitmap.Ok())
+ return;
+ if ((pMask = vBitmap.GetMask()) != NULL)
+ if (pMask->GetMaskBitmap() != NULLHANDLE)
+ bUseMask = TRUE;
+
+ if (!pTool->IsToggled())
+ {
+ LowerTool(pTool, FALSE);
+ if (!pTool->IsEnabled())
+ {
+ wxColour vColor(wxT("GREY"));
+
+ rDc.SetTextForeground(vColor);
+ if (!pTool->GetDisabledBitmap().Ok())
+ pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
+ ,(long)GetBackgroundColour().GetPixel()
+ ));
+ rDc.DrawBitmap( pTool->GetDisabledBitmap()
+ ,pTool->m_vX
+ ,pTool->m_vY
+ ,bUseMask
+ );
+ }
+ else
+ {
+ wxColour vColor(wxT("BLACK"));
+
+ rDc.SetTextForeground(vColor);
+ rDc.DrawBitmap( vBitmap
+ ,pTool->m_vX
+ ,pTool->m_vY
+ ,bUseMask
+ );
+ }
+ if (m_windowStyle & wxTB_3DBUTTONS)
+ {
+ RaiseTool(pTool);
+ }
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+ {
+ wxCoord vX;
+ wxCoord vY;
+ wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
+
+ rDc.SetFont(GetFont());
+ rDc.GetTextExtent( pTool->GetLabel()
+ ,&vX
+ ,&vY
+ );
+ if (pTool->GetWidth() > vX) // large tools
+ {
+ vLeft = pTool->m_vX + (pTool->GetWidth() - vX);
+ GetSize(&vX, &vY);
+ rDc.DrawText( pTool->GetLabel()
+ ,vLeft
+ ,vY - (m_vTextY - 2)
+ );
+ }
+ else // normal tools
+ {
+ vLeft += (wxCoord)((m_vTextX - vX)/2);
+ rDc.DrawText( pTool->GetLabel()
+ ,vLeft
+ ,pTool->m_vY + m_vTextY + 4 // a bit of margin
+ );
+ }
+ }
+ }
+ else
{
- wxToolBarTool *tool = (wxToolBarTool *)node->Data();
- tool->m_enabled = enable;
- // TODO enable button
+ wxColour vColor(wxT("GREY"));
+
+ LowerTool(pTool);
+ rDc.SetTextForeground(vColor);
+ if (!pTool->GetDisabledBitmap().Ok())
+ pTool->SetDisabledBitmap(wxDisableBitmap( vBitmap
+ ,(long)GetBackgroundColour().GetPixel()
+ ));
+ rDc.DrawBitmap( pTool->GetDisabledBitmap()
+ ,pTool->m_vX
+ ,pTool->m_vY
+ ,bUseMask
+ );
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
+ {
+ wxCoord vX;
+ wxCoord vY;
+ wxCoord vLeft = pTool->m_vX - (int)(pTool->GetWidth()/2);
+
+ rDc.SetFont(GetFont());
+ rDc.GetTextExtent( pTool->GetLabel()
+ ,&vX
+ ,&vY
+ );
+ vLeft += (wxCoord)((m_vTextX - vX)/2);
+ rDc.DrawText( pTool->GetLabel()
+ ,vLeft
+ ,pTool->m_vY + m_vTextY + 4 // a bit of margin
+ );
+ }
}
-}
+} // end of wxToolBar::DrawTool
+
+// ----------------------------------------------------------------------------
+// toolbar geometry
+// ----------------------------------------------------------------------------
+
+void wxToolBar::SetRows(
+ int nRows
+)
+{
+ wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
+
+ m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
+ Refresh();
+} // end of wxToolBar::SetRows
-void wxToolBar::ToggleTool(int toolIndex, bool toggle)
+wxToolBarToolBase* wxToolBar::FindToolForPosition(
+ wxCoord vX
+, wxCoord vY
+) const
{
- wxNode *node = m_tools.Find((long)toolIndex);
- if (node)
+ wxCoord vTBarHeight = 0;
+
+ GetSize( NULL
+ ,&vTBarHeight
+ );
+ vY = vTBarHeight - vY;
+ wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+ while (node)
{
- wxToolBarTool *tool = (wxToolBarTool *)node->Data();
- if (tool->m_isToggle)
+ wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
+
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
{
- tool->m_toggleState = toggle;
- // TODO: set toggle state
+ if ((vX >= (pTool->m_vX - ((wxCoord)(pTool->GetWidth()/2) - 2))) &&
+ (vY >= (pTool->m_vY - 2)) &&
+ (vX <= (pTool->m_vX + pTool->GetWidth())) &&
+ (vY <= (pTool->m_vY + pTool->GetHeight() + m_vTextY + 2)))
+ {
+ return pTool;
+ }
}
+ else
+ {
+ if ((vX >= pTool->m_vX) &&
+ (vY >= pTool->m_vY) &&
+ (vX <= (pTool->m_vX + pTool->GetWidth())) &&
+ (vY <= (pTool->m_vY + pTool->GetHeight())))
+ {
+ return pTool;
+ }
+ }
+ node = node->GetNext();
}
-}
+ return (wxToolBarToolBase *)NULL;
+} // end of wxToolBar::FindToolForPosition
+
+// ----------------------------------------------------------------------------
+// tool state change handlers
+// ----------------------------------------------------------------------------
+
+void wxToolBar::DoEnableTool(
+ wxToolBarToolBase* pTool
+, bool WXUNUSED(bEnable)
+)
+{
+ DrawTool(pTool);
+} // end of wxToolBar::DoEnableTool
+
+void wxToolBar::DoToggleTool(
+ wxToolBarToolBase* pTool
+, bool WXUNUSED(bToggle)
+)
+{
+ DrawTool(pTool);
+} // end of wxToolBar::DoToggleTool
+
+void wxToolBar::DoSetToggle(
+ wxToolBarToolBase* WXUNUSED(pTool)
+, bool WXUNUSED(bToggle)
+)
+{
+ // nothing to do
+} // end of wxToolBar::DoSetToggle
-void wxToolBar::ClearTools()
+//
+// Okay, so we've left the tool we're in ... we must check if the tool we're
+// leaving was a 'sprung push button' and if so, spring it back to the up
+// state.
+//
+void wxToolBar::SpringUpButton(
+ int vId
+)
{
- // TODO
- wxToolBarBase::ClearTools();
-}
+ wxToolBarToolBase* pTool = FindById(vId);
+
+ if (pTool && pTool->CanBeToggled())
+ {
+ if (pTool->IsToggled())
+ pTool->Toggle();
+
+ DrawTool(pTool);
+ }
+} // end of wxToolBar::SpringUpButton
-// 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.
+// ----------------------------------------------------------------------------
+// private helpers
+// ----------------------------------------------------------------------------
-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)
+void wxToolBar::LowerTool (
+ wxToolBarToolBase* pToolBase
+, bool bLower
+)
{
- wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2);
- tool->m_clientData = clientData;
+ wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
+ wxCoord vX;
+ wxCoord vY;
+ wxCoord vWidth;
+ wxCoord vHeight;
+ wxPen vDarkGreyPen( wxColour(85, 85, 85)
+ ,1
+ ,wxSOLID
+ );
+ wxPen vWhitePen( wxT("WHITE")
+ ,1
+ ,wxSOLID
+ );
+ wxPen vClearPen( GetBackgroundColour()
+ ,1
+ ,wxSOLID
+ );
+ wxClientDC vDC(this);
- if (xPos > -1)
- tool->m_x = xPos;
- else
- tool->m_x = m_xMargin;
+ if (!pTool)
+ return;
- if (yPos > -1)
- tool->m_y = yPos;
- else
- tool->m_y = m_yMargin;
+ if (pTool->IsSeparator())
+ return;
- tool->SetSize(GetDefaultButtonWidth(), GetDefaultButtonHeight());
+ //
+ // We only do this for flat toolbars
+ //
+ if (!HasFlag(wxTB_FLAT))
+ return;
- m_tools.Append((long)index, tool);
- return tool;
-}
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
+ {
+ if (pTool->GetWidth() > m_vTextX)
+ {
+ vX = pTool->m_vX - 2;
+ vWidth = pTool->GetWidth() + 4;
+ }
+ else
+ {
+ vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
+ vWidth = m_vTextX + 4;
+ }
+ vY = pTool->m_vY - 2;
+ vHeight = pTool->GetHeight() + m_vTextY + 2;
+ }
+ else
+ {
+ vX = pTool->m_vX - 2;
+ vY = pTool->m_vY - 2;
+ vWidth = pTool->GetWidth() + 4;
+ vHeight = pTool->GetHeight() + 4;
+ }
+ if (bLower)
+ {
+ vDC.SetPen(vWhitePen);
+ vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+ vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+ vDC.SetPen(vDarkGreyPen);
+ vDC.DrawLine(vX, vY, vX + vWidth, vY);
+ vDC.DrawLine(vX, vY + vHeight, vX, vY);
+ }
+ else
+ {
+ vDC.SetPen(vClearPen);
+ vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+ vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+ vDC.DrawLine(vX, vY, vX + vWidth, vY);
+ vDC.DrawLine(vX, vY + vHeight, vX, vY);
+ }
+} // end of WinGuiBase_CToolBarTool::LowerTool
+
+void wxToolBar::RaiseTool (
+ wxToolBarToolBase* pToolBase
+, bool bRaise
+)
+{
+ wxToolBarTool* pTool = (wxToolBarTool*)pToolBase;
+ wxCoord vX;
+ wxCoord vY;
+ wxCoord vWidth;
+ wxCoord vHeight;
+ wxPen vDarkGreyPen( wxColour(85, 85, 85)
+ ,1
+ ,wxSOLID
+ );
+ wxPen vWhitePen( wxT("WHITE")
+ ,1
+ ,wxSOLID
+ );
+ wxPen vClearPen( GetBackgroundColour()
+ ,1
+ ,wxSOLID
+ );
+ wxClientDC vDC(this);
+
+ if (!pTool)
+ return;
+
+ if (pTool->IsSeparator())
+ return;
+
+ if (!pTool->IsEnabled())
+ return;
+
+ //
+ // We only do this for flat toolbars
+ //
+ if (!HasFlag(wxTB_FLAT))
+ return;
+
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsEmpty())
+ {
+ if (pTool->GetWidth() > m_vTextX)
+ {
+ vX = pTool->m_vX - 2;
+ vWidth = pTool->GetWidth() + 4;
+ }
+ else
+ {
+ vX = pTool->m_vX - (wxCoord)(pTool->GetWidth()/2);
+ vWidth = m_vTextX + 4;
+ }
+ vY = pTool->m_vY - 2;
+ vHeight = pTool->GetHeight() + m_vTextY + 2;
+ }
+ else
+ {
+ vX = pTool->m_vX - 2;
+ vY = pTool->m_vY - 2;
+ vWidth = pTool->GetWidth() + 4;
+ vHeight = pTool->GetHeight() + 4;
+ }
+ if (bRaise)
+ {
+ vDC.SetPen(vDarkGreyPen);
+ vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+ vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+ vDC.SetPen(vWhitePen);
+ vDC.DrawLine(vX, vY, vX + vWidth, vY);
+ vDC.DrawLine(vX, vY + vHeight, vX, vY);
+ }
+ else
+ {
+ vDC.SetPen(vClearPen);
+ vDC.DrawLine(vX + vWidth, vY + vHeight, vX, vY + vHeight);
+ vDC.DrawLine(vX + vWidth, vY, vX + vWidth, vY + vHeight);
+ vDC.DrawLine(vX, vY, vX + vWidth, vY);
+ vDC.DrawLine(vX, vY + vHeight, vX, vY);
+ }
+} // end of wxToolBar::RaiseTool
+
+void wxToolBar::OnTimer (
+ wxTimerEvent& rEvent
+)
+{
+ if (rEvent.GetId() == m_vToolTimer.GetTimerId())
+ {
+ wxPoint vPos( m_vXMouse
+ ,m_vYMouse
+ );
+
+ m_pToolTip->DisplayToolTipWindow(vPos);
+ m_vToolTimer.Stop();
+ m_vToolExpTimer.Start(4000L, TRUE);
+ }
+ else if (rEvent.GetId() == m_vToolExpTimer.GetTimerId())
+ {
+ m_pToolTip->HideToolTipWindow();
+ GetParent()->Refresh();
+ m_vToolExpTimer.Stop();
+ }
+} // end of wxToolBar::OnTimer
+#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE