X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0e320a79f187558effb04d92020b470372bbe456..38c8fce8c4348a61a1e55da13142b84e44924845:/src/os2/toolbar.cpp diff --git a/src/os2/toolbar.cpp b/src/os2/toolbar.cpp index 3cb859e366..ea8d5f8480 100644 --- a/src/os2/toolbar.cpp +++ b/src/os2/toolbar.cpp @@ -1,145 +1,1204 @@ ///////////////////////////////////////////////////////////////////////////// // 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 -void wxToolBar::SetToolBitmapSize(const wxSize& size) +wxToolBar::~wxToolBar() { - m_defaultWidth = size.x; m_defaultHeight = size.y; - // TODO -} + if (m_pToolTip) + { + delete m_pToolTip; + m_pToolTip = NULL; + } +} // end of wxToolBar::~wxToolBar -wxSize wxToolBar::GetMaxSize() const +bool wxToolBar::Realize() { - // TODO - return wxSize(0, 0); -} + 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(); -// The button size is bigger than the bitmap size -wxSize wxToolBar::GetToolSize() const + while (node ) + { + wxToolBarTool* pTool = (wxToolBarTool *)node->GetData(); + + if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty()) + { + // + // 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::OnPaint ( + wxPaintEvent& WXUNUSED(rEvent) +) { - // TODO - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); -} + wxPaintDC vDc(this); + + PrepareDC(vDc); -void wxToolBar::EnableTool(int toolIndex, bool enable) + 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()) + { + wxColour gray85(85, 85, 85); + wxPen vDarkGreyPen( gray85, 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) +) +{ +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif +} // end of wxToolBar::OnSize + +void wxToolBar::OnKillFocus( + wxFocusEvent& WXUNUSED(rEvent) +) +{ + OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1); +} // end of wxToolBar::OnKillFocus + +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()) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_enabled = enable; - // TODO enable button + 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().empty()) + { + 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; } -} -void wxToolBar::ToggleTool(int toolIndex, bool toggle) + // 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 +) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) + wxToolBarTool* pTool = (wxToolBarTool *)pToolBase; + wxColour gray85( 85,85,85 ); + wxPen vDarkGreyPen( gray85, 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()) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) + LowerTool(pTool, FALSE); + if (!pTool->IsEnabled()) { - tool->m_toggleState = toggle; - // TODO: set toggle state + 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 + { + rDc.SetTextForeground(*wxBLACK); + 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 + { + 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::ClearTools() +void wxToolBar::SetRows( + int nRows +) { - // TODO - wxToolBarBase::ClearTools(); -} + wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") ); -// 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. + m_maxCols = (GetToolsCount() + nRows - 1) / nRows; + Refresh(); +} // end of wxToolBar::SetRows -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) +wxToolBarToolBase* wxToolBar::FindToolForPosition( + wxCoord vX +, wxCoord vY +) const { - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2); - tool->m_clientData = clientData; + wxCoord vTBarHeight = 0; - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; + GetSize( NULL + ,&vTBarHeight + ); + vY = vTBarHeight - vY; + wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); + while (node) + { + wxToolBarTool* pTool = (wxToolBarTool *)node->GetData(); + + if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull()) + { + 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 + +// +// 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 +) +{ + wxToolBarToolBase* pTool = FindById(vId); + + if (pTool && pTool->CanBeToggled()) + { + if (pTool->IsToggled()) + pTool->Toggle(); + + DrawTool(pTool); + } +} // end of wxToolBar::SpringUpButton + +// ---------------------------------------------------------------------------- +// private helpers +// ---------------------------------------------------------------------------- + +void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase, + bool bLower ) +{ + wxToolBarTool* pTool = (wxToolBarTool*)pToolBase; + wxCoord vX; + wxCoord vY; + wxCoord vWidth; + wxCoord vHeight; + wxColour gray85( 85,85,85 ); + wxPen vDarkGreyPen( gray85, 1, wxSOLID ); + wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID ); + wxClientDC vDC(this); + + if (!pTool) + return; + + if (pTool->IsSeparator()) + return; + + // + // We only do this for flat toolbars + // + if (!HasFlag(wxTB_FLAT)) + return; + + if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty()) + { + 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(*wxWHITE_PEN); + 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 - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; +void wxToolBar::RaiseTool ( wxToolBarToolBase* pToolBase, + bool bRaise ) +{ + wxToolBarTool* pTool = (wxToolBarTool*)pToolBase; + wxCoord vX; + wxCoord vY; + wxCoord vWidth; + wxCoord vHeight; + wxColour gray85( 85,85,85 ); + wxPen vDarkGreyPen( gray85, 1, wxSOLID ); + wxPen vClearPen( GetBackgroundColour(), 1, wxSOLID ); + wxClientDC vDC(this); + + if (!pTool) + return; + + if (pTool->IsSeparator()) + return; + + if (!pTool->IsEnabled()) + 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().empty()) + { + 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(*wxWHITE_PEN); + 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