// Purpose: wxToolBar
// Author: David Webster
// Modified by:
-// Created: 10/17/99
+// Created: 06/30/02
// RCS-ID: $Id$
// Copyright: (c) David Webster
// Licence: wxWindows licence
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
-#ifndef WX_PRECOMP
-#include "wx/wx.h"
-#endif
-
#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
-#include "wx/toolbar.h"
-
-#include "malloc.h"
-#include "wx/os2/private.h"
-
-#include "wx/app.h" // for GetComCtl32Version
-
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
-
-// these standard constants are not always defined in compilers headers
-
-// Styles
-#ifndef TBSTYLE_FLAT
- #define TBSTYLE_LIST 0x1000
- #define TBSTYLE_FLAT 0x0800
- #define TBSTYLE_TRANSPARENT 0x8000
-#endif
- // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT
-// Messages
-#ifndef TB_GETSTYLE
- #define TB_SETSTYLE (WM_USER + 56)
- #define TB_GETSTYLE (WM_USER + 57)
-#endif
-
-#ifndef TB_HITTEST
- #define TB_HITTEST (WM_USER + 69)
+#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
-// these values correspond to those used by comctl32.dll
-#define DEFAULTBITMAPX 16
-#define DEFAULTBITMAPY 15
-#define DEFAULTBUTTONX 24
-#define DEFAULTBUTTONY 24
-#define DEFAULTBARHEIGHT 27
-
-// ----------------------------------------------------------------------------
-// private function prototypes
-// ----------------------------------------------------------------------------
-
-static void wxMapBitmap( HBITMAP hBitmap
- ,int nWidth
- ,int nHeight
- );
-
-// ----------------------------------------------------------------------------
-// wxWin macros
-// ----------------------------------------------------------------------------
-
-IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
+#include "wx/tooltip.h"
+#include "wx/toolbar.h"
-BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
- EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
- EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged)
-END_EVENT_TABLE()
+bool wxToolBar::m_bInitialized = FALSE;
// ----------------------------------------------------------------------------
// private classes
public:
inline wxToolBarTool( wxToolBar* pTbar
,int vId
+ ,const wxString& rsLabel
,const wxBitmap& rBitmap1
,const wxBitmap& rBitmap2
- ,bool bToggle
+ ,wxItemKind vKind
,wxObject* pClientData
- ,const wxString& rShortHelpString
- ,const wxString& rLongHelpString
+ ,const wxString& rsShortHelpString
+ ,const wxString& rsLongHelpString
) : wxToolBarToolBase( pTbar
,vId
+ ,rsLabel
,rBitmap1
,rBitmap2
- ,bToggle
+ ,vKind
,pClientData
- ,rShortHelpString
- ,rLongHelpString
+ ,rsShortHelpString
+ ,rsLongHelpString
)
{
- m_nSepCount = 0;
}
inline wxToolBarTool( wxToolBar* pTbar
,pControl
)
{
- m_nSepCount = 1;
}
- // set/get the number of separators which we use to cover the space used by
- // a control in the toolbar
- inline void SetSeparatorsCount(size_t nCount) { m_nSepCount = nCount; }
- inline size_t GetSeparatorsCount(void) const { return m_nSepCount; }
+ 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
+// ----------------------------------------------------------------------------
-private:
- size_t m_nSepCount;
-};
+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()
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
-// wxToolBarTool
+// tool bar tools creation
// ----------------------------------------------------------------------------
wxToolBarToolBase* wxToolBar::CreateTool(
int nId
-, const wxBitmap& rBitmap1
-, const wxBitmap& rBitmap2
-, bool bToggle
+, const wxString& rsLabel
+, const wxBitmap& rBmpNormal
+, const wxBitmap& rBmpDisabled
+, wxItemKind eKind
, wxObject* pClientData
-, const wxString& rShortHelpString
-, const wxString& rLongHelpString
+, const wxString& rsShortHelp
+, const wxString& rsLongHelp
)
{
- return(new wxToolBarTool( this
+ return new wxToolBarTool( this
,nId
- ,rBitmap1
- ,rBitmap2
- ,bToggle
+ ,rsLabel
+ ,rBmpNormal
+ ,rBmpDisabled
+ ,eKind
,pClientData
- ,rShortHelpString
- ,rLongHelpString
- ));
-}
+ ,rsShortHelp
+ ,rsLongHelp
+ );
+} // end of wxToolBarSimple::CreateTool
-wxToolBarToolBase* wxToolBar::CreateTool(
+wxToolBarToolBase *wxToolBar::CreateTool(
wxControl* pControl
)
{
- return(new wxToolBarTool( this
+ return new wxToolBarTool( this
,pControl
- ));
-}
+ );
+} // end of wxToolBarSimple::CreateTool
// ----------------------------------------------------------------------------
-// wxToolBar construction
+// wxToolBarSimple creation
// ----------------------------------------------------------------------------
void wxToolBar::Init()
{
- m_hBitmap = 0;
- m_nButtons = 0;
- m_defaultWidth = DEFAULTBITMAPX;
- m_defaultHeight = DEFAULTBITMAPY;
-}
-
-bool wxToolBar::Create(
- wxWindow* pParent
-, wxWindowID vId
-, const wxPoint& rPos
-, const wxSize& rSize
-, long lStyle
-, const wxString& rName
+ m_nCurrentRowsOrColumns = 0;
+
+ 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;
+
+ m_toolPacking = 1;
+ m_toolSeparation = 5;
+
+ 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
+)
+{
+ //
+ // Rememeber the position for DoInsertTool()
+ //
+ m_vXPos = vXPos;
+ m_vYPos = vYPos;
+
+ return wxToolBarBase::DoAddTool( vId
+ ,rsLabel
+ ,rBitmap
+ ,rBmpDisabled
+ ,eKind
+ ,rsShortHelp
+ ,rsLongHelp
+ ,pClientData
+ ,vXPos
+ ,vYPos
+ );
+} // end of wxToolBar::DoAddTool
+
+bool wxToolBar::DeleteTool(
+ int nId
)
{
- // common initialisation
- if (!CreateControl( pParent
- ,vId
- ,rPos
- ,rSize
- ,lStyle
- , wxDefaultValidator
- ,rName
- ))
- return(FALSE);
-
- // prepare flags
- DWORD msflags = 0; // WS_VISIBLE | WS_CHILD always included
- // TODO
- /*
-
- if (lStyle & wxBORDER)
- msflags |= WS_BORDER;
- msflags |= TBSTYLE_TOOLTIPS;
-
- if (style & wxTB_FLAT)
+ bool bOk = wxToolBarBase::DeleteTool(nId);
+
+ if (bOk)
{
- if (wxTheApp->GetComCtl32Version() > 400)
- msflags |= TBSTYLE_FLAT;
+ Realize();
}
+ return bOk;
+} // end of wxToolBar::DeleteTool
- // MSW-specific initialisation
- if ( !wxControl::MSWCreateControl(TOOLBARCLASSNAME, msflags) )
- return FALSE;
-
- // toolbar-specific post initialisation
- ::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
-
- // set up the colors and fonts
- wxRGBToColour(m_backgroundColour, GetSysColor(COLOR_BTNFACE));
- m_foregroundColour = *wxBLACK;
+bool wxToolBar::DeleteToolByPos(
+ size_t nPos
+)
+{
+ bool bOk = wxToolBarBase::DeleteToolByPos(nPos);
- SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
+ if (bOk)
+ {
+ Realize();
+ }
+ return bOk;
+} // end of wxToolBar::DeleteTool
- // position it
- int x = pos.x;
- int y = pos.y;
- int width = size.x;
- int height = size.y;
+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
- if (width <= 0)
- width = 100;
- if (height <= 0)
- height = m_defaultHeight;
- if (x < 0)
- x = 0;
- if (y < 0)
- y = 0;
+wxToolBarToolBase* wxToolBar::InsertSeparator(
+ size_t nPos
+)
+{
+ wxToolBarToolBase* pTool = wxToolBarBase::InsertSeparator(nPos);
- SetSize(x, y, width, height);
- */
- return(TRUE);
-}
+ if (m_bInitialized)
+ {
+ Realize();
+ Refresh();
+ }
+ return pTool;
+} // end of wxToolBar::InsertSeparator
-wxToolBar::~wxToolBar()
+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
+)
{
- if (m_hBitmap)
+ wxToolBarToolBase* pTool = wxToolBarBase::InsertTool( nPos
+ ,nId
+ ,rsLabel
+ ,rBitmap
+ ,rBmpDisabled
+ ,eKind
+ ,rsShortHelp
+ ,rsLongHelp
+ ,pClientData
+ );
+ if (m_bInitialized)
{
- ::GpiDeleteBitmap((HBITMAP) m_hBitmap);
+ Realize();
+ Refresh();
}
-}
-
-// ----------------------------------------------------------------------------
-// adding/removing tools
-// ----------------------------------------------------------------------------
+ return pTool;
+} // end of wxToolBar::InsertTool
bool wxToolBar::DoInsertTool(
size_t WXUNUSED(nPos)
-, wxToolBarToolBase* pTool
+, wxToolBarToolBase* pToolBase
)
{
- // nothing special to do here - we really create the toolbar buttons in
- // Realize() later
- pTool->Attach(this);
- return(TRUE);
-}
+ 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 nPos
+ size_t WXUNUSED(nPos)
, wxToolBarToolBase* pTool
)
{
- // normally, we only delete one button, but we use several separators to
- // cover the space used by one control sometimes (with old comctl32.dll)
- size_t nButtonsToDelete = 1;
+ pTool->Detach();
+ Refresh();
+ return TRUE;
+} // end of wxToolBar::DoDeleteTool
- // get the size of the button we're going to delete
- RECTL vRect;
+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;
+
+ // Set it to grey (or other 3D face colour)
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
+ SetFont(*wxSMALL_FONT);
- // TODO:
- /*
- if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) )
+ if (GetWindowStyleFlag() & wxTB_VERTICAL)
{
- wxLogLastError(_T("TB_GETITEMRECT"));
- }
+ m_vLastX = 7;
+ m_vLastY = 3;
- int width = r.right - r.left;
+ m_maxRows = 32000; // a lot
+ m_maxCols = 1;
+ }
+ else
+ {
+ m_vLastX = 3;
+ m_vLastY = 7;
- if ( tool->IsControl() )
+ 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))
{
- nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
+ wxClientDC vDC(this);
- width *= nButtonsToDelete;
+ vDC.SetFont(GetFont());
+ vDC.GetTextExtent( wxT("XXXX")
+ ,&m_vTextX
+ ,&m_vTextY
+ );
}
- while ( nButtonsToDelete-- > 0 )
+ //
+ // Position it
+ //
+ int nX = rPos.x;
+ int nY = rPos.y;
+ int nWidth = rSize.x;
+ int nHeight = rSize.y;
+
+ if (lStyle & wxTB_HORIZONTAL)
{
- if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) )
+ if (nWidth <= 0)
{
- wxLogLastError("TB_DELETEBUTTON");
-
- return FALSE;
+ nWidth = pParent->GetClientSize().x;
+ }
+ if (nHeight <= 0)
+ {
+ if (lStyle & wxTB_TEXT)
+ nHeight = m_defaultHeight + m_vTextY;
+ else
+ nHeight = m_defaultHeight;
}
}
-
- tool->Detach();
-
- m_nButtons -= nButtonsToDelete;
-
- // reposition all the controls after this button
- wxToolBarToolsList::Node *node = m_tools.Item(pos);
- for ( node = node->GetNext(); node; node = node->GetNext() )
+ else
{
- wxToolBarToolBase *tool2 = node->GetData();
- if ( tool2->IsControl() )
+ if (nHeight <= 0)
+ {
+ nHeight = pParent->GetClientSize().y;
+ }
+ if (nWidth <= 0)
{
- int x;
- wxControl *control = tool2->GetControl();
- control->GetPosition(&x, NULL);
- control->Move(x - width, -1);
+ 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
}
}
- */
- return(TRUE);
-}
+ if (nX < 0)
+ nX = 0;
+ if (nY < 0)
+ nY = 0;
+
+ SetSize( nX
+ ,nY
+ ,nWidth
+ ,nHeight
+ );
+ return TRUE;
+} // end of wxToolBar::Create
-bool wxToolBar::Realize()
+wxToolBar::~wxToolBar()
{
- size_t nTools = GetToolsCount();
-
- if (nTools == 0)
+ if (m_pToolTip)
{
- // nothing to do
- return(TRUE);
+ delete m_pToolTip;
+ m_pToolTip = NULL;
}
+} // end of wxToolBar::~wxToolBar
- bool bIsVertical = (GetWindowStyle() & wxTB_VERTICAL) != 0;
+bool wxToolBar::Realize()
+{
+ int nMaxToolWidth = 0;
+ int nMaxToolHeight = 0;
- // TODO:
- /*
- // First, add the bitmap: we use one bitmap for all toolbar buttons
- // ----------------------------------------------------------------
+ m_nCurrentRowsOrColumns = 0;
+ m_vLastX = m_xMargin;
+ m_vLastY = m_yMargin;
+ m_vMaxWidth = 0;
+ m_vMaxHeight = 0;
- // if we already have a bitmap, we'll replace the existing one - otherwise
- // we'll install a new one
- HBITMAP oldToolBarBitmap = (HBITMAP)m_hBitmap;
- int totalBitmapWidth = (int)(m_defaultWidth * nTools);
- int totalBitmapHeight = (int)m_defaultHeight;
+ //
+ // Find the maximum tool width and height
+ //
+ wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
- // Create a bitmap for all the tool bitmaps
- HBITMAP hBitmap = ::CreateCompatibleBitmap(ScreenHDC(),
- totalBitmapWidth,
- totalBitmapHeight);
- if ( !hBitmap )
+ while (node )
{
- wxLogLastError(_T("CreateCompatibleBitmap"));
+ wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
- return FALSE;
+ 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();
}
- m_hBitmap = (WXHBITMAP)hBitmap;
-
- // Now blit all the tools onto this bitmap
- HDC memoryDC = ::CreateCompatibleDC(NULL);
- HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, hBitmap);
+ wxCoord vTbWidth = 0L;
+ wxCoord vTbHeight = 0L;
- HDC memoryDC2 = ::CreateCompatibleDC(NULL);
+ GetSize( &vTbWidth
+ ,&vTbHeight
+ );
+ if (vTbHeight < nMaxToolHeight)
+ {
+ SetSize( -1L
+ ,-1L
+ ,vTbWidth
+ ,nMaxToolHeight + 4
+ );
+ if (GetParent()->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
- // the button position
- wxCoord x = 0;
+ if (pFrame)
+ pFrame->PositionToolBar();
+ }
+ }
- // the number of buttons (not separators)
- int nButtons = 0;
+ int nSeparatorSize = m_toolSeparation;
- wxToolBarToolsList::Node *node = m_tools.GetFirst();
- while ( node )
+ node = m_tools.GetFirst();
+ while (node)
{
- wxToolBarToolBase *tool = node->GetData();
- if ( tool->IsButton() )
+ wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
+
+ if (pTool->IsSeparator())
{
- HBITMAP hbmp = GetHbitmapOf(tool->GetBitmap1());
- if ( hbmp )
+ if (GetWindowStyleFlag() & wxTB_HORIZONTAL)
{
- HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp);
- if ( !BitBlt(memoryDC, x, 0, m_defaultWidth, m_defaultHeight,
- memoryDC2, 0, 0, SRCCOPY) )
- {
- wxLogLastError("BitBlt");
- }
-
- ::SelectObject(memoryDC2, oldBitmap2);
+ 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
{
- wxFAIL_MSG( _T("invalid tool button bitmap") );
+ 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;
}
-
- // still inc width and number of buttons because otherwise the
- // subsequent buttons will all be shifted which is rather confusing
- // (and like this you'd see immediately which bitmap was bad)
- x += m_defaultWidth;
- nButtons++;
}
-
- node = node->GetNext();
- }
-
- ::SelectObject(memoryDC, oldBitmap);
- ::DeleteDC(memoryDC);
- ::DeleteDC(memoryDC2);
-
- // Map to system colours
- wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight);
-
- if ( oldToolBarBitmap )
- {
- TBREPLACEBITMAP replaceBitmap;
- replaceBitmap.hInstOld = NULL;
- replaceBitmap.hInstNew = NULL;
- replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
- replaceBitmap.nIDNew = (UINT) hBitmap;
- replaceBitmap.nButtons = nButtons;
- if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
- 0, (LPARAM) &replaceBitmap) )
- {
- wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
- }
-
- ::DeleteObject(oldToolBarBitmap);
-
- // Now delete all the buttons
- for ( size_t pos = 0; pos < m_nButtons; pos++ )
+ else if (pTool->IsButton())
{
- if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) )
+ 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
{
- wxLogLastError("TB_DELETEBUTTON");
+ 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 // no old bitmap
- {
- TBADDBITMAP addBitmap;
- addBitmap.hInst = 0;
- addBitmap.nID = (UINT) hBitmap;
- if ( ::SendMessage(GetHwnd(), TB_ADDBITMAP,
- (WPARAM) nButtons, (LPARAM)&addBitmap) == -1 )
+ else
{
- wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
+ // 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();
}
- // Next add the buttons and separators
- // -----------------------------------
+ if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+ m_maxWidth += nMaxToolWidth;
+ else
+ m_maxHeight += nMaxToolHeight;
- TBBUTTON *buttons = new TBBUTTON[nTools];
+ m_maxWidth += m_xMargin;
+ m_maxHeight += m_yMargin;
+ m_bInitialized = TRUE;
+ return TRUE;
+} // end of wxToolBar::Realize
- // this array will hold the indices of all controls in the toolbar
- wxArrayInt controlIds;
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
- int i = 0;
- int bitmapId = 0;
+void wxToolBar::OnPaint (
+ wxPaintEvent& WXUNUSED(rEvent)
+)
+{
+ wxPaintDC vDc(this);
- for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
- {
- wxToolBarToolBase *tool = node->GetData();
+ PrepareDC(vDc);
- // don't add separators to the vertical toolbar - looks ugly
- if ( isVertical && tool->IsSeparator() )
- continue;
+ static int nCount = 0;
- TBBUTTON& button = buttons[i];
+ //
+ // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
+ //
+ if (nCount > 0)
+ return;
+ nCount++;
- wxZeroMemory(button);
+ ::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();
- switch ( tool->GetStyle() )
+ if (pTool->IsButton() )
+ DrawTool(vDc, pTool);
+ if (pTool->IsSeparator())
{
- case wxTOOL_STYLE_CONTROL:
- button.idCommand = tool->GetId();
- // fall through: create just a separator too
+ 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
- case wxTOOL_STYLE_SEPARATOR:
- button.fsState = TBSTATE_ENABLED;
- button.fsStyle = TBSTYLE_SEP;
- break;
+void wxToolBar::OnSize (
+ wxSizeEvent& WXUNUSED(rEvent)
+)
+{
+#if wxUSE_CONSTRAINTS
+ if (GetAutoLayout())
+ Layout();
+#endif
+} // end of wxToolBar::OnSize
- case wxTOOL_STYLE_BUTTON:
- button.iBitmap = bitmapId;
- button.idCommand = tool->GetId();
+void wxToolBar::OnKillFocus(
+ wxFocusEvent& WXUNUSED(rEvent)
+)
+{
+ OnMouseEnter(m_nPressedTool = m_nCurrentTool = -1);
+} // end of wxToolBar::OnKillFocus
- if ( tool->IsEnabled() )
- button.fsState |= TBSTATE_ENABLED;
- if ( tool->IsToggled() )
- button.fsState |= TBSTATE_CHECKED;
+void wxToolBar::OnMouseEvent(
+ wxMouseEvent& rEvent
+)
+{
+ 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;
+ }
- button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK
- : TBSTYLE_BUTTON;
+ rEvent.GetPosition(&vX, &vY);
- bitmapId++;
- break;
- }
+ wxToolBarTool* pTool = (wxToolBarTool *)FindToolForPosition( vX
+ ,vY
+ );
- i++;
+ if (rEvent.LeftDown())
+ {
+ CaptureMouse();
}
-
- if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS,
- (WPARAM)i, (LPARAM)buttons) )
+ if (rEvent.LeftUp())
{
- wxLogLastError("TB_ADDBUTTONS");
+ ReleaseMouse();
}
- delete [] buttons;
-
- // Deal with the controls finally
- // ------------------------------
-
- // adjust the controls size to fit nicely in the toolbar
- size_t index = 0;
- for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
+ if (!pTool)
{
- wxToolBarToolBase *tool = node->GetData();
- if ( !tool->IsControl() )
- continue;
-
- wxControl *control = tool->GetControl();
-
- wxSize size = control->GetSize();
-
- // the position of the leftmost controls corner
- int left = -1;
-
- // note that we use TB_GETITEMRECT and not TB_GETRECT because the
- // latter only appeared in v4.70 of comctl32.dll
- RECT r;
- if ( !SendMessage(GetHwnd(), TB_GETITEMRECT,
- index, (LPARAM)(LPRECT)&r) )
+ m_vToolTimer.Stop();
+ if (m_nCurrentTool > -1)
{
- wxLogLastError("TB_GETITEMRECT");
+ if (rEvent.LeftIsDown())
+ SpringUpButton(m_nCurrentTool);
+ pTool = (wxToolBarTool *)FindById(m_nCurrentTool);
+ if (pTool && !pTool->IsToggled())
+ {
+ RaiseTool( pTool
+ ,FALSE
+ );
+ }
+ m_nCurrentTool = -1;
+ OnMouseEnter(-1);
}
-
- // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
- #if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
- // available in headers, now check whether it is available now
- // (during run-time)
- if ( wxTheApp->GetComCtl32Version() >= 471 )
+ 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())
{
- // set the (underlying) separators width to be that of the
- // control
- TBBUTTONINFO tbbi;
- tbbi.cbSize = sizeof(tbbi);
- tbbi.dwMask = TBIF_SIZE;
- tbbi.cx = size.x;
- if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
- tool->GetId(), (LPARAM)&tbbi) )
+ SpringUpButton(m_nCurrentTool);
+ if (pTool->CanBeToggled())
{
- // the id is probably invalid?
- wxLogLastError("TB_SETBUTTONINFO");
+ pTool->Toggle();
}
-
+ DrawTool(pTool);
}
- else
- #endif // comctl32.dll 4.71
- // TB_SETBUTTONINFO unavailable
+ wxToolBarTool* pOldTool = (wxToolBarTool*)FindById(m_nCurrentTool);
+
+ if (pOldTool && !pTool->IsToggled())
+ RaiseTool( pOldTool
+ ,FALSE
+ );
+ m_nCurrentTool = pTool->GetId();
+ OnMouseEnter(m_nCurrentTool);
+ if (!pTool->GetShortHelp().empty())
{
- // try adding several separators to fit the controls width
- int widthSep = r.right - r.left;
- left = r.left;
-
- TBBUTTON tbb;
- wxZeroMemory(tbb);
- tbb.idCommand = 0;
- tbb.fsState = TBSTATE_ENABLED;
- tbb.fsStyle = TBSTYLE_SEP;
-
- size_t nSeparators = size.x / widthSep;
- for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
- {
- if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON,
- index, (LPARAM)&tbb) )
- {
- wxLogLastError("TB_INSERTBUTTON");
- }
-
- index++;
- }
-
- // remember the number of separators we used - we'd have to
- // delete all of them later
- ((wxToolBarTool *)tool)->SetSeparatorsCount(nSeparators);
-
- // adjust the controls width to exactly cover the separators
- control->SetSize((nSeparators + 1)*widthSep, -1);
+ 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);
}
-
- // and position the control itself correctly vertically
- int height = r.bottom - r.top;
- int diff = height - size.y;
- if ( diff < 0 )
- {
- // the control is too high, resize to fit
- control->SetSize(-1, height - 2);
-
- diff = 2;
+ if (!pTool->IsToggled())
+ RaiseTool(pTool);
}
-
- control->Move(left == -1 ? r.left : left, r.top + (diff + 1) / 2);
+ return;
}
- // the max index is the "real" number of buttons - i.e. counting even the
- // separators which we added just for aligning the controls
- m_nButtons = index;
-
- if ( !isVertical )
+ // Left button pressed.
+ if (rEvent.LeftDown() && pTool->IsEnabled())
{
- if ( m_maxRows == 0 )
+ if (pTool->CanBeToggled())
{
- // if not set yet, only one row
- SetRows(1);
+ pTool->Toggle();
}
+ DrawTool(pTool);
}
- else if ( m_nButtons > 0 ) // vertical non empty toolbar
+ else if (rEvent.RightDown())
{
- if ( m_maxRows == 0 )
+ 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 not set yet, have one column
- SetRows(m_nButtons);
+ //
+ // If it was a toggle, and OnLeftClick says No Toggle allowed,
+ // then change it back
+ //
+ pTool->Toggle();
}
+ DrawTool(pTool);
}
- */
- return TRUE;
-}
+} // end of wxToolBar::OnMouseEvent
// ----------------------------------------------------------------------------
-// message handlers
+// drawing
// ----------------------------------------------------------------------------
-bool wxToolBar::OS2Command(
- WXUINT nCmd
-, WXWORD nId
+void wxToolBar::DrawTool(
+ wxToolBarToolBase* pTool
)
{
- wxToolBarToolBase* pTool = FindById((int)nId);
-
- if (!pTool)
- return(FALSE);
- // TODO:
- /*
- if (pTool->CanBeToggled())
- {
- LRESULT state = ::SendMessage(GetHwnd(), TB_GETSTATE, id, 0);
- tool->SetToggle((state & TBSTATE_CHECKED) != 0);
- }
-
- bool toggled = tool->IsToggled();
+ wxClientDC vDc(this);
- // OnLeftClick() can veto the button state change - for buttons which may
- // be toggled only, of couse
- if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() )
- {
- // revert back
- toggled = !toggled;
- tool->SetToggle(toggled);
+ DrawTool( vDc
+ ,pTool
+ );
+} // end of wxToolBar::DrawTool
- ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0));
- }
- */
- return(TRUE);
-}
-
-bool wxToolBar::OS2OnNotify(
- int WXUNUSED(idCtrl)
-, WXLPARAM lParam
-, WXLPARAM* pResult
+void wxToolBar::DrawTool(
+ wxDC& rDc
+, wxToolBarToolBase* pToolBase
)
{
- // TODO:
- /*
- // First check if this applies to us
- NMHDR *hdr = (NMHDR *)lParam;
-
- // the tooltips control created by the toolbar is sometimes Unicode, even
- // in an ANSI application - this seems to be a bug in comctl32.dll v5
- int code = (int)hdr->code;
- if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) )
- return FALSE;
-
- HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
- if ( toolTipWnd != hdr->hwndFrom )
- return FALSE;
-
- LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
- int id = (int)ttText->hdr.idFrom;
+ wxToolBarTool* pTool = (wxToolBarTool *)pToolBase;
+ wxColour gray85( 85,85,85 );
+ wxPen vDarkGreyPen( gray85, 1, wxSOLID );
+ wxBitmap vBitmap = pTool->GetNormalBitmap();
+ bool bUseMask = FALSE;
+ wxMask* pMask = NULL;
- wxToolBarToolBase *tool = FindById(id);
- if ( !tool )
- return FALSE;
+ PrepareDC(rDc);
- const wxString& help = tool->GetShortHelp();
+ if (!vBitmap.Ok())
+ return;
+ if ((pMask = vBitmap.GetMask()) != NULL)
+ if (pMask->GetMaskBitmap() != NULLHANDLE)
+ bUseMask = TRUE;
- if ( !help.IsEmpty() )
+ if (!pTool->IsToggled())
{
- if ( code == TTN_NEEDTEXTA )
+ LowerTool(pTool, FALSE);
+ if (!pTool->IsEnabled())
{
- ttText->lpszText = (wxChar *)help.c_str();
+ 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
+ );
}
-#if (_WIN32_IE >= 0x0300)
else
{
- // FIXME this is a temp hack only until I understand better what
- // must be done in both ANSI and Unicode builds
-
- size_t lenAnsi = help.Len();
- #ifdef __MWERKS__
- // MetroWerks doesn't like calling mbstowcs with NULL argument
- size_t lenUnicode = 2*lenAnsi;
- #else
- size_t lenUnicode = mbstowcs(NULL, help, lenAnsi);
- #endif
-
- // using the pointer of right type avoids us doing all sorts of
- // pointer arithmetics ourselves
- wchar_t *dst = (wchar_t *)ttText->szText,
- *pwz = new wchar_t[lenUnicode + 1];
- mbstowcs(pwz, help, lenAnsi + 1);
- memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
-
- // put the terminating _wide_ NUL
- dst[lenUnicode] = 0;
-
- delete [] pwz;
+ 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
+ );
+ }
}
-#endif // _WIN32_IE >= 0x0300
}
-
- // For backward compatibility...
- OnMouseEnter(tool->GetId());
- */
- return(TRUE);
-}
+ 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::SetToolBitmapSize(
- const wxSize& rSize
-)
-{
- wxToolBarBase::SetToolBitmapSize(rSize);
-
- // ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y));
-}
-
void wxToolBar::SetRows(
int nRows
)
{
- if (nRows == m_maxRows)
- {
- // avoid resizing the frame uselessly
- return;
- }
- // TODO:
- /*
- // TRUE in wParam means to create at least as many rows, FALSE -
- // at most as many
- RECT rect;
- ::SendMessage(GetHwnd(), TB_SETROWS,
- MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)),
- (LPARAM) &rect);
-
- m_maxRows = nRows;
-
- UpdateSize();
- */
-}
-
-// The button size is bigger than the bitmap size
-wxSize wxToolBar::GetToolSize() const
-{
- // TODO:
- /*
- // TB_GETBUTTONSIZE is supported from version 4.70
-#if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 )
- if ( wxTheApp->GetComCtl32Version() >= 470 )
- {
- DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0);
+ wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") );
- return wxSize(LOWORD(dw), HIWORD(dw));
- }
- else
-#endif // comctl32.dll 4.70+
- {
- // defaults
- return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
- }
- */
- return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
-}
+ m_maxCols = (GetToolsCount() + nRows - 1) / nRows;
+ Refresh();
+} // end of wxToolBar::SetRows
-wxToolBarToolBase *wxToolBar::FindToolForPosition(
+wxToolBarToolBase* wxToolBar::FindToolForPosition(
wxCoord vX
, wxCoord vY
) const
{
- POINTL vPt;
-
- vPt.x = vX;
- vPt.y = vY;
-
- int nIndex = 0; //(int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt);
- if (nIndex < 0)
+ wxCoord vTBarHeight = 0;
+
+ GetSize( NULL
+ ,&vTBarHeight
+ );
+ vY = vTBarHeight - vY;
+ wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+ while (node)
{
- // it's a separator or there is no tool at all there
- return (wxToolBarToolBase *)NULL;
- }
- return(m_tools.Item((size_t)nIndex)->GetData());
-}
-
-void wxToolBar::UpdateSize()
-{
- // we must refresh the frame after the toolbar size (possibly) changed
- wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
+ wxToolBarTool* pTool = (wxToolBarTool *)node->GetData();
- if (pFrame)
- {
- // don't change the size, we just need to generate a WM_SIZE
- RECTL vR;
- // TODO:
- /*
- if ( !GetWindowRect(GetHwndOf(frame), &r) )
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().IsNull())
{
- wxLogLastError(_T("GetWindowRect"));
+ 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;
+ }
}
-
- (void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
- MAKELPARAM(r.right - r.left, r.bottom - r.top));
- */
+ 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
+// tool state change handlers
// ----------------------------------------------------------------------------
void wxToolBar::DoEnableTool(
wxToolBarToolBase* pTool
-, bool bEnable
+, bool WXUNUSED(bEnable)
)
{
- // TODO:
- /*
- ::SendMessage(GetHwnd(), TB_ENABLEBUTTON,
- (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0));
- */
-}
+ DrawTool(pTool);
+} // end of wxToolBar::DoEnableTool
void wxToolBar::DoToggleTool(
wxToolBarToolBase* pTool
-, bool bToggle
+, bool WXUNUSED(bToggle)
)
{
- // TODO:
- /*
- ::SendMessage(GetHwnd(), TB_CHECKBUTTON,
- (WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0));
- */
-}
+ DrawTool(pTool);
+} // end of wxToolBar::DoToggleTool
void wxToolBar::DoSetToggle(
- wxToolBarToolBase* pTool
-, bool bToggle
+ 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
)
{
- // VZ: AFAIK, the button has to be created either with TBSTYLE_CHECK or
- // without, so we really need to delete the button and recreate it here
- wxFAIL_MSG( _T("not implemented") );
-}
+ wxToolBarToolBase* pTool = FindById(vId);
+
+ if (pTool && pTool->CanBeToggled())
+ {
+ if (pTool->IsToggled())
+ pTool->Toggle();
+
+ DrawTool(pTool);
+ }
+} // end of wxToolBar::SpringUpButton
// ----------------------------------------------------------------------------
-// event handlers
+// private helpers
// ----------------------------------------------------------------------------
-// Responds to colour changes, and passes event on to children.
-void wxToolBar::OnSysColourChanged(
- wxSysColourChangedEvent& rEvent
-)
+void wxToolBar::LowerTool ( wxToolBarToolBase* pToolBase,
+ bool bLower )
{
- // TODO:
- /*
- m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
- GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
- */
+ 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);
- // Remap the buttons
- Realize();
+ if (!pTool)
+ return;
- Refresh();
+ if (pTool->IsSeparator())
+ return;
- // Propagate the event to the non-top-level children
- wxWindow::OnSysColourChanged(rEvent);
-}
+ //
+ // We only do this for flat toolbars
+ //
+ if (!HasFlag(wxTB_FLAT))
+ return;
-void wxToolBar::OnMouseEvent(
- wxMouseEvent& rEvent
-)
-{
- if (rEvent.RightDown())
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
{
- // For now, we don't have an id. Later we could
- // try finding the tool.
- OnRightClick( (int)-1
- ,rEvent.GetX()
- ,rEvent.GetY()
- );
+ 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
{
- rEvent.Skip();
+ vX = pTool->m_vX - 2;
+ vY = pTool->m_vY - 2;
+ vWidth = pTool->GetWidth() + 4;
+ vHeight = pTool->GetHeight() + 4;
}
-}
-
-MRESULT wxToolBar::OS2WindowProc(
- WXUINT ulMsg
-, MPARAM wParam
-, MPARAM lParam
-)
-{
- // TODO:
- /*
- if (nMsg == WM_SIZE)
+ if (bLower)
{
- // calculate our minor dimenstion ourselves - we're confusing the
- // standard logic (TB_AUTOSIZE) with our horizontal toolbars and other
- // hacks
- RECT r;
- if ( ::SendMessage(GetHwnd(), TB_GETITEMRECT, 0, (LPARAM)&r) )
- {
- int w, h;
+ 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 ( GetWindowStyle() & wxTB_VERTICAL )
- {
- w = r.right - r.left;
- if ( m_maxRows )
- {
- w *= (m_nButtons + m_maxRows - 1)/m_maxRows;
- }
- h = HIWORD(lParam);
- }
- else
- {
- w = LOWORD(lParam);
- h = r.bottom - r.top;
- if ( m_maxRows )
- {
- h += 6; // FIXME: this is the separator line height...
- h *= m_maxRows;
- }
- }
+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 ( MAKELPARAM(w, h) != lParam )
- {
- // size really changed
- SetSize(w, h);
- }
+ if (!pTool)
+ return;
- // message processed
- return 0;
- }
- }
+ if (pTool->IsSeparator())
+ return;
- return wxControl::MSWWindowProc(nMsg, wParam, lParam);
- */
- return((MRESULT)0);
-}
+ if (!pTool->IsEnabled())
+ return;
-// ----------------------------------------------------------------------------
-// private functions
-// ----------------------------------------------------------------------------
+ //
+ // We only do this for flat toolbars
+ //
+ if (!HasFlag(wxTB_FLAT))
+ return;
-// These are the default colors used to map the bitmap colors to the current
-// system colors. Note that they are in BGR format because this is what Windows
-// wants (and not RGB)
-
-#define BGR_BUTTONTEXT (RGB(000,000,000)) // black
-#define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
-#define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
-#define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
-#define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
-#define BGR_BACKGROUND (RGB(255,000,255)) // magenta
-
-void wxMapBitmap(
- HBITMAP hBitmap
-, int nWidth
-, int nHeight
-)
-{
- // TODO:
- /*
- COLORMAP ColorMap[] =
- {
- {BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black
- {BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey
- {BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey
- {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
- {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue
- {BGR_BACKGROUND, COLOR_WINDOW} // magenta
- };
-
- int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
- int n;
- for ( n = 0; n < NUM_MAPS; n++)
- {
- ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
- }
-
- HBITMAP hbmOld;
- HDC hdcMem = CreateCompatibleDC(NULL);
-
- if (hdcMem)
- {
- hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap);
-
- int i, j, k;
- for ( i = 0; i < width; i++)
+ if (HasFlag(wxTB_TEXT) && !pTool->GetLabel().empty())
{
- for ( j = 0; j < height; j++)
+ if (pTool->GetWidth() > m_vTextX)
{
- COLORREF pixel = ::GetPixel(hdcMem, i, j);
-//
-// BYTE red = GetRValue(pixel);
-// BYTE green = GetGValue(pixel);
-// BYTE blue = GetBValue(pixel);
-//
-
- for ( k = 0; k < NUM_MAPS; k ++)
- {
- if ( ColorMap[k].from == pixel )
- {
- // COLORREF actualPixel = ::SetPixel(hdcMem, i, j, ColorMap[k].to);
- break;
- }
- }
+ 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
+ );
- SelectObject(hdcMem, hbmOld);
- DeleteObject(hdcMem);
- }
- */
-}
-
-// Some experiments...
-#if 0
- // What we want to do is create another bitmap which has a depth of 4,
- // and set the bits. So probably we want to convert this HBITMAP into a
- // DIB, then call SetDIBits.
- // AAAGH. The stupid thing is that if newBitmap has a depth of 4 (less than that of
- // the screen), then SetDIBits fails.
- HBITMAP newBitmap = ::CreateBitmap(totalBitmapWidth, totalBitmapHeight, 1, 4, NULL);
- HANDLE newDIB = ::BitmapToDIB((HBITMAP) m_hBitmap, NULL);
- LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) GlobalLock(newDIB);
-
- dc = ::GetDC(NULL);
-// LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) newDIB;
-
- int result = ::SetDIBits(dc, newBitmap, 0, lpbmi->biHeight, FindDIBBits((LPSTR)lpbmi), (LPBITMAPINFO)lpbmi,
- DIB_PAL_COLORS);
- DWORD err = GetLastError();
-
- ::ReleaseDC(NULL, dc);
-
- // Delete the DIB
- GlobalUnlock (newDIB);
- GlobalFree (newDIB);
-
-// WXHBITMAP hBitmap2 = wxCreateMappedBitmap((WXHINSTANCE) wxGetInstance(), (WXHBITMAP) m_hBitmap);
- // Substitute our new bitmap for the old one
- ::DeleteObject((HBITMAP) m_hBitmap);
- m_hBitmap = (WXHBITMAP) newBitmap;
-#endif
+ 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
+#endif // ndef for wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE