From 8a0681f9338345d0ef32b2ad809d49fd20861119 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 15 Dec 1999 19:47:54 +0000 Subject: [PATCH] merging in the toolbar changes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4977 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/tbargtk.h | 179 +++---- include/wx/gtk1/tbargtk.h | 179 +++---- include/wx/motif/toolbar.h | 117 ++--- include/wx/msw/tbar95.h | 89 ++-- include/wx/msw/tbarmsw.h | 210 ++++---- include/wx/tbarbase.h | 434 +++++++++------- include/wx/tbarmsw.h | 13 - include/wx/tbarsmpl.h | 198 ++++++-- include/wx/toolbar.h | 49 +- src/common/tbarbase.cpp | 963 ++++++++++++++--------------------- src/common/tbarsmpl.cpp | 461 ----------------- src/generic/tbarsmpl.cpp | 992 +++++++++++++++++++++++++++++++++++++ src/gtk/tbargtk.cpp | 731 +++++++++++---------------- src/gtk1/tbargtk.cpp | 731 +++++++++++---------------- src/motif/toolbar.cpp | 685 +++++++++++++------------ src/msw/tbar95.cpp | 627 ++++++++++++++--------- src/msw/tbarmsw.cpp | 943 ++++++++++++++++++++--------------- 17 files changed, 4004 insertions(+), 3597 deletions(-) delete mode 100644 include/wx/tbarmsw.h delete mode 100644 src/common/tbarsmpl.cpp create mode 100644 src/generic/tbarsmpl.cpp diff --git a/include/wx/gtk/tbargtk.h b/include/wx/gtk/tbargtk.h index 3d7c30d434..1187c5887f 100644 --- a/include/wx/gtk/tbargtk.h +++ b/include/wx/gtk/tbargtk.h @@ -4,139 +4,92 @@ // Author: Robert Roebling // RCS-ID: $Id$ // Copyright: (c) Robert Roebling -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef __TBARGTKH__ -#define __TBARGTKH__ +#ifndef _WX_GTK_TBARGTK_H_ +#define _WX_GTK_TBARGTK_H_ #ifdef __GNUG__ -#pragma interface + #pragma interface "tbargtk.h" #endif -#include "wx/defs.h" - #if wxUSE_TOOLBAR -#include "wx/control.h" -#include "wx/bitmap.h" -#include "wx/tbarbase.h" - -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class wxToolBarTool; -class wxToolBar; - -//----------------------------------------------------------------------------- -// constants -//----------------------------------------------------------------------------- - -#define wxTOOL_STYLE_BUTTON 1 -#define wxTOOL_STYLE_SEPARATOR 2 - -//----------------------------------------------------------------------------- -// global data -//----------------------------------------------------------------------------- - -extern const wxChar *wxToolBarNameStr; - -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxToolBar -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- -class wxToolBar: public wxControl +class wxToolBar : public wxToolBarBase { public: - wxToolBar(); - wxToolBar( wxWindow *parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxToolBarNameStr ); - ~wxToolBar(); - - bool Create( wxWindow *parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxToolBarNameStr); - - // Only allow toggle if returns TRUE. Call when left button up. - virtual bool OnLeftClick(int toolIndex, bool toggleDown); - - // Call when right button down. - virtual void OnRightClick(int toolIndex, float x, float y); - - // Called when the mouse cursor enters a tool bitmap. - // Argument is -1 if mouse is exiting the toolbar. - virtual void OnMouseEnter(int toolIndex); - - // 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. - virtual wxToolBarTool *AddTool( int toolIndex, const wxBitmap& bitmap, - const wxBitmap& pushedBitmap = wxNullBitmap, bool toggle = FALSE, - wxCoord xPos = -1, wxCoord yPos = -1, wxObject *clientData = (wxObject *)NULL, - const wxString& helpString1 = "", const wxString& helpString2 = ""); - - // Add arbitrary control - virtual bool AddControl(wxControl *control); - - // Add space - virtual void AddSeparator(); - - // Delete tool by index (=id) - virtual bool DeleteTool(int toolIndex); - - // Delete all tools - virtual void ClearTools(); - - // Has to be called after adding tools or changing something - virtual bool Realize(); - - virtual void EnableTool(int toolIndex, bool enable); - virtual void ToggleTool(int toolIndex, bool toggle); // toggle is TRUE if toggled on - virtual wxObject *GetToolClientData(int index) const; - - virtual bool GetToolState(int toolIndex) const; - virtual bool GetToolEnabled(int toolIndex) const; - + // construction/destruction + wxToolBar() { Init(); } + wxToolBar( wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxToolBarNameStr ) + { + Init(); + + Create(parent, id, pos, size, style, name); + } + + bool Create( wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxToolBarNameStr ); + + virtual ~wxToolBar(); + + // override base class virtuals virtual void SetMargins(int x, int y); - void SetMargins(const wxSize& size) { SetMargins(size.x, size.y); }; - virtual wxSize GetToolMargins(void) { return wxSize(m_xMargin, m_yMargin); } - - virtual void SetToolPacking(int packing); virtual void SetToolSeparation(int separation); - virtual int GetToolPacking(); - virtual int GetToolSeparation(); - - virtual wxString GetToolLongHelp(int toolIndex); - virtual wxString GetToolShortHelp(int toolIndex); - - virtual void SetToolLongHelp(int toolIndex, const wxString& helpString); - virtual void SetToolShortHelp(int toolIndex, const wxString& helpString); - - void OnIdle( wxIdleEvent &ievent ); - - // implementation - + + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; + + // implementation from now on + // -------------------------- + GtkToolbar *m_toolbar; - int m_separation; - wxList m_tools; - - GdkColor *m_fg; - GdkColor *m_bg; - int m_xMargin; - int m_yMargin; - bool m_hasToolAlready; + + GdkColor *m_fg; + GdkColor *m_bg; + bool m_blockNextEvent; - + void OnInternalIdle(); - + +protected: + // common part of all ctors + void Init(); + + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + private: - DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxToolBar) }; -#endif +#endif // wxUSE_TOOLBAR #endif - // __TBARGTKH__ + // _WX_GTK_TBARGTK_H_ diff --git a/include/wx/gtk1/tbargtk.h b/include/wx/gtk1/tbargtk.h index 3d7c30d434..1187c5887f 100644 --- a/include/wx/gtk1/tbargtk.h +++ b/include/wx/gtk1/tbargtk.h @@ -4,139 +4,92 @@ // Author: Robert Roebling // RCS-ID: $Id$ // Copyright: (c) Robert Roebling -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef __TBARGTKH__ -#define __TBARGTKH__ +#ifndef _WX_GTK_TBARGTK_H_ +#define _WX_GTK_TBARGTK_H_ #ifdef __GNUG__ -#pragma interface + #pragma interface "tbargtk.h" #endif -#include "wx/defs.h" - #if wxUSE_TOOLBAR -#include "wx/control.h" -#include "wx/bitmap.h" -#include "wx/tbarbase.h" - -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class wxToolBarTool; -class wxToolBar; - -//----------------------------------------------------------------------------- -// constants -//----------------------------------------------------------------------------- - -#define wxTOOL_STYLE_BUTTON 1 -#define wxTOOL_STYLE_SEPARATOR 2 - -//----------------------------------------------------------------------------- -// global data -//----------------------------------------------------------------------------- - -extern const wxChar *wxToolBarNameStr; - -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxToolBar -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- -class wxToolBar: public wxControl +class wxToolBar : public wxToolBarBase { public: - wxToolBar(); - wxToolBar( wxWindow *parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxToolBarNameStr ); - ~wxToolBar(); - - bool Create( wxWindow *parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = 0, const wxString& name = wxToolBarNameStr); - - // Only allow toggle if returns TRUE. Call when left button up. - virtual bool OnLeftClick(int toolIndex, bool toggleDown); - - // Call when right button down. - virtual void OnRightClick(int toolIndex, float x, float y); - - // Called when the mouse cursor enters a tool bitmap. - // Argument is -1 if mouse is exiting the toolbar. - virtual void OnMouseEnter(int toolIndex); - - // 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. - virtual wxToolBarTool *AddTool( int toolIndex, const wxBitmap& bitmap, - const wxBitmap& pushedBitmap = wxNullBitmap, bool toggle = FALSE, - wxCoord xPos = -1, wxCoord yPos = -1, wxObject *clientData = (wxObject *)NULL, - const wxString& helpString1 = "", const wxString& helpString2 = ""); - - // Add arbitrary control - virtual bool AddControl(wxControl *control); - - // Add space - virtual void AddSeparator(); - - // Delete tool by index (=id) - virtual bool DeleteTool(int toolIndex); - - // Delete all tools - virtual void ClearTools(); - - // Has to be called after adding tools or changing something - virtual bool Realize(); - - virtual void EnableTool(int toolIndex, bool enable); - virtual void ToggleTool(int toolIndex, bool toggle); // toggle is TRUE if toggled on - virtual wxObject *GetToolClientData(int index) const; - - virtual bool GetToolState(int toolIndex) const; - virtual bool GetToolEnabled(int toolIndex) const; - + // construction/destruction + wxToolBar() { Init(); } + wxToolBar( wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxToolBarNameStr ) + { + Init(); + + Create(parent, id, pos, size, style, name); + } + + bool Create( wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxToolBarNameStr ); + + virtual ~wxToolBar(); + + // override base class virtuals virtual void SetMargins(int x, int y); - void SetMargins(const wxSize& size) { SetMargins(size.x, size.y); }; - virtual wxSize GetToolMargins(void) { return wxSize(m_xMargin, m_yMargin); } - - virtual void SetToolPacking(int packing); virtual void SetToolSeparation(int separation); - virtual int GetToolPacking(); - virtual int GetToolSeparation(); - - virtual wxString GetToolLongHelp(int toolIndex); - virtual wxString GetToolShortHelp(int toolIndex); - - virtual void SetToolLongHelp(int toolIndex, const wxString& helpString); - virtual void SetToolShortHelp(int toolIndex, const wxString& helpString); - - void OnIdle( wxIdleEvent &ievent ); - - // implementation - + + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; + + // implementation from now on + // -------------------------- + GtkToolbar *m_toolbar; - int m_separation; - wxList m_tools; - - GdkColor *m_fg; - GdkColor *m_bg; - int m_xMargin; - int m_yMargin; - bool m_hasToolAlready; + + GdkColor *m_fg; + GdkColor *m_bg; + bool m_blockNextEvent; - + void OnInternalIdle(); - + +protected: + // common part of all ctors + void Init(); + + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + private: - DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxToolBar) }; -#endif +#endif // wxUSE_TOOLBAR #endif - // __TBARGTKH__ + // _WX_GTK_TBARGTK_H_ diff --git a/include/wx/motif/toolbar.h b/include/wx/motif/toolbar.h index 01452609a5..443e3e559e 100644 --- a/include/wx/motif/toolbar.h +++ b/include/wx/motif/toolbar.h @@ -1,8 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: toolbar.h +// Name: wx/motif/toolbar.h // Purpose: wxToolBar class // Author: Julian Smart -// Modified by: +// Modified by: 13.12.99 by VZ during toolbar classes reorganization // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -13,81 +13,60 @@ #define _WX_TOOLBAR_H_ #ifdef __GNUG__ -#pragma interface "toolbar.h" + #pragma interface "toolbar.h" #endif -#include "wx/tbarbase.h" +class WXDLLEXPORT wxToolBar : public wxToolBarBase +{ +public: + // ctors and dtor + wxToolBar() { Init(); } -WXDLLEXPORT_DATA(extern const char*) wxToolBarNameStr; + wxToolBar(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER | wxTB_HORIZONTAL, + const wxString& name = wxToolBarNameStr) + { + Init(); -class WXDLLEXPORT wxToolBar: public wxToolBarBase -{ - DECLARE_DYNAMIC_CLASS(wxToolBar) - public: - /* - * Public interface - */ - - wxToolBar(); - - inline wxToolBar(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER|wxTB_HORIZONTAL, - const wxString& name = wxToolBarNameStr): - m_widgets(wxKEY_INTEGER) - - { - Create(parent, id, pos, size, style, name); - } - ~wxToolBar(); - - bool Create(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER|wxTB_HORIZONTAL, - const wxString& name = wxToolBarNameStr); - - // If pushedBitmap is NULL, a reversed version of bitmap is - // created and used as the pushed/toggled image. - // If toggle is TRUE, the button toggles between the two states. - wxToolBarTool *AddTool(int toolIndex, const wxBitmap& bitmap, const wxBitmap& pushedBitmap = wxNullBitmap, - bool toggle = FALSE, wxCoord xPos = -1, wxCoord yPos = -1, wxObject *clientData = NULL, - const wxString& helpString1 = "", const wxString& helpString2 = ""); - - // Set default bitmap size - void SetToolBitmapSize(const wxSize& size); - void EnableTool(int toolIndex, bool enable); // additional drawing on enabling - void ToggleTool(int toolIndex, bool toggle); // toggle is TRUE if toggled on - void ClearTools(); - - // The button size is bigger than the bitmap size - wxSize GetToolSize() const; - - wxSize GetMaxSize() const; - - // Add all the buttons - virtual bool CreateTools(); - virtual void LayoutTools() {} - - // The post-tool-addition call. TODO: do here whatever's - // necessary for completing the toolbar construction. - bool Realize() { return CreateTools(); }; - -// Implementation - void DestroyPixmaps(); - int FindIndexForWidget(WXWidget w); - WXWidget FindWidgetForIndex(int index); - - WXWidget GetTopWidget() const; - WXWidget GetClientWidget() const; - WXWidget GetMainWidget() const; + Create(parent, id, pos, size, style, name); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER | wxTB_HORIZONTAL, + const wxString& name = wxToolBarNameStr); + + virtual ~wxToolBar(); + + // override/implement base class virtuals + virtual wxToolBarTool *FindToolForPosition(wxCoord x, wxCoord y) const; + + virtual bool Realize(); + + // implementation from now on + + // find tool by widget + wxToolBarTool *FindToolByWidget(WXWidget w) const; protected: - // List of widgets in the toolbar, indexed by tool index - wxList m_widgets; + // common part of all ctors + void Init(); + + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarTool *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarTool *tool); - // List of pixmaps to destroy when tools are recreated or - // or toolbar is destroyed. - wxList m_pixmaps; + virtual void DoEnableTool(wxToolBarTool *tool, bool enable); + virtual void DoToggleTool(wxToolBarTool *tool, bool toggle); + virtual void DoSetToggle(wxToolBarTool *tool, bool toggle); -DECLARE_EVENT_TABLE() +private: + DECLARE_DYNAMIC_CLASS(wxToolBar) }; #endif diff --git a/include/wx/msw/tbar95.h b/include/wx/msw/tbar95.h index 97f27e9ec5..c6952d346a 100644 --- a/include/wx/msw/tbar95.h +++ b/include/wx/msw/tbar95.h @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: wx/msw/tbar95.h -// Purpose: wxToolBar95 (Windows 95 toolbar) class +// Purpose: wxToolBar (Windows 95 toolbar) class // Author: Julian Smart // Modified by: // Created: 01/02/97 @@ -13,21 +13,20 @@ #define _WX_TBAR95_H_ #ifdef __GNUG__ -#pragma interface "tbar95.h" + #pragma interface "tbar95.h" #endif #if wxUSE_TOOLBAR #include "wx/dynarray.h" -#include "wx/tbarbase.h" - -class WXDLLEXPORT wxToolBar95 : public wxToolBarBase +class WXDLLEXPORT wxToolBar : public wxToolBarBase { public: - wxToolBar95() { Init(); } + // ctors and dtor + wxToolBar() { Init(); } - wxToolBar95(wxWindow *parent, + wxToolBar(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, @@ -39,8 +38,6 @@ public: Create(parent, id, pos, size, style, name); } - ~wxToolBar95(); - bool Create(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, @@ -48,36 +45,21 @@ public: long style = wxNO_BORDER | wxTB_HORIZONTAL, const wxString& name = wxToolBarNameStr); - // override base class virtuals - - virtual wxToolBarTool *AddTool(int toolIndex, - const wxBitmap& bitmap, - const wxBitmap& pushedBitmap = wxNullBitmap, - bool toggle = FALSE, - long xPos = -1, long yPos = -1, - wxObject *clientData = NULL, - const wxString& helpString1 = wxEmptyString, - const wxString& helpString2 = wxEmptyString); - virtual bool AddControl(wxControl *control); - - virtual bool DeleteTool(int toolIndex); - virtual void ClearTools(); + virtual ~wxToolBar(); - virtual bool Realize() { return CreateTools(); }; + // override/implement base class virtuals + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; - virtual void EnableTool(int toolIndex, bool enable); - virtual void ToggleTool(int toolIndex, bool toggle); + virtual bool Realize(); virtual void SetToolBitmapSize(const wxSize& size); virtual wxSize GetToolSize() const; - virtual wxSize GetMaxSize() const; - virtual bool GetToolState(int toolIndex) const; - - virtual bool CreateTools(); virtual void SetRows(int nRows); - // IMPLEMENTATION + // implementation only from now on + // ------------------------------- + virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result); @@ -88,34 +70,37 @@ protected: // common part of all ctors void Init(); - // the array storing the id for each index - wxArrayInt m_ids; + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); - // get index from id (returns wxNOT_FOUND if no such button) - int GetIndexFromId(int id) const; + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); - // the big bitmap containing all bitmaps of the toolbar buttons - WXHBITMAP m_hBitmap; + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); - DECLARE_EVENT_TABLE() -}; + // should be called whenever the toolbar size changes + void UpdateSize(); -class WXDLLEXPORT wxToolBar : public wxToolBar95 -{ -public: - wxToolBar() { } + // override WndProc to process WM_SIZE + virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); - wxToolBar(wxWindow *parent, - wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER | wxTB_HORIZONTAL, - const wxString& name = wxToolBarNameStr) - : wxToolBar95(parent, id, pos, size, style, name) - { - } + // the big bitmap containing all bitmaps of the toolbar buttons + WXHBITMAP m_hBitmap; + + // the total number of toolbar elements + size_t m_nButtons; private: + DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxToolBar) }; diff --git a/include/wx/msw/tbarmsw.h b/include/wx/msw/tbarmsw.h index 75fe842966..ed88e668d2 100644 --- a/include/wx/msw/tbarmsw.h +++ b/include/wx/msw/tbarmsw.h @@ -1,8 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: tbarmsw.h -// Purpose: wxToolBarMSW class +// Name: wx/msw/tbarmsw.h +// Purpose: wxToolBar for Win16 // Author: Julian Smart -// Modified by: +// Modified by: 13.12.99 by VZ during toolbar classes reorganization // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -24,117 +24,123 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxButtonBarNameStr; class WXDLLEXPORT wxMemoryDC; -// Non-Win95 (WIN32, WIN16, UNIX) version +// ---------------------------------------------------------------------------- +// wxToolBar for Win16 +// ---------------------------------------------------------------------------- -class WXDLLEXPORT wxToolBarMSW: public wxToolBarBase +class WXDLLEXPORT wxToolBar : public wxToolBarBase { - DECLARE_DYNAMIC_CLASS(wxToolBarMSW) public: - /* - * Public interface - */ - wxToolBarMSW(void); - - inline wxToolBarMSW(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER|wxTB_HORIZONTAL, const wxString& name = wxButtonBarNameStr) - { - Create(parent, id, pos, size, style, name); - } - bool Create(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER|wxTB_HORIZONTAL, const wxString& name = wxButtonBarNameStr); - - ~wxToolBarMSW(void); - - // Handle wxWindows events - void OnPaint(wxPaintEvent& event); - void OnSize(wxSizeEvent& event); - void OnMouseEvent(wxMouseEvent& event); - - // If pushedBitmap is NULL, a reversed version of bitmap is - // created and used as the pushed/toggled image. - // If toggle is TRUE, the button toggles between the two states. - wxToolBarTool *AddTool(int toolIndex, const wxBitmap& bitmap, const wxBitmap& pushedBitmap = wxNullBitmap, - bool toggle = FALSE, long xPos = -1, long yPos = -1, wxObject *clientData = NULL, - const wxString& helpString1 = wxEmptyString, const wxString& helpString2 = wxEmptyString); - - void DrawTool(wxDC& dc, wxMemoryDC& memDc, wxToolBarTool *tool); - - // Set default bitmap size - virtual void SetToolBitmapSize(const wxSize& size); - void EnableTool(int toolIndex, bool enable); // additional drawing on enabling - - // The button size is bigger than the bitmap size - wxSize GetToolSize(void) const; - - void LayoutTools(); - - // The post-tool-addition call - bool Realize() { Layout(); return TRUE; }; - - protected: - void DrawTool(wxDC& dc, wxToolBarTool *tool, int state); - - void GetSysColors(void); - bool InitGlobalObjects(void); - void FreeGlobalObjects(void); - void PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb); - void CreateMask(WXHDC hDC, int xoffset, int yoffset, int dx, int dy); - void DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state); - void DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBarTool *tool, int state); - WXHBITMAP CreateDitherBitmap(); - bool CreateDitherBrush(void); - bool FreeDitherBrush(void); - WXHBITMAP CreateMappedBitmap(WXHINSTANCE hInstance, void *lpBitmapInfo); - WXHBITMAP CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap); - -protected: - int m_currentRowsOrColumns; - long m_lastX, m_lastY; - - WXHBRUSH m_hbrDither; - WXDWORD m_rgbFace; - WXDWORD m_rgbShadow; - WXDWORD m_rgbHilight; - WXDWORD m_rgbFrame; - -// -// m_hdcMono is the DC that holds a mono bitmap, m_hbmMono -// that is used to create highlights -// of button faces. -// m_hbmDefault hold the default bitmap if there is one. -// - WXHDC m_hdcMono; - WXHBITMAP m_hbmMono; - WXHBITMAP m_hbmDefault; - -DECLARE_EVENT_TABLE() -}; - -// -// States (not all of them currently used) -// -#define wxTBSTATE_CHECKED 0x01 // radio button is checked -#define wxTBSTATE_PRESSED 0x02 // button is being depressed (any style) -#define wxTBSTATE_ENABLED 0x04 // button is enabled -#define wxTBSTATE_HIDDEN 0x08 // button is hidden -#define wxTBSTATE_INDETERMINATE 0x10 // button is indeterminate - -class WXDLLEXPORT wxToolBar : public wxToolBarMSW -{ -public: - wxToolBar() { } + // construction + wxToolBar() { Init(); } wxToolBar(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER | wxTB_HORIZONTAL, - const wxString& name = wxToolBarNameStr) - : wxToolBarMSW(parent, id, pos, size, style, name) + long style = wxNO_BORDER|wxTB_HORIZONTAL, + const wxString& name = wxButtonBarNameStr) { + Init(); + + Create(parent, id, pos, size, style, name); } + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER|wxTB_HORIZONTAL, + const wxString& name = wxButtonBarNameStr); + + ~wxToolBar(); + + // implement/override base class (pure) virtuals + virtual wxToolBarToolBase *AddTool(int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + bool toggle, + wxCoord xPos, + wxCoord yPos = -1, + wxObject *clientData = NULL, + const wxString& helpString1 = wxEmptyString, + const wxString& helpString2 = wxEmptyString); + + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; + + virtual void SetToolBitmapSize(const wxSize& size); + virtual wxSize GetToolSize() const; + + virtual bool Realize(); + + // implementation only from now on + // ------------------------------- + + // Handle wxWindows events + void OnPaint(wxPaintEvent& event); + void OnMouseEvent(wxMouseEvent& event); + +protected: + void Init(); + + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + + void DoRedrawTool(wxToolBarToolBase *tool); + + void DrawTool(wxDC& dc, wxToolBarToolBase *tool); + void DrawTool(wxDC& dc, wxToolBarToolBase *tool, int state); + + void GetSysColors(); + bool InitGlobalObjects(); + void FreeGlobalObjects(); + void PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb); + void CreateMask(WXHDC hDC, int xoffset, int yoffset, int dx, int dy); + void DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state); + void DrawButton(WXHDC hdc, int x, int y, int dx, int dy, + wxToolBarTool *tool, int state); + WXHBITMAP CreateDitherBitmap(); + bool CreateDitherBrush(); + bool FreeDitherBrush(); + WXHBITMAP CreateMappedBitmap(WXHINSTANCE hInstance, void *lpBitmapInfo); + WXHBITMAP CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap); + + int m_currentRowsOrColumns; + int m_pressedTool, m_currentTool; + + wxCoord m_xPos, m_yPos; + wxCoord m_lastX, m_lastY; + + WXHBRUSH m_hbrDither; + WXDWORD m_rgbFace; + WXDWORD m_rgbShadow; + WXDWORD m_rgbHilight; + WXDWORD m_rgbFrame; + + // + // m_hdcMono is the DC that holds a mono bitmap, m_hbmMono + // that is used to create highlights + // of button faces. + // m_hbmDefault hold the default bitmap if there is one. + // + WXHDC m_hdcMono; + WXHBITMAP m_hbmMono; + WXHBITMAP m_hbmDefault; + private: + DECLARE_EVENT_TABLE() DECLARE_DYNAMIC_CLASS(wxToolBar) }; diff --git a/include/wx/tbarbase.h b/include/wx/tbarbase.h index 08ce5dbe1e..c282777eaa 100644 --- a/include/wx/tbarbase.h +++ b/include/wx/tbarbase.h @@ -26,7 +26,8 @@ #include "wx/list.h" #include "wx/control.h" -class WXDLLEXPORT wxToolBar; +class WXDLLEXPORT wxToolBarBase; +class WXDLLEXPORT wxToolBarToolBase; // ---------------------------------------------------------------------------- // constants @@ -36,7 +37,7 @@ WXDLLEXPORT_DATA(extern const wxChar*) wxToolBarNameStr; WXDLLEXPORT_DATA(extern const wxSize) wxDefaultSize; WXDLLEXPORT_DATA(extern const wxPoint) wxDefaultPosition; -enum +enum wxToolBarToolStyle { wxTOOL_STYLE_BUTTON = 1, wxTOOL_STYLE_SEPARATOR = 2, @@ -44,60 +45,128 @@ enum }; // ---------------------------------------------------------------------------- -// wxToolBarTool is one button/separator/whatever in the toolbar +// wxToolBarTool is a toolbar element. +// +// It has a unique id (except for the separators which always have id -1), the +// style (telling whether it is a normal button, separator or a control), the +// state (toggled or not, enabled or not) and short and long help strings. The +// default implementations use the short help string for the tooltip text which +// is popped up when the mouse pointer enters the tool and the long help string +// for the applications status bar. // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxToolBarTool : public wxObject +class WXDLLEXPORT wxToolBarToolBase : public wxObject { public: // ctors & dtor // ------------ - wxToolBarTool() { } - -#ifdef __WXGTK__ - wxToolBarTool(wxToolBar *owner, - int theIndex = 0, - const wxBitmap& bitmap1 = wxNullBitmap, - const wxBitmap& bitmap2 = wxNullBitmap, - bool toggle = FALSE, - wxObject *clientData = (wxObject *) NULL, - const wxString& shortHelpString = wxEmptyString, - const wxString& longHelpString = wxEmptyString, - GtkWidget *pixmap = (GtkWidget *) NULL ); -#else // !GTK - wxToolBarTool(int theIndex, - const wxBitmap& bitmap1 = wxNullBitmap, - const wxBitmap& bitmap2 = wxNullBitmap, - bool toggle = FALSE, - long xPos = -1, - long yPos = -1, - const wxString& shortHelpString = wxEmptyString, - const wxString& longHelpString = wxEmptyString); -#endif // GTK/!GTK - - wxToolBarTool(wxControl *control); - - ~wxToolBarTool(); + wxToolBarToolBase(wxToolBarBase *tbar = (wxToolBarBase *)NULL, + int id = wxID_SEPARATOR, + const wxBitmap& bitmap1 = wxNullBitmap, + const wxBitmap& bitmap2 = wxNullBitmap, + bool toggle = FALSE, + wxObject *clientData = (wxObject *) NULL, + const wxString& shortHelpString = wxEmptyString, + const wxString& longHelpString = wxEmptyString) + : m_shortHelpString(shortHelpString), + m_longHelpString(longHelpString) + { + m_tbar = tbar; + m_id = id; + m_clientData = clientData; + + m_bitmap1 = bitmap1; + m_bitmap2 = bitmap2; + + m_isToggle = toggle; + m_enabled = TRUE; + m_toggled = FALSE; + + m_toolStyle = id == wxID_SEPARATOR ? wxTOOL_STYLE_SEPARATOR + : wxTOOL_STYLE_BUTTON; + } + + wxToolBarToolBase(wxToolBarBase *tbar, wxControl *control) + { + m_tbar = tbar; + m_control = control; + m_id = control->GetId(); + + m_isToggle = FALSE; + m_enabled = TRUE; + m_toggled = FALSE; + + m_toolStyle = wxTOOL_STYLE_CONTROL; + } + + ~wxToolBarToolBase(); // accessors // --------- - void SetSize( long w, long h ) { m_width = w; m_height = h; } - long GetWidth() const { return m_width; } - long GetHeight() const { return m_height; } + // general + int GetId() const { return m_id; } wxControl *GetControl() const { - wxASSERT_MSG( m_toolStyle == wxTOOL_STYLE_CONTROL, - _T("this toolbar tool is not a control") ); + wxASSERT_MSG( IsControl(), _T("this toolbar tool is not a control") ); return m_control; } -public: - int m_toolStyle; - int m_index; + wxToolBarBase *GetToolBar() const { return m_tbar; } + + // style + int IsButton() const { return m_toolStyle == wxTOOL_STYLE_BUTTON; } + int IsControl() const { return m_toolStyle == wxTOOL_STYLE_CONTROL; } + int IsSeparator() const { return m_toolStyle == wxTOOL_STYLE_SEPARATOR; } + int GetStyle() const { return m_toolStyle; } + + // state + bool IsEnabled() const { return m_enabled; } + bool IsToggled() const { return m_toggled; } + bool CanBeToggled() const { return m_isToggle; } + + // attributes + const wxBitmap& GetBitmap1() const { return m_bitmap1; } + const wxBitmap& GetBitmap2() const { return m_bitmap2; } + + const wxBitmap& GetBitmap() const + { return IsToggled() ? m_bitmap2 : m_bitmap1; } + + wxString GetShortHelp() const { return m_shortHelpString; } + wxString GetLongHelp() const { return m_longHelpString; } + + wxObject *GetClientData() const + { + wxASSERT_MSG( m_toolStyle != wxTOOL_STYLE_CONTROL, + _T("this toolbar tool doesn't have client data") ); + + return m_clientData; + } + + // modifiers: return TRUE if the state really changed + bool Enable(bool enable); + bool Toggle(bool toggle); + bool SetToggle(bool toggle); + bool SetShortHelp(const wxString& help); + bool SetLongHelp(const wxString& help); + + void Toggle() { Toggle(!IsToggled()); } + + void SetBitmap1(const wxBitmap& bmp) { m_bitmap1 = bmp; } + void SetBitmap2(const wxBitmap& bmp) { m_bitmap2 = bmp; } + + // add tool to/remove it from a toolbar + virtual void Detach() { m_tbar = (wxToolBarBase *)NULL; } + virtual void Attach(wxToolBarBase *tbar) { m_tbar = tbar; } + +protected: + wxToolBarBase *m_tbar; // the toolbar to which we belong (may be NULL) + + int m_toolStyle; // see enum wxToolBarToolStyle + int m_id; // the tool id, wxID_SEPARATOR for separator // as controls have their own client data, no need to waste memory union @@ -106,33 +175,23 @@ public: wxControl *m_control; }; - wxCoord m_x; - wxCoord m_y; - wxCoord m_width; - wxCoord m_height; - - bool m_toggleState; - bool m_isToggle; - bool m_enabled; - bool m_isMenuCommand; + // tool state + bool m_toggled; + bool m_isToggle; + bool m_enabled; - bool m_deleteSecondBitmap; - wxBitmap m_bitmap1; - wxBitmap m_bitmap2; + // normal and toggles bitmaps + wxBitmap m_bitmap1; + wxBitmap m_bitmap2; - wxString m_shortHelpString; - wxString m_longHelpString; - -#ifdef __WXGTK__ - wxToolBar *m_owner; - GtkWidget *m_item; - GtkWidget *m_pixmap; -#endif // GTK - -private: - DECLARE_DYNAMIC_CLASS(wxToolBarTool) + // short and long help strings + wxString m_shortHelpString; + wxString m_longHelpString; }; +// a list of toolbar tools +WX_DECLARE_LIST(wxToolBarToolBase, wxToolBarToolsList); + // ---------------------------------------------------------------------------- // the base class for all toolbars // ---------------------------------------------------------------------------- @@ -141,7 +200,7 @@ class WXDLLEXPORT wxToolBarBase : public wxControl { public: wxToolBarBase(); - ~wxToolBarBase(); + virtual ~wxToolBarBase(); // toolbar construction // -------------------- @@ -149,50 +208,93 @@ public: // 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. - virtual wxToolBarTool *AddTool(int toolIndex, + wxToolBarToolBase *AddTool(int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap = wxNullBitmap, + bool toggle = FALSE, + wxObject *clientData = NULL, + const wxString& shortHelpString = wxEmptyString, + const wxString& longHelpString = wxEmptyString) + { + return AddTool(id, bitmap, pushedBitmap, toggle, + -1, -1, clientData, shortHelpString, longHelpString); + } + + // the old version of AddTool() kept for compatibility + virtual wxToolBarToolBase *AddTool + ( + int id, const wxBitmap& bitmap, - const wxBitmap& pushedBitmap = wxNullBitmap, - bool toggle = FALSE, - wxCoord xPos = -1, + const wxBitmap& pushedBitmap, + bool toggle, + wxCoord xPos, wxCoord yPos = -1, wxObject *clientData = NULL, const wxString& helpString1 = wxEmptyString, - const wxString& helpString2 = wxEmptyString); - - // add an arbitrary control to the toolbar at given index, return TRUE if - // ok (notice that the control will be deleted by the toolbar and that it - // will also adjust its position/size) + const wxString& helpString2 = wxEmptyString + ); + + // insert the new tool at the given position, if pos == GetToolsCount(), it + // is equivalent to AddTool() + virtual wxToolBarToolBase *InsertTool + ( + size_t pos, + int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap = wxNullBitmap, + bool toggle = FALSE, + wxObject *clientData = NULL, + const wxString& help1 = wxEmptyString, + const wxString& help2 = wxEmptyString + ); + + // add an arbitrary control to the toolbar, return TRUE if ok (notice that + // the control will be deleted by the toolbar and that it will also adjust + // its position/size) // // NB: the control should have toolbar as its parent - virtual bool AddControl(wxControl * WXUNUSED(control)) { return FALSE; } + virtual wxToolBarToolBase *AddControl(wxControl *control); + virtual wxToolBarToolBase *InsertControl(size_t pos, wxControl *control); - virtual void AddSeparator(); + // add a separator to the toolbar + virtual wxToolBarToolBase *AddSeparator(); + virtual wxToolBarToolBase *InsertSeparator(size_t pos); + + // remove the tool from the toolbar: the caller is responsible for actually + // deleting the pointer + virtual wxToolBarToolBase *RemoveTool(int id); + + // delete tool either by index or by position + virtual bool DeleteToolByPos(size_t pos); + virtual bool DeleteTool(int id); + + // delete all tools virtual void ClearTools(); // must be called after all buttons have been created to finish toolbar // initialisation - virtual bool Realize() = 0; + virtual bool Realize(); // tools state // ----------- - virtual void EnableTool(int toolIndex, bool enable); - - // toggle is TRUE if toggled on - virtual void ToggleTool(int toolIndex, bool toggle); + virtual void EnableTool(int id, bool enable); + virtual void ToggleTool(int id, bool toggle); // Set this to be togglable (or not) - virtual void SetToggle(int toolIndex, bool toggle); + virtual void SetToggle(int id, bool toggle); + virtual wxObject *GetToolClientData(int index) const; - virtual bool GetToolState(int toolIndex) const; - virtual bool GetToolEnabled(int toolIndex) const; - virtual wxToolBarTool *FindToolForPosition(long x, long y) const; + // return TRUE if the tool is toggled + virtual bool GetToolState(int id) const; + + virtual bool GetToolEnabled(int id) const; - virtual void SetToolShortHelp(int toolIndex, const wxString& helpString); - virtual wxString GetToolShortHelp(int toolIndex) const; - virtual void SetToolLongHelp(int toolIndex, const wxString& helpString); - virtual wxString GetToolLongHelp(int toolIndex) const; + virtual void SetToolShortHelp(int id, const wxString& helpString); + virtual wxString GetToolShortHelp(int id) const; + virtual void SetToolLongHelp(int id, const wxString& helpString); + virtual wxString GetToolLongHelp(int id) const; // margins/packing/separation // -------------------------- @@ -200,48 +302,58 @@ public: virtual void SetMargins(int x, int y); void SetMargins(const wxSize& size) { SetMargins((int) size.x, (int) size.y); } - virtual void SetToolPacking(int packing); - virtual void SetToolSeparation(int separation); + virtual void SetToolPacking(int packing) + { m_toolPacking = packing; } + virtual void SetToolSeparation(int separation) + { m_toolSeparation = separation; } virtual wxSize GetToolMargins() { return wxSize(m_xMargin, m_yMargin); } virtual int GetToolPacking() { return m_toolPacking; } virtual int GetToolSeparation() { return m_toolSeparation; } + // toolbar geometry + // ---------------- + + // set the number of toolbar rows + virtual void SetRows(int nRows); + + // the toolbar can wrap - limit the number of columns or rows it may take void SetMaxRowsCols(int rows, int cols) { m_maxRows = rows; m_maxCols = cols; } int GetMaxRows() const { return m_maxRows; } int GetMaxCols() const { return m_maxCols; } - // tool(bar) size - // ------------- - + // get/set the size of the bitmaps used by the toolbar: should be called + // before adding any tools to the toolbar virtual void SetToolBitmapSize(const wxSize& size) { m_defaultWidth = size.x; m_defaultHeight = size.y; }; virtual wxSize GetToolBitmapSize() const { return wxSize(m_defaultWidth, m_defaultHeight); } - // After the toolbar has initialized, this is the size the tools take up - virtual wxSize GetMaxSize() const; - - // The button size (in some implementations) is bigger than the bitmap size: this returns - // the total button size. + // the button size in some implementations is bigger than the bitmap size: + // get the total button size (by default the same as bitmap size) virtual wxSize GetToolSize() const - { return wxSize(m_defaultWidth, m_defaultHeight); } ; + { return GetToolBitmapSize(); } ; - // Handle wxToolBar events - // ----------------------- + // returns a (non separator) tool containing the point (x, y) or NULL if + // there is no tool at this point (corrdinates are client) + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, + wxCoord y) const = 0; + + // event handlers + // -------------- // NB: these functions are deprecated, use EVT_TOOL_XXX() instead! // Only allow toggle if returns TRUE. Call when left button up. - virtual bool OnLeftClick(int toolIndex, bool toggleDown); + virtual bool OnLeftClick(int id, bool toggleDown); // Call when right button down. - virtual void OnRightClick(int toolIndex, long x, long y); + virtual void OnRightClick(int id, long x, long y); // Called when the mouse cursor enters a tool bitmap. // Argument is -1 if mouse is exiting the toolbar. - virtual void OnMouseEnter(int toolIndex); + virtual void OnMouseEnter(int id); // more deprecated functions // ------------------------- @@ -255,103 +367,75 @@ public: virtual void SetDefaultSize(const wxSize& size) { SetToolBitmapSize(size); } virtual wxSize GetDefaultSize() const { return GetToolBitmapSize(); } virtual wxSize GetDefaultButtonSize() const { return GetToolSize(); } - void GetMaxSize ( long * width, long * height ) const - { wxSize maxSize(GetMaxSize()); *width = maxSize.x; *height = maxSize.y; } #endif // WXWIN_COMPATIBILITY // implementation only from now on // ------------------------------- - wxList& GetTools() const { return (wxList&) m_tools; } + size_t GetToolsCount() const { return m_tools.GetCount(); } - // Lay the tools out - virtual void LayoutTools(); - - // Add all the buttons: required for Win95. - virtual bool CreateTools() { return TRUE; } - - void Command(wxCommandEvent& event); - - // SCROLLING: this has to be copied from wxScrolledWindow since wxToolBarBase - // inherits from wxControl. This could have been put into wxToolBarSimple, - // but we might want any derived toolbar class to be scrollable. - - // Number of pixels per user unit (0 or -1 for no scrollbar) - // Length of virtual canvas in user units - virtual void SetScrollbars(int horizontal, int vertical, - int x_length, int y_length, - int x_pos = 0, int y_pos = 0); + void OnIdle(wxIdleEvent& event); - // Physically scroll the window - virtual void Scroll(int x_pos, int y_pos); - virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const; - virtual void EnableScrolling(bool x_scrolling, bool y_scrolling); - virtual void AdjustScrollbars(); + // Do the toolbar button updates (check for EVT_UPDATE_UI handlers) + virtual void DoToolbarUpdates(); - // Prepare the DC by translating it according to the current scroll position - virtual void PrepareDC(wxDC& dc); +protected: + // to implement in derived classes + // ------------------------------- - int GetScrollPageSize(int orient) const ; - void SetScrollPageSize(int orient, int pageSize); + // the tool is not yet inserted into m_tools list when this function is + // called and will only be added to it if this function succeeds + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool) = 0; - // Get the view start - virtual void ViewStart(int *x, int *y) const; + // the tool is still in m_tools list when this function is called, it will + // only be deleted from it if it succeeds + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool) = 0; - // Actual size in pixels when scrolling is taken into account - virtual void GetVirtualSize(int *x, int *y) const; + // called when the tools enabled flag changes + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable) = 0; - // Do the toolbar button updates (check for EVT_UPDATE_UI handlers) - virtual void DoToolbarUpdates(); + // called when the tool is toggled + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle) = 0; - // event handlers - void OnScroll(wxScrollEvent& event); - void OnSize(wxSizeEvent& event); - void OnIdle(wxIdleEvent& event); + // called when the tools "can be toggled" flag changes + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle) = 0; -protected: - wxList m_tools; + // the functions to create toolbar tools + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) = 0; + virtual wxToolBarToolBase *CreateTool(wxControl *control) = 0; - int m_maxRows; - int m_maxCols; - long m_maxWidth, - m_maxHeight; + // helper functions + // ---------------- - int m_currentTool; // Tool where mouse currently is - int m_pressedTool; // Tool where mouse pressed + // find the tool by id + wxToolBarToolBase *FindById(int id) const; - int m_xMargin; - int m_yMargin; - int m_toolPacking; - int m_toolSeparation; + // the list of all our tools + wxToolBarToolsList m_tools; - wxCoord m_defaultWidth; - wxCoord m_defaultHeight; + // the offset of the first tool + int m_xMargin; + int m_yMargin; -public: - //////////////////////////////////////////////////////////////////////// - //// IMPLEMENTATION + // the maximum number of toolbar rows/columns + int m_maxRows; + int m_maxCols; - // Calculate scroll increment - virtual int CalcScrollInc(wxScrollEvent& event); + // the tool packing and separation + int m_toolPacking, + m_toolSeparation; - //////////////////////////////////////////////////////////////////////// - //// PROTECTED DATA -protected: - int m_xScrollPixelsPerLine; - int m_yScrollPixelsPerLine; - bool m_xScrollingEnabled; - bool m_yScrollingEnabled; - int m_xScrollPosition; - int m_yScrollPosition; - bool m_calcScrolledOffset; // If TRUE, wxCanvasDC uses scrolled offsets - int m_xScrollLines; - int m_yScrollLines; - int m_xScrollLinesPerPage; - int m_yScrollLinesPerPage; + // the size of the toolbar bitmaps + wxCoord m_defaultWidth, m_defaultHeight; private: DECLARE_EVENT_TABLE() - DECLARE_ABSTRACT_CLASS(wxToolBarBase) }; #endif diff --git a/include/wx/tbarmsw.h b/include/wx/tbarmsw.h deleted file mode 100644 index 4b9d761fcf..0000000000 --- a/include/wx/tbarmsw.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _WX_TBARMSW_H_BASE_ -#define _WX_TBARMSW_H_BASE_ - -#if defined(__WXMSW__) -#include "wx/msw/tbarmsw.h" -#elif defined(__WXMOTIF__) -#include "wx/motif/tbarmsw.h" -#elif defined(__WXGTK__) -#include "wx/gtk/tbarmsw.h" -#endif - -#endif - // _WX_TBARMSW_H_BASE_ diff --git a/include/wx/tbarsmpl.h b/include/wx/tbarsmpl.h index 54e1354a77..4fed98e06a 100644 --- a/include/wx/tbarsmpl.h +++ b/include/wx/tbarsmpl.h @@ -1,81 +1,173 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: tbarsmpl.h +// Name: wx/tbarsmpl.h // Purpose: wxToolBarSimple class // Author: Julian Smart -// Modified by: +// Modified by: VZ on 14.12.99 during wxToolBar classes reorganization // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_TBARSMPLH__ #define _WX_TBARSMPLH__ #ifdef __GNUG__ -#pragma interface "tbarsmpl.h" + #pragma interface "tbarsmpl.h" #endif -#include "wx/defs.h" - -#if wxUSE_TOOLBAR - -#include "wx/bitmap.h" -#include "wx/list.h" #include "wx/tbarbase.h" +#if wxUSE_TOOLBAR_SIMPLE + class WXDLLEXPORT wxMemoryDC; -WXDLLEXPORT_DATA(extern const wxChar*) wxToolBarNameStr; -WXDLLEXPORT_DATA(extern const wxSize) wxDefaultSize; -WXDLLEXPORT_DATA(extern const wxPoint) wxDefaultPosition; +// ---------------------------------------------------------------------------- +// wxToolBarSimple is a generic toolbar implementation in pure wxWindows +// ---------------------------------------------------------------------------- -// XView can't cope properly with panels that behave like canvases -// (e.g. no scrollbars in panels) class WXDLLEXPORT wxToolBarSimple : public wxToolBarBase { - DECLARE_DYNAMIC_CLASS(wxToolBarSimple) - - public: - - wxToolBarSimple(void); - inline wxToolBarSimple(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER|wxTB_HORIZONTAL, - const wxString& name = wxToolBarNameStr) - { - Create(parent, id, pos, size, style, name); - } - ~wxToolBarSimple(void); - - bool Create(wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, - long style = wxNO_BORDER|wxTB_HORIZONTAL, const wxString& name = wxToolBarNameStr); - - void OnPaint(wxPaintEvent& event); - void OnSize(wxSizeEvent& event); - void OnMouseEvent(wxMouseEvent& event); - void OnKillFocus(wxFocusEvent& event); - - // Handle wxToolBar events - - virtual void DrawTool(wxDC& dc, wxMemoryDC& memDC, wxToolBarTool *tool); - virtual void ToggleTool(int toolIndex, bool toggle); // toggle is TRUE if toggled on - - virtual void SpringUpButton(int index); - - virtual void LayoutTools(); - - // The post-tool-addition call - virtual bool Realize() { LayoutTools(); return TRUE; }; +public: + // ctors and dtor + wxToolBarSimple() { Init(); } + + wxToolBarSimple(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER | wxTB_HORIZONTAL, + const wxString& name = wxToolBarNameStr) + { + Init(); + + Create(parent, id, pos, size, style, name); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER | wxTB_HORIZONTAL, + const wxString& name = wxToolBarNameStr); + + virtual ~wxToolBarSimple(); + + // override/implement base class virtuals + virtual wxToolBarToolBase *AddTool + ( + int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + bool toggle, + wxCoord xPos, + wxCoord yPos = -1, + wxObject *clientData = NULL, + const wxString& helpString1 = wxEmptyString, + const wxString& helpString2 = wxEmptyString + ); + + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const; + + virtual bool Realize(); + + virtual void SetRows(int nRows); + + // implementation from now on + // -------------------------- + + // SCROLLING: this has to be copied from wxScrolledWindow since + // wxToolBarBase inherits from wxControl. This could have been put into + // wxToolBarSimple, but we might want any derived toolbar class to be + // scrollable. + + // Number of pixels per user unit (0 or -1 for no scrollbar) + // Length of virtual canvas in user units + virtual void SetScrollbars(int horizontal, int vertical, + int x_length, int y_length, + int x_pos = 0, int y_pos = 0); + + // Physically scroll the window + virtual void Scroll(int x_pos, int y_pos); + virtual void GetScrollPixelsPerUnit(int *x_unit, int *y_unit) const; + virtual void EnableScrolling(bool x_scrolling, bool y_scrolling); + virtual void AdjustScrollbars(); + + // Prepare the DC by translating it according to the current scroll position + virtual void PrepareDC(wxDC& dc); + + int GetScrollPageSize(int orient) const ; + void SetScrollPageSize(int orient, int pageSize); + + // Get the view start + virtual void ViewStart(int *x, int *y) const; + + // Actual size in pixels when scrolling is taken into account + virtual void GetVirtualSize(int *x, int *y) const; + + int CalcScrollInc(wxScrollEvent& event); + + // event handlers + void OnPaint(wxPaintEvent& event); + void OnSize(wxSizeEvent& event); + void OnMouseEvent(wxMouseEvent& event); + void OnKillFocus(wxFocusEvent& event); + void OnScroll(wxScrollEvent& event); protected: - int m_currentRowsOrColumns; - long m_lastX, m_lastY; - -DECLARE_EVENT_TABLE() - + // common part of all ctors + void Init(); + + // implement base class pure virtuals + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + + // helpers + void DrawTool(wxToolBarToolBase *tool); + virtual void DrawTool(wxDC& dc, wxToolBarToolBase *tool); + virtual void SpringUpButton(int index); + + int m_currentRowsOrColumns; + + int m_pressedTool, m_currentTool; + + wxCoord m_lastX, m_lastY; + wxCoord m_maxWidth, m_maxHeight; + wxCoord m_xPos, m_yPos; + + // scrolling data + int m_xScrollPixelsPerLine; + int m_yScrollPixelsPerLine; + bool m_xScrollingEnabled; + bool m_yScrollingEnabled; + int m_xScrollPosition; + int m_yScrollPosition; + bool m_calcScrolledOffset; // If TRUE, wxCanvasDC uses scrolled offsets + int m_xScrollLines; + int m_yScrollLines; + int m_xScrollLinesPerPage; + int m_yScrollLinesPerPage; + +private: + DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS(wxToolBarSimple) }; -#endif // wxUSE_TOOLBAR +#endif // wxUSE_TOOLBAR_SIMPLE + #endif // _WX_TBARSMPLH__ diff --git a/include/wx/toolbar.h b/include/wx/toolbar.h index 600a4743af..db17a682c1 100644 --- a/include/wx/toolbar.h +++ b/include/wx/toolbar.h @@ -14,29 +14,32 @@ #include "wx/tbarbase.h" // the base class for all toolbars -#if 0 -class WXDLLEXPORT wxToolBar : public wxControl -{ -}; -#endif // 0 - -#if defined(__WXMSW__) && defined(__WIN95__) -# include "wx/msw/tbar95.h" -#elif defined(__WXMSW__) -# include "wx/msw/tbarmsw.h" -#elif defined(__WXMOTIF__) -# include "wx/motif/toolbar.h" -#elif defined(__WXGTK__) -# include "wx/gtk/tbargtk.h" -#elif defined(__WXQT__) -# include "wx/qt/tbarqt.h" -#elif defined(__WXMAC__) -# include "wx/mac/toolbar.h" -#elif defined(__WXPM__) -# include "wx/os2/toolbar.h" -#elif defined(__WXSTUBS__) -# include "wx/stubs/toolbar.h" -#endif +#if wxUSE_TOOLBAR + #if !wxUSE_TOOLBAR_NATIVE + // the wxToolBarSimple is *the* toolbar class in this case + #define wxToolBarSimple wxToolBar + + #include "wx/tbarsmpl.h" + #else // wxUSE_TOOLBAR_NATIVE + #if defined(__WXMSW__) && defined(__WIN95__) + #include "wx/msw/tbar95.h" + #elif defined(__WXMSW__) + #include "wx/msw/tbarmsw.h" + #elif defined(__WXMOTIF__) + #include "wx/motif/toolbar.h" + #elif defined(__WXGTK__) + #include "wx/gtk/tbargtk.h" + #elif defined(__WXQT__) + #include "wx/qt/tbarqt.h" + #elif defined(__WXMAC__) + #include "wx/mac/toolbar.h" + #elif defined(__WXPM__) + #include "wx/os2/toolbar.h" + #elif defined(__WXSTUBS__) + #include "wx/stubs/toolbar.h" + #endif + #endif // !wxUSE_TOOLBAR_NATIVE/wxUSE_TOOLBAR_NATIVE +#endif // wxUSE_TOOLBAR #endif // _WX_TOOLBAR_H_BASE_ diff --git a/src/common/tbarbase.cpp b/src/common/tbarbase.cpp index 2f855b19a8..7864d099dd 100644 --- a/src/common/tbarbase.cpp +++ b/src/common/tbarbase.cpp @@ -1,27 +1,35 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: tbarbase.cpp -// Purpose: Toolbar base classes +// Name: common/tbarbase.cpp +// Purpose: wxToolBarBase implementation // Author: Julian Smart -// Modified by: +// Modified by: VZ at 11.12.99 (wxScrollableToolBar splitted off) // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "tbarbase.h" + #pragma implementation "tbarbase.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #ifndef WX_PRECOMP -#include "wx/wx.h" + #include "wx/wx.h" #endif #include "wx/frame.h" @@ -35,744 +43,503 @@ #include "wx/tbarbase.h" -IMPLEMENT_ABSTRACT_CLASS(wxToolBarBase, wxControl) -IMPLEMENT_DYNAMIC_CLASS(wxToolBarTool, wxObject) - -BEGIN_EVENT_TABLE(wxToolBarBase, wxControl) - EVT_SCROLL(wxToolBarBase::OnScroll) - EVT_SIZE(wxToolBarBase::OnSize) - EVT_IDLE(wxToolBarBase::OnIdle) -END_EVENT_TABLE() - -// Keep a list of all toolbars created, so you can tell whether a toolbar -// is still valid: a tool may have quit the toolbar. -static wxList gs_ToolBars; - -#ifdef __WXGTK__ -wxToolBarTool::wxToolBarTool(wxToolBar *owner, int theIndex, - const wxBitmap& theBitmap1, const wxBitmap& theBitmap2, - bool toggle, wxObject *clientData, - const wxString& helpS1, const wxString& helpS2, - GtkWidget *pixmap ) -#else -wxToolBarTool::wxToolBarTool(int theIndex, - const wxBitmap& theBitmap1, const wxBitmap& theBitmap2, bool toggle, - long xPos, long yPos, const wxString& helpS1, const wxString& helpS2) -#endif -{ - m_toolStyle = wxTOOL_STYLE_BUTTON; -#ifdef __WXGTK__ - m_owner = owner; - m_pixmap = pixmap; - m_item = (GtkWidget*) NULL; - m_clientData = clientData; - m_x = 0; - m_y = 0; -#else - m_clientData = NULL; - m_x = xPos; - m_y = yPos; +// ---------------------------------------------------------------------------- +// wxWindows macros +// ---------------------------------------------------------------------------- + +#if !USE_SHARED_LIBRARY + BEGIN_EVENT_TABLE(wxToolBarBase, wxControl) + EVT_IDLE(wxToolBarBase::OnIdle) + END_EVENT_TABLE() #endif - m_index = theIndex; - m_isToggle = toggle; - m_toggleState = FALSE; - m_enabled = TRUE; - m_bitmap1 = theBitmap1; - m_bitmap2 = theBitmap2; - m_width = m_height = 0; - m_deleteSecondBitmap = FALSE; - if (m_bitmap1.Ok()) - { - m_width = m_bitmap1.GetWidth()+2; - m_height = m_bitmap1.GetHeight()+2; - } - m_shortHelpString = helpS1; - m_longHelpString = helpS2; - m_control = (wxControl*) NULL; -} -wxToolBarTool::wxToolBarTool(wxControl *control) -{ - m_toolStyle = wxTOOL_STYLE_CONTROL; - m_control = control; - m_index = control->GetId(); -} +#include "wx/listimpl.cpp" -wxToolBarTool::~wxToolBarTool() -{ -/* - if (m_deleteSecondBitmap && m_bitmap2) - delete m_bitmap2; -*/ -} +WX_DEFINE_LIST(wxToolBarToolsList); +// ============================================================================ +// implementation +// ============================================================================ -// class wxToolBar +// ---------------------------------------------------------------------------- +// wxToolBarToolBase +// ---------------------------------------------------------------------------- -wxToolBarBase::wxToolBarBase(void) : m_tools(wxKEY_INTEGER) +bool wxToolBarToolBase::Enable(bool enable) { - gs_ToolBars.Append(this); + if ( m_enabled == enable ) + return FALSE; - m_maxRows = 1; - m_maxCols = 32000; - m_maxWidth = 0; - m_maxHeight = 0; - m_defaultWidth = 16; - m_defaultHeight = 15; - m_xMargin = 0; - m_yMargin = 0; - m_toolPacking = 1; - m_toolSeparation = 5; - m_currentTool = -1; + m_enabled = enable; - m_xScrollPixelsPerLine = 0; - m_yScrollPixelsPerLine = 0; - m_xScrollingEnabled = TRUE; - m_yScrollingEnabled = TRUE; - m_xScrollPosition = 0; - m_yScrollPosition = 0; - m_calcScrolledOffset = TRUE; - m_xScrollLines = 0; - m_yScrollLines = 0; - m_xScrollLinesPerPage = 0; - m_yScrollLinesPerPage = 0; + return TRUE; } -wxToolBarBase::~wxToolBarBase () +bool wxToolBarToolBase::Toggle(bool toggle) { - gs_ToolBars.DeleteObject(this); + wxASSERT_MSG( m_isToggle, _T("can't toggle this tool") ); + + if ( m_toggled == toggle ) + return FALSE; - for ( wxNode *node = m_tools.First(); node; node = node->Next() ) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - delete tool; - } + m_toggled = toggle; + + return TRUE; } -// Only allow toggle if returns TRUE -bool wxToolBarBase::OnLeftClick(int toolIndex, bool toggleDown) +bool wxToolBarToolBase::SetToggle(bool toggle) { - wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, toolIndex); - event.SetEventObject(this); - event.SetExtraLong((long) toggleDown); + if ( m_isToggle == toggle ) + return FALSE; - // Send events to this toolbar instead (and thence up the window hierarchy) - GetEventHandler()->ProcessEvent(event); + m_isToggle = toggle; return TRUE; } -// Call when right button down. -void wxToolBarBase::OnRightClick(int toolIndex, - long WXUNUSED(x), - long WXUNUSED(y)) +bool wxToolBarToolBase::SetShortHelp(const wxString& help) { - wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, toolIndex); - event.SetEventObject(this); - event.SetInt(toolIndex); + if ( m_shortHelpString == help ) + return FALSE; - GetEventHandler()->ProcessEvent(event); + m_shortHelpString = help; + + return TRUE; } -// Called when the mouse cursor enters a tool bitmap (no button pressed). -// Argument is -1 if mouse is exiting the toolbar. -// Note that for this event, the id of the window is used, -// and the integer parameter of wxCommandEvent is used to retrieve -// the tool id. -void wxToolBarBase::OnMouseEnter ( int toolIndex ) +bool wxToolBarToolBase::SetLongHelp(const wxString& help) { - wxCommandEvent event(wxEVT_COMMAND_TOOL_ENTER, GetId()); - event.SetEventObject(this); - event.SetInt(toolIndex); + if ( m_longHelpString == help ) + return FALSE; - GetEventHandler()->ProcessEvent(event); + m_longHelpString = help; + + return TRUE; } -// If pushedBitmap is NULL, a reversed version of bitmap is -// created and used as the pushed/toggled image. -// If toggle is TRUE, the button toggles between the two states. -wxToolBarTool *wxToolBarBase::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& pushedBitmap, - bool toggle, wxCoord xPos, wxCoord yPos, wxObject *clientData, - const wxString& helpString1, const wxString& helpString2) +wxToolBarToolBase::~wxToolBarToolBase() { -#ifdef __WXGTK__ - wxToolBarTool *tool = new wxToolBarTool( (wxToolBar*)this, index, bitmap, pushedBitmap, toggle, - (wxObject*) NULL, helpString1, helpString2); -#else - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, pushedBitmap, toggle, xPos, yPos, helpString1, helpString2); -#endif - tool->m_clientData = clientData; - - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; +} - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; +// ---------------------------------------------------------------------------- +// wxToolBarBase adding/deleting items +// ---------------------------------------------------------------------------- - // Calculate reasonable max size in case Layout() not called - if ((tool->m_x + bitmap.GetWidth() + m_xMargin) > m_maxWidth) - m_maxWidth = (tool->m_x + bitmap.GetWidth() + m_xMargin); +wxToolBarBase::wxToolBarBase() +{ + // the list owns the pointers + m_tools.DeleteContents(TRUE); - if ((tool->m_y + bitmap.GetHeight() + m_yMargin) > m_maxHeight) - m_maxHeight = (tool->m_y + bitmap.GetHeight() + m_yMargin); + m_xMargin = m_yMargin = 0; - m_tools.Append((long)index, tool); - return tool; + m_maxRows = m_maxCols = 0; } -void wxToolBarBase::AddSeparator () +wxToolBarToolBase *wxToolBarBase::AddTool(int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + bool toggle, + wxCoord WXUNUSED(xPos), + wxCoord WXUNUSED(yPos), + wxObject *clientData, + const wxString& helpString1, + const wxString& helpString2) { - wxToolBarTool *tool = new wxToolBarTool; - tool->m_index = -1; - tool->m_toolStyle = wxTOOL_STYLE_SEPARATOR; - m_tools.Append(-1, tool); + return InsertTool(GetToolsCount(), id, bitmap, pushedBitmap, + toggle, clientData, helpString1, helpString2); } -void wxToolBarBase::ClearTools() +wxToolBarToolBase *wxToolBarBase::InsertTool(size_t pos, + int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + bool toggle, + wxObject *clientData, + const wxString& helpString1, + const wxString& helpString2) { - m_pressedTool = m_currentTool = -1; - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - wxNode *nextNode = node->Next(); - delete tool; - delete node; - node = nextNode; - } + wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL, + _T("invalid position in wxToolBar::InsertTool()") ); + + wxToolBarToolBase *tool = CreateTool(id, bitmap, pushedBitmap, toggle, + clientData, helpString1, helpString2); + + if ( !tool || !DoInsertTool(pos, tool) ) + { + delete tool; + + return NULL; + } + + m_tools.Insert(pos, tool); + + return tool; } -void wxToolBarBase::EnableTool(int index, bool enable) +wxToolBarToolBase *wxToolBarBase::AddControl(wxControl *control) { - wxNode *node = m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool) - tool->m_enabled = enable; - } + return InsertControl(GetToolsCount(), control); } -void wxToolBarBase::ToggleTool(int WXUNUSED(index), - bool WXUNUSED(toggle)) +wxToolBarToolBase *wxToolBarBase::InsertControl(size_t pos, wxControl *control) { + wxCHECK_MSG( control, (wxToolBarToolBase *)NULL, + _T("toolbar: can't insert NULL control") ); + + wxCHECK_MSG( control->GetParent() == this, (wxToolBarToolBase *)NULL, + _T("control must have toolbar as parent") ); + + wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL, + _T("invalid position in wxToolBar::InsertControl()") ); + + wxToolBarToolBase *tool = CreateTool(control); + + if ( !tool || !DoInsertTool(pos, tool) ) + { + delete tool; + + return NULL; + } + + m_tools.Insert(pos, tool); + + return tool; } -void wxToolBarBase::SetToggle(int index, bool value) +wxToolBarToolBase *wxToolBarBase::AddSeparator() { - wxNode *node=m_tools.Find((long)index); - if (node){ - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_isToggle = value; - } + return InsertSeparator(GetToolsCount()); } -bool wxToolBarBase::GetToolState(int index) const +wxToolBarToolBase *wxToolBarBase::InsertSeparator(size_t pos) { - wxNode *node = m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool) + wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL, + _T("invalid position in wxToolBar::InsertSeparator()") ); + + wxToolBarToolBase *tool = CreateTool(wxID_SEPARATOR, + wxNullBitmap, wxNullBitmap, + FALSE, (wxObject *)NULL, + wxEmptyString, wxEmptyString); + + if ( !tool || !DoInsertTool(pos, tool) ) { - return tool->m_toggleState; + delete tool; + + return NULL; } - else return FALSE; - } - else return FALSE; + + m_tools.Insert(pos, tool); + + return tool; } -bool wxToolBarBase::GetToolEnabled(int index) const +wxToolBarToolBase *wxToolBarBase::RemoveTool(int id) { - wxNode *node = m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool) + size_t pos = 0; + wxToolBarToolsList::Node *node; + for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) { - return tool->m_enabled; + if ( node->GetData()->GetId() == id ) + break; + + pos++; } - else return FALSE; - } - else return FALSE; -} -wxObject *wxToolBarBase::GetToolClientData(int index) const -{ - wxNode *node = m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool) + if ( !node ) { - return tool->m_clientData; + // don't give any error messages - sometimes we might call RemoveTool() + // without knowing whether the tool is or not in the toolbar + return (wxToolBarToolBase *)NULL; } - else return NULL; - } - else return NULL; -} -void wxToolBarBase::SetToolShortHelp(int index, const wxString& helpString) -{ - wxNode *node=m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_shortHelpString = helpString; - } -} + wxToolBarToolBase *tool = node->GetData(); + if ( !DoDeleteTool(pos, tool) ) + { + return (wxToolBarToolBase *)NULL; + } -wxString wxToolBarBase::GetToolShortHelp(int index) const -{ - wxNode *node=m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - return tool->m_shortHelpString; - } - else - return wxString(""); -} + // the node would delete the data, so set it to NULL to avoid this + node->SetData(NULL); -void wxToolBarBase::SetToolLongHelp(int index, const wxString& helpString) -{ - wxNode *node=m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_longHelpString = helpString; - } -} + m_tools.DeleteNode(node); -wxString wxToolBarBase::GetToolLongHelp(int index) const -{ - wxNode *node=m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - return tool->m_longHelpString; - } - else - return wxString(""); + return tool; } -wxToolBarTool *wxToolBarBase::FindToolForPosition(long x, long y) const +bool wxToolBarBase::DeleteToolByPos(size_t pos) { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if ((x >= tool->m_x) && (y >= tool->m_y) && - (x <= (tool->m_x + tool->GetWidth())) && - (y <= (tool->m_y + tool->GetHeight()))) - return tool; + wxCHECK_MSG( pos < GetToolsCount(), FALSE, + _T("invalid position in wxToolBar::DeleteToolByPos()") ); - node = node->Next(); - } - return NULL; -} + wxToolBarToolsList::Node *node = m_tools.Item(pos); -wxSize wxToolBarBase::GetMaxSize ( void ) const -{ - return wxSize(m_maxWidth, m_maxHeight); + if ( !DoDeleteTool(pos, node->GetData()) ) + { + return FALSE; + } + + m_tools.DeleteNode(node); + + return TRUE; } -// 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 wxToolBarBase::SetMargins(int x, int y) +bool wxToolBarBase::DeleteTool(int id) { - m_xMargin = x; - m_yMargin = y; + size_t pos = 0; + wxToolBarToolsList::Node *node; + for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) + { + if ( node->GetData()->GetId() == id ) + break; + + pos++; + } + + if ( !node || !DoDeleteTool(pos, node->GetData()) ) + { + return FALSE; + } + + m_tools.DeleteNode(node); + + return TRUE; } -void wxToolBarBase::SetToolPacking(int packing) +wxToolBarToolBase *wxToolBarBase::FindById(int id) const { - m_toolPacking = packing; + wxToolBarToolBase *tool = (wxToolBarToolBase *)NULL; + + for ( wxToolBarToolsList::Node *node = m_tools.GetFirst(); + node; + node = node->GetNext() ) + { + tool = node->GetData(); + if ( tool->GetId() == id ) + { + // found + break; + } + } + + return tool; } -void wxToolBarBase::SetToolSeparation(int separation) +void wxToolBarBase::ClearTools() { - m_toolSeparation = separation; + m_tools.Clear(); } -void wxToolBarBase::Command(wxCommandEvent& WXUNUSED(event)) +bool wxToolBarBase::Realize() { + return TRUE; } -void wxToolBarBase::LayoutTools() +wxToolBarBase::~wxToolBarBase() { } +// ---------------------------------------------------------------------------- +// wxToolBarBase tools state +// ---------------------------------------------------------------------------- -// SCROLLING IMPLEMENTATION - -/* - * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line) - * noUnitsX/noUnitsY: : no. units per scrollbar - */ -void wxToolBarBase::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY, - int noUnitsX, int noUnitsY, - int xPos, int yPos) +void wxToolBarBase::EnableTool(int id, bool enable) { - m_xScrollPixelsPerLine = pixelsPerUnitX; - m_yScrollPixelsPerLine = pixelsPerUnitY; - m_xScrollLines = noUnitsX; - m_yScrollLines = noUnitsY; - - int w, h; - GetSize(&w, &h); - - // Recalculate scroll bar range and position - if (m_xScrollLines > 0) - { - m_xScrollPosition = xPos; - SetScrollPos (wxHORIZONTAL, m_xScrollPosition, TRUE); - } - else + wxToolBarToolBase *tool = FindById(id); + if ( tool ) { - SetScrollbar(wxHORIZONTAL, 0, 0, 0, FALSE); - m_xScrollPosition = 0; + if ( tool->Enable(enable) ) + { + DoEnableTool(tool, enable); + } } +} - if (m_yScrollLines > 0) - { - m_yScrollPosition = yPos; - SetScrollPos (wxVERTICAL, m_yScrollPosition, TRUE); - } - else +void wxToolBarBase::ToggleTool(int id, bool toggle) +{ + wxToolBarToolBase *tool = FindById(id); + if ( tool && tool->CanBeToggled() ) { - SetScrollbar(wxVERTICAL, 0, 0, 0, FALSE); - m_yScrollPosition = 0; + if ( tool->Toggle(toggle) ) + { + DoToggleTool(tool, toggle); + } } - AdjustScrollbars(); - Refresh(); -#ifdef __WXMSW__ - ::UpdateWindow ((HWND) GetHWND()); -#endif } - -void wxToolBarBase::OnScroll(wxScrollEvent& event) -{ - int orient = event.GetOrientation(); - - int nScrollInc = CalcScrollInc(event); - if (nScrollInc == 0) - return; - - if (orient == wxHORIZONTAL) - { - int newPos = m_xScrollPosition + nScrollInc; - SetScrollPos(wxHORIZONTAL, newPos, TRUE ); - } - else - { - int newPos = m_yScrollPosition + nScrollInc; - SetScrollPos(wxVERTICAL, newPos, TRUE ); - } - - if (orient == wxHORIZONTAL) - { - if (m_xScrollingEnabled) - ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, NULL); - else - Refresh(); - } - else - { - if (m_yScrollingEnabled) - ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, NULL); - else - Refresh(); - } - - if (orient == wxHORIZONTAL) - { - m_xScrollPosition += nScrollInc; - } - else - { - m_yScrollPosition += nScrollInc; - } - -} - -int wxToolBarBase::CalcScrollInc(wxScrollEvent& event) -{ - int pos = event.GetPosition(); - int orient = event.GetOrientation(); - - int nScrollInc = 0; - switch (event.GetEventType()) - { - case wxEVT_SCROLL_TOP: - { - if (orient == wxHORIZONTAL) - nScrollInc = - m_xScrollPosition; - else - nScrollInc = - m_yScrollPosition; - break; - } - case wxEVT_SCROLL_BOTTOM: - { - if (orient == wxHORIZONTAL) - nScrollInc = m_xScrollLines - m_xScrollPosition; - else - nScrollInc = m_yScrollLines - m_yScrollPosition; - break; - } - case wxEVT_SCROLL_LINEUP: - { - nScrollInc = -1; - break; - } - case wxEVT_SCROLL_LINEDOWN: - { - nScrollInc = 1; - break; - } - case wxEVT_SCROLL_PAGEUP: - { - if (orient == wxHORIZONTAL) - nScrollInc = -GetScrollPageSize(wxHORIZONTAL); - else - nScrollInc = -GetScrollPageSize(wxVERTICAL); - break; - } - case wxEVT_SCROLL_PAGEDOWN: +void wxToolBarBase::SetToggle(int id, bool toggle) +{ + wxToolBarToolBase *tool = FindById(id); + if ( tool ) { - if (orient == wxHORIZONTAL) - nScrollInc = GetScrollPageSize(wxHORIZONTAL); - else - nScrollInc = GetScrollPageSize(wxVERTICAL); - break; + if ( tool->SetToggle(toggle) ) + { + DoSetToggle(tool, toggle); + } } - case wxEVT_SCROLL_THUMBTRACK: +} + +void wxToolBarBase::SetToolShortHelp(int id, const wxString& help) +{ + wxToolBarToolBase *tool = FindById(id); + if ( tool ) { - if (orient == wxHORIZONTAL) - nScrollInc = pos - m_xScrollPosition; - else - nScrollInc = pos - m_yScrollPosition; - break; + (void)tool->SetShortHelp(help); } - default: +} + +void wxToolBarBase::SetToolLongHelp(int id, const wxString& help) +{ + wxToolBarToolBase *tool = FindById(id); + if ( tool ) { - break; + (void)tool->SetLongHelp(help); } - } - if (orient == wxHORIZONTAL) - { - int w, h; - GetClientSize(&w, &h); - - int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine; - int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 ); - if (noPositions < 0) - noPositions = 0; - - if ( (m_xScrollPosition + nScrollInc) < 0 ) - nScrollInc = -m_xScrollPosition; // As -ve as we can go - else if ( (m_xScrollPosition + nScrollInc) > noPositions ) - nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go - - return nScrollInc; - } - else - { - int w, h; - GetClientSize(&w, &h); - - int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine; - int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 ); - if (noPositions < 0) - noPositions = 0; - - if ( (m_yScrollPosition + nScrollInc) < 0 ) - nScrollInc = -m_yScrollPosition; // As -ve as we can go - else if ( (m_yScrollPosition + nScrollInc) > noPositions ) - nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go - - return nScrollInc; - } -} - -// Adjust the scrollbars - new version. -void wxToolBarBase::AdjustScrollbars() -{ - int w, h; - GetClientSize(&w, &h); - - // Recalculate scroll bar range and position - if (m_xScrollLines > 0) - { - int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine; - int newRange = (int) ( ((nMaxWidth)/(float)m_xScrollPixelsPerLine) + 0.5 ); - if (newRange < 0) - newRange = 0; - - m_xScrollPosition = wxMin(newRange, m_xScrollPosition); - - // Calculate page size i.e. number of scroll units you get on the - // current client window - int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 ); - if (noPagePositions < 1) - noPagePositions = 1; - - SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, newRange); - SetScrollPageSize(wxHORIZONTAL, noPagePositions); - } - if (m_yScrollLines > 0) - { - int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine; - int newRange = (int) ( ((nMaxHeight)/(float)m_yScrollPixelsPerLine) + 0.5 ); - if (newRange < 0) - newRange = 0; - - m_yScrollPosition = wxMin(newRange, m_yScrollPosition); - - // Calculate page size i.e. number of scroll units you get on the - // current client window - int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 ); - if (noPagePositions < 1) - noPagePositions = 1; - - SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, newRange); - SetScrollPageSize(wxVERTICAL, noPagePositions); - } -} - -// Default OnSize resets scrollbars, if any -void wxToolBarBase::OnSize(wxSizeEvent& WXUNUSED(event)) -{ -#if wxUSE_CONSTRAINTS - if (GetAutoLayout()) - Layout(); -#endif - - AdjustScrollbars(); } -// Prepare the DC by translating it according to the current scroll position -void wxToolBarBase::PrepareDC(wxDC& dc) +wxObject *wxToolBarBase::GetToolClientData(int id) const { - dc.SetDeviceOrigin(- m_xScrollPosition * m_xScrollPixelsPerLine, - m_yScrollPosition * m_yScrollPixelsPerLine); + wxToolBarToolBase *tool = FindById(id); + + return tool ? tool->GetClientData() : (wxObject *)NULL; } -void wxToolBarBase::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const +bool wxToolBarBase::GetToolState(int id) const { - *x_unit = m_xScrollPixelsPerLine; - *y_unit = m_yScrollPixelsPerLine; + wxToolBarToolBase *tool = FindById(id); + wxCHECK_MSG( tool, FALSE, _T("no such tool") ); + + return tool->IsToggled(); } -int wxToolBarBase::GetScrollPageSize(int orient) const +bool wxToolBarBase::GetToolEnabled(int id) const { - if ( orient == wxHORIZONTAL ) - return m_xScrollLinesPerPage; - else - return m_yScrollLinesPerPage; + wxToolBarToolBase *tool = FindById(id); + wxCHECK_MSG( tool, FALSE, _T("no such tool") ); + + return tool->IsEnabled(); } -void wxToolBarBase::SetScrollPageSize(int orient, int pageSize) +wxString wxToolBarBase::GetToolShortHelp(int id) const { - if ( orient == wxHORIZONTAL ) - m_xScrollLinesPerPage = pageSize; - else - m_yScrollLinesPerPage = pageSize; + wxToolBarToolBase *tool = FindById(id); + wxCHECK_MSG( tool, _T(""), _T("no such tool") ); + + return tool->GetShortHelp(); } -/* - * Scroll to given position (scroll position, not pixel position) - */ -void wxToolBarBase::Scroll (int x_pos, int y_pos) +wxString wxToolBarBase::GetToolLongHelp(int id) const { - int old_x, old_y; - ViewStart (&old_x, &old_y); - if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y))) - return; + wxToolBarToolBase *tool = FindById(id); + wxCHECK_MSG( tool, _T(""), _T("no such tool") ); - if (x_pos > -1) - { - m_xScrollPosition = x_pos; - SetScrollPos (wxHORIZONTAL, x_pos, TRUE); - } - if (y_pos > -1) - { - m_yScrollPosition = y_pos; - SetScrollPos (wxVERTICAL, y_pos, TRUE); - } - Refresh(); -#ifdef __WXMSW__ - UpdateWindow ((HWND) GetHWND()); -#endif + return tool->GetLongHelp(); } -void wxToolBarBase::EnableScrolling (bool x_scroll, bool y_scroll) +// ---------------------------------------------------------------------------- +// wxToolBarBase geometry +// ---------------------------------------------------------------------------- + +void wxToolBarBase::SetMargins(int x, int y) { - m_xScrollingEnabled = x_scroll; - m_yScrollingEnabled = y_scroll; + m_xMargin = x; + m_yMargin = y; } -void wxToolBarBase::GetVirtualSize (int *x, int *y) const +void wxToolBarBase::SetRows(int WXUNUSED(nRows)) { - *x = m_xScrollPixelsPerLine * m_xScrollLines; - *y = m_yScrollPixelsPerLine * m_yScrollLines; + // nothing } -// Where the current view starts from -void wxToolBarBase::ViewStart (int *x, int *y) const +// ---------------------------------------------------------------------------- +// event processing +// ---------------------------------------------------------------------------- + +// Only allow toggle if returns TRUE +bool wxToolBarBase::OnLeftClick(int id, bool toggleDown) { - *x = m_xScrollPosition; - *y = m_yScrollPosition; + wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, id); + event.SetEventObject(this); + event.SetExtraLong((long) toggleDown); + + // Send events to this toolbar instead (and thence up the window hierarchy) + GetEventHandler()->ProcessEvent(event); + + return TRUE; } -void wxToolBarBase::OnIdle(wxIdleEvent& -#ifdef __WXGTK__ - WXUNUSED(event) -#else - event -#endif - ) +// Call when right button down. +void wxToolBarBase::OnRightClick(int id, + long WXUNUSED(x), + long WXUNUSED(y)) { -#ifndef __WXGTK__ - wxWindow::OnIdle(event); -#endif + wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, id); + event.SetEventObject(this); + event.SetInt(id); + + GetEventHandler()->ProcessEvent(event); +} +// Called when the mouse cursor enters a tool bitmap (no button pressed). +// Argument is -1 if mouse is exiting the toolbar. +// Note that for this event, the id of the window is used, +// and the integer parameter of wxCommandEvent is used to retrieve +// the tool id. +void wxToolBarBase::OnMouseEnter(int id) +{ + wxCommandEvent event(wxEVT_COMMAND_TOOL_ENTER, GetId()); + event.SetEventObject(this); + event.SetInt(id); + + (void)GetEventHandler()->ProcessEvent(event); + + wxToolBarToolBase *tool = FindById(id); + if ( !tool || !tool->GetLongHelp() ) + return; + + wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); + if ( !frame ) + return; + + frame->SetStatusText(tool->GetLongHelp()); +} + +// ---------------------------------------------------------------------------- +// UI updates +// ---------------------------------------------------------------------------- + +void wxToolBarBase::OnIdle(wxIdleEvent& event) +{ DoToolbarUpdates(); + + event.Skip(); } // Do the toolbar button updates (check for EVT_UPDATE_UI handlers) void wxToolBarBase::DoToolbarUpdates() { - wxEvtHandler* evtHandler = GetEventHandler() ; + wxEvtHandler* evtHandler = GetEventHandler(); - wxNode* node = GetTools().First(); - while (node) + for ( wxToolBarToolsList::Node* node = m_tools.GetFirst(); + node; + node = node->GetNext() ) { - wxToolBarTool* tool = (wxToolBarTool* ) node->Data(); + int id = node->GetData()->GetId(); - wxUpdateUIEvent event(tool->m_index); + wxUpdateUIEvent event(id); event.SetEventObject(this); - if (evtHandler->ProcessEvent(event)) + if ( evtHandler->ProcessEvent(event) ) { - if (event.GetSetEnabled()) - EnableTool(tool->m_index, event.GetEnabled()); - if (event.GetSetChecked()) - ToggleTool(tool->m_index, event.GetChecked()); -/* - if (event.GetSetText()) + if ( event.GetSetEnabled() ) + EnableTool(id, event.GetEnabled()); + if ( event.GetSetChecked() ) + ToggleTool(id, event.GetChecked()); +#if 0 + if ( event.GetSetText() ) // Set tooltip? -*/ +#endif // 0 } - - node = node->Next(); } } -#endif +#endif // wxUSE_TOOLBAR diff --git a/src/common/tbarsmpl.cpp b/src/common/tbarsmpl.cpp deleted file mode 100644 index db6caf0cf2..0000000000 --- a/src/common/tbarsmpl.cpp +++ /dev/null @@ -1,461 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: tbarsmpl.cpp -// Purpose: wxToolBarSimple -// Author: Julian Smart -// Modified by: -// Created: 04/01/98 -// RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license -///////////////////////////////////////////////////////////////////////////// - -#ifdef __GNUG__ -#pragma implementation "tbarsmpl.h" -#endif - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/settings.h" -#include "wx/window.h" -#include "wx/dcclient.h" -#include "wx/dcmemory.h" -#endif - -#if wxUSE_TOOLBAR - -#include "wx/tbarsmpl.h" - -IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxToolBarBase) - -BEGIN_EVENT_TABLE(wxToolBarSimple, wxToolBarBase) - EVT_SIZE(wxToolBarSimple::OnSize) - EVT_PAINT(wxToolBarSimple::OnPaint) - EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus) - EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent) -END_EVENT_TABLE() - -wxToolBarSimple::wxToolBarSimple(void) -{ - m_currentRowsOrColumns = 0; - m_lastX = 0; - m_lastY = 0; -} - -bool wxToolBarSimple::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, - const wxString& name ) -{ - if ( ! wxWindow::Create(parent, id, pos, size, style, name) ) - return FALSE; - - // Set it to grey (or other 3D face colour) - wxSystemSettings settings; - SetBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_3DFACE)); - - if ( GetWindowStyleFlag() & wxTB_VERTICAL ) - { m_lastX = 7; m_lastY = 3; } - else - { m_lastX = 3; m_lastY = 7; } - m_maxWidth = m_maxHeight = 0; - m_pressedTool = m_currentTool = -1; - m_xMargin = 0; - m_yMargin = 0; - m_toolPacking = 1; - m_toolSeparation = 5; - SetCursor(*wxSTANDARD_CURSOR); - - return TRUE; -} - -wxToolBarSimple::~wxToolBarSimple () -{ -} - -void wxToolBarSimple::OnPaint (wxPaintEvent& WXUNUSED(event)) -{ - wxPaintDC dc(this); - PrepareDC(dc); - - static int count = 0; - // Prevent reentry of OnPaint which would cause wxMemoryDC errors. - if ( count > 0 ) - return; - count++; - - wxMemoryDC mem_dc; - - for ( wxNode *node = m_tools.First(); node; node = node->Next() ) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_toolStyle == wxTOOL_STYLE_BUTTON) - DrawTool(dc, mem_dc, tool); - } - - count--; -} - -void wxToolBarSimple::OnSize ( wxSizeEvent& event ) -{ - wxToolBarBase::OnSize(event); -} - -void wxToolBarSimple::OnKillFocus (wxFocusEvent& WXUNUSED(event)) -{ - OnMouseEnter(m_pressedTool = m_currentTool = -1); -} - -void wxToolBarSimple::OnMouseEvent ( wxMouseEvent & event ) -{ - wxCoord x, y; - event.GetPosition(&x, &y); - wxToolBarTool *tool = FindToolForPosition(x, y); - - if (event.LeftDown()) - { - CaptureMouse(); - } - if (event.LeftUp()) - { - ReleaseMouse(); - } - - if (!tool) - { - if (m_currentTool > -1) - { - if (event.LeftIsDown()) - SpringUpButton(m_currentTool); - m_currentTool = -1; - OnMouseEnter(-1); - } - return; - } - - if (!event.IsButton()) - { - if (tool->m_index != m_currentTool) - { - // If the left button is kept down and moved over buttons, - // press those buttons. - if (event.LeftIsDown() && tool->m_enabled) - { - SpringUpButton(m_currentTool); - tool->m_toggleState = !tool->m_toggleState; - wxMemoryDC *dc2 = new wxMemoryDC; - wxClientDC dc(this); - DrawTool(dc, *dc2, tool); - delete dc2; - } - m_currentTool = tool->m_index; - OnMouseEnter(tool->m_index); - } - return; - } - - // Left button pressed. - if (event.LeftDown() && tool->m_enabled) - { - if (tool->m_isToggle) - { - tool->m_toggleState = !tool->m_toggleState; - } - - wxMemoryDC *dc2 = new wxMemoryDC; - wxClientDC dc(this); - DrawTool(dc, *dc2, tool); - delete dc2; - - } - else if (event.RightDown()) - { - OnRightClick(tool->m_index, x, y); - } - - // 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 (event.LeftUp() && tool->m_enabled && - (tool->m_toggleState || tool->m_isToggle)) - { - if (!tool->m_isToggle) - tool->m_toggleState = FALSE; - - // Pass the OnLeftClick event to tool - if (!OnLeftClick(tool->m_index, tool->m_toggleState) && tool->m_isToggle) - { - // If it was a toggle, and OnLeftClick says No Toggle allowed, - // then change it back - tool->m_toggleState = !tool->m_toggleState; - } - - wxClientDC dc(this); - wxMemoryDC *dc2 = new wxMemoryDC; - DrawTool(dc, *dc2, tool); - delete dc2; - } -} - -void wxToolBarSimple::DrawTool(wxDC& dc, wxMemoryDC& memDC, wxToolBarTool *tool) -{ - PrepareDC(dc); - - wxPen dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID); - wxPen white_pen("WHITE", 1, wxSOLID); - wxPen black_pen("BLACK", 1, wxSOLID); - - wxBitmap *bitmap = tool->m_toggleState ? (& tool->m_bitmap2) : (& tool->m_bitmap1); - - if (bitmap && bitmap->Ok()) - { -#ifndef __WXGTK__ - if (bitmap->GetPalette()) - memDC.SetPalette(*bitmap->GetPalette()); -#endif - - int ax = (int)tool->m_x, - ay = (int)tool->m_y, - bx = (int)(tool->m_x+tool->GetWidth()), - by = (int)(tool->m_y+tool->GetHeight()); - - memDC.SelectObject(*bitmap); - if (m_windowStyle & wxTB_3DBUTTONS) - { - dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1)); - dc.Blit((ax+1), (ay+1), (bx-ax-2), (by-ay-2), &memDC, 0, 0); - wxPen * old_pen = & dc.GetPen(); - dc.SetPen( white_pen ); - dc.DrawLine(ax,(by-1),ax,ay); - dc.DrawLine(ax,ay,(bx-1),ay); - dc.SetPen( dark_grey_pen ); - dc.DrawLine((bx-1),(ay+1),(bx-1),(by-1)); - dc.DrawLine((bx-1),(by-1),(ax+1),(by-1)); - dc.SetPen( black_pen ); - dc.DrawLine(bx,ay,bx,by); - dc.DrawLine(bx,by,ax,by); - dc.SetPen( *old_pen ); - dc.DestroyClippingRegion(); - // Select bitmap out of the DC - } - else - { - dc.Blit(tool->m_x, tool->m_y, - bitmap->GetWidth(), bitmap->GetHeight(), - &memDC, 0, 0); - } - memDC.SelectObject(wxNullBitmap); -#ifndef __WXGTK__ - memDC.SetPalette(wxNullPalette); -#endif - } - // No second bitmap, so draw a thick line around bitmap, or invert if mono - else if (tool->m_toggleState) - { - bool drawBorder = FALSE; -#ifdef __X__ // X doesn't invert properly on colour - drawBorder = wxColourDisplay(); -#else // Inversion works fine under Windows - drawBorder = FALSE; -#endif - - if (!drawBorder) - { - memDC.SelectObject(tool->m_bitmap1); - dc.Blit(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight(), - &memDC, 0, 0, wxSRC_INVERT); - memDC.SelectObject(wxNullBitmap); - } - else - { - if (m_windowStyle & wxTB_3DBUTTONS) - { - int ax = (int)tool->m_x, - ay = (int)tool->m_y, - bx = (int)(tool->m_x+tool->GetWidth()), - by = (int)(tool->m_y+tool->GetHeight()); - - memDC.SelectObject(tool->m_bitmap1); - dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1)); - dc.Blit((ax+2), (ay+2), (bx-ax-2), (by-ay-2), &memDC, 0, 0); - wxPen * old_pen = & dc.GetPen(); - dc.SetPen( black_pen ); - dc.DrawLine(ax,(by-1),ax,ay); - dc.DrawLine(ax,ay,(bx-1),ay); - dc.SetPen( dark_grey_pen ); - dc.DrawLine((ax+1),(by-2),(ax+1),(ay+1)); - dc.DrawLine((ax+1),(ay+1),(bx-2),(ay+1)); - dc.SetPen( white_pen ); - dc.DrawLine(bx,ay,bx,by); - dc.DrawLine(bx,by,ax,by); - dc.SetPen( *old_pen ); - dc.DestroyClippingRegion(); - memDC.SelectObject(wxNullBitmap); - } - else - { - long x = tool->m_x; - long y = tool->m_y; - long w = tool->m_bitmap1.GetWidth(); - long h = tool->m_bitmap1.GetHeight(); - wxPen thick_black_pen("BLACK", 3, wxSOLID); - - memDC.SelectObject(tool->m_bitmap1); - dc.SetClippingRegion(tool->m_x, tool->m_y, w, h); - dc.Blit(tool->m_x, tool->m_y, w, h, - &memDC, 0, 0); - dc.SetPen(thick_black_pen); - dc.SetBrush(*wxTRANSPARENT_BRUSH); - dc.DrawRectangle(x, y, w-1, h-1); - dc.DestroyClippingRegion(); - memDC.SelectObject(wxNullBitmap); - } - } - } -} - -void wxToolBarSimple::ToggleTool(int index, bool toggle) -{ - wxNode *node = (wxNode*) NULL; - node = m_tools.Find((long)index); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool && tool->m_isToggle) - { - bool oldState = tool->m_toggleState; - tool->m_toggleState = toggle; - - if (oldState != toggle) - { - wxMemoryDC memDC; - wxClientDC dc(this); - DrawTool(dc, memDC, tool); - } - } - } -} - -// 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 wxToolBarSimple::SpringUpButton(int index) -{ - wxNode *node = (wxNode*) NULL; - node=m_tools.Find((long)index); - if (node) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool && !tool->m_isToggle && tool->m_toggleState){ - tool->m_toggleState = FALSE; - wxMemoryDC memDC; - wxClientDC dc(this); - DrawTool(dc, memDC, tool); - } - else if (tool && tool->m_isToggle){ - tool->m_toggleState = !tool->m_toggleState; - wxMemoryDC memDC; - wxClientDC dc(this); - DrawTool(dc, memDC, tool); - } - } -} - -void wxToolBarSimple::LayoutTools(void) -{ - m_currentRowsOrColumns = 0; - m_lastX = m_xMargin; - m_lastY = m_yMargin; - int maxToolWidth = 0; - int maxToolHeight = 0; - m_maxWidth = 0; - m_maxHeight = 0; - - // Find the maximum tool width and height - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->GetWidth() > maxToolWidth) - maxToolWidth = (int)tool->GetWidth(); - if (tool->GetHeight() > maxToolHeight) - maxToolHeight = (int)tool->GetHeight(); - node = node->Next(); - } - - int separatorSize = m_toolSeparation; - - node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) - { - if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) - { - if (m_currentRowsOrColumns >= m_maxCols) - m_lastY += separatorSize; - else - m_lastX += separatorSize; - } - else - { - if (m_currentRowsOrColumns >= m_maxRows) - m_lastX += separatorSize; - else - m_lastY += separatorSize; - } - } - else if (tool->m_toolStyle == wxTOOL_STYLE_BUTTON) - { - if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) - { - if (m_currentRowsOrColumns >= m_maxCols) - { - m_currentRowsOrColumns = 0; - m_lastX = m_xMargin; - m_lastY += maxToolHeight + m_toolPacking; - } - tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); - tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); - - m_lastX += maxToolWidth + m_toolPacking; - } - else - { - if (m_currentRowsOrColumns >= m_maxRows) - { - m_currentRowsOrColumns = 0; - m_lastX += (maxToolWidth + m_toolPacking); - m_lastY = m_yMargin; - } - tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); - tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); - - m_lastY += maxToolHeight + m_toolPacking; - } - m_currentRowsOrColumns ++; - } - - if (m_lastX > m_maxWidth) - m_maxWidth = m_lastX; - if (m_lastY > m_maxHeight) - m_maxHeight = m_lastY; - - node = node->Next(); - } - if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) - m_maxWidth += maxToolWidth; - else - m_maxHeight += maxToolHeight; - - m_maxWidth += m_xMargin; - m_maxHeight += m_yMargin; -} - - -#endif diff --git a/src/generic/tbarsmpl.cpp b/src/generic/tbarsmpl.cpp new file mode 100644 index 0000000000..e2a28f3f7e --- /dev/null +++ b/src/generic/tbarsmpl.cpp @@ -0,0 +1,992 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: generic/tbarsmpl.cpp +// Purpose: wxToolBarSimple +// Author: Julian Smart +// Modified by: VZ on 14.12.99 during wxToolBarSimple reorganization +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "tbarsmpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_TOOLBAR_SIMPLE + +#ifndef WX_PRECOMP + #include "wx/settings.h" + #include "wx/window.h" + #include "wx/dcclient.h" + #include "wx/dcmemory.h" +#endif + +#include "wx/tbarsmpl.h" + +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxToolBarToolSimple : public wxToolBarToolBase +{ +public: + wxToolBarToolSimple(wxToolBarSimple *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) + : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString) + { + } + + wxToolBarToolSimple(wxToolBarSimple *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + } + + void SetSize(const wxSize& size) + { + m_width = size.x; + m_height = size.y; + } + + long GetWidth() const { return m_width; } + long GetHeight() const { return m_height; } + + wxCoord m_x; + wxCoord m_y; + wxCoord m_width; + wxCoord m_height; +}; + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxToolBarSimple, wxControl) + +BEGIN_EVENT_TABLE(wxToolBarSimple, wxToolBarBase) + EVT_SIZE(wxToolBarSimple::OnSize) + EVT_SCROLL(wxToolBarSimple::OnScroll) + EVT_PAINT(wxToolBarSimple::OnPaint) + EVT_KILL_FOCUS(wxToolBarSimple::OnKillFocus) + EVT_MOUSE_EVENTS(wxToolBarSimple::OnMouseEvent) +END_EVENT_TABLE() + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// tool bar tools creation +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBarSimple::CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarToolSimple(this, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString); +} + +wxToolBarToolBase *wxToolBarSimple::CreateTool(wxControl *control) +{ + return new wxToolBarToolSimple(this, control); +} + +// ---------------------------------------------------------------------------- +// wxToolBarSimple creation +// ---------------------------------------------------------------------------- + +void wxToolBarSimple::Init() +{ + m_currentRowsOrColumns = 0; + + m_lastX = + m_lastY = 0; + + m_maxWidth = + m_maxHeight = 0; + + m_pressedTool = + m_currentTool = -1; + + m_xPos = + m_yPos = -1; + + m_toolPacking = 1; + m_toolSeparation = 5; + + m_defaultWidth = 16; + m_defaultHeight = 15; +} + +wxToolBarToolBase *wxToolBarSimple::AddTool(int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + bool toggle, + wxCoord xPos, + wxCoord yPos, + wxObject *clientData, + const wxString& helpString1, + const wxString& helpString2) +{ + // rememeber the position for DoInsertTool() + m_xPos = xPos; + m_yPos = yPos; + + return wxToolBarBase::AddTool(id, bitmap, pushedBitmap, toggle, + xPos, yPos, clientData, + helpString1, helpString2); +} + +bool wxToolBarSimple::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) +{ + wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase; + + wxCHECK_MSG( !tool->IsControl(), FALSE, + _T("generic wxToolBarSimple doesn't support controls") ); + + tool->m_x = m_xPos; + if ( tool->m_x == -1 ) + tool->m_x = m_xMargin; + + tool->m_y = m_yPos; + if ( tool->m_y == -1 ) + tool->m_y = m_yMargin; + + tool->SetSize(GetToolSize()); + + if ( tool->IsButton() ) + { + // Calculate reasonable max size in case Layout() not called + if ((tool->m_x + tool->GetBitmap1().GetWidth() + m_xMargin) > m_maxWidth) + m_maxWidth = (tool->m_x + tool->GetWidth() + m_xMargin); + + if ((tool->m_y + tool->GetBitmap1().GetHeight() + m_yMargin) > m_maxHeight) + m_maxHeight = (tool->m_y + tool->GetHeight() + m_yMargin); + } + + return TRUE; +} + +bool wxToolBarSimple::DoDeleteTool(size_t WXUNUSED(pos), + wxToolBarToolBase *tool) +{ + // VZ: didn't test whether it works, but why not... + tool->Detach(); + + Refresh(); + + return TRUE; +} + +bool wxToolBarSimple::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + if ( !wxWindow::Create(parent, id, pos, size, style, name) ) + return FALSE; + + // Set it to grey (or other 3D face colour) + wxSystemSettings settings; + SetBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_3DFACE)); + + if ( GetWindowStyleFlag() & wxTB_VERTICAL ) + { + m_lastX = 7; + m_lastY = 3; + + m_maxRows = 32000; // a lot + m_maxCols = 1; + } + else + { + m_lastX = 3; + m_lastY = 7; + + m_maxRows = 1; + m_maxCols = 32000; // a lot + } + + SetCursor(*wxSTANDARD_CURSOR); + + return TRUE; +} + +wxToolBarSimple::~wxToolBarSimple() +{ +} + +bool wxToolBarSimple::Realize() +{ + m_currentRowsOrColumns = 0; + m_lastX = m_xMargin; + m_lastY = m_yMargin; + m_maxWidth = 0; + m_maxHeight = 0; + + int maxToolWidth = 0; + int maxToolHeight = 0; + + // Find the maximum tool width and height + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while ( node ) + { + wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData(); + if ( tool->GetWidth() > maxToolWidth ) + maxToolWidth = tool->GetWidth(); + if (tool->GetHeight() > maxToolHeight) + maxToolHeight = tool->GetHeight(); + + node = node->GetNext(); + } + + int separatorSize = m_toolSeparation; + + node = m_tools.GetFirst(); + while ( node ) + { + wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData(); + if ( tool->IsSeparator() ) + { + if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) + { + if (m_currentRowsOrColumns >= m_maxCols) + m_lastY += separatorSize; + else + m_lastX += separatorSize; + } + else + { + if (m_currentRowsOrColumns >= m_maxRows) + m_lastX += separatorSize; + else + m_lastY += separatorSize; + } + } + else if ( tool->IsButton() ) + { + if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) + { + if (m_currentRowsOrColumns >= m_maxCols) + { + m_currentRowsOrColumns = 0; + m_lastX = m_xMargin; + m_lastY += maxToolHeight + m_toolPacking; + } + tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); + tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); + + m_lastX += maxToolWidth + m_toolPacking; + } + else + { + if (m_currentRowsOrColumns >= m_maxRows) + { + m_currentRowsOrColumns = 0; + m_lastX += (maxToolWidth + m_toolPacking); + m_lastY = m_yMargin; + } + tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); + tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); + + m_lastY += maxToolHeight + m_toolPacking; + } + m_currentRowsOrColumns ++; + } + else + { + // TODO: support the controls + } + + if (m_lastX > m_maxWidth) + m_maxWidth = m_lastX; + if (m_lastY > m_maxHeight) + m_maxHeight = m_lastY; + + node = node->GetNext(); + } + + if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) + m_maxWidth += maxToolWidth; + else + m_maxHeight += maxToolHeight; + + m_maxWidth += m_xMargin; + m_maxHeight += m_yMargin; + + return TRUE; +} + +// ---------------------------------------------------------------------------- +// event handlers +// ---------------------------------------------------------------------------- + +void wxToolBarSimple::OnPaint (wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + PrepareDC(dc); + + static int count = 0; + // Prevent reentry of OnPaint which would cause wxMemoryDC errors. + if ( count > 0 ) + return; + count++; + + for ( wxToolBarToolsList::Node *node = m_tools.GetFirst(); + node; + node = node->GetNext() ) + { + wxToolBarToolBase *tool = node->GetData(); + if ( tool->IsButton() ) + DrawTool(dc, tool); + } + + count--; +} + +void wxToolBarSimple::OnSize (wxSizeEvent& WXUNUSED(event)) +{ +#if wxUSE_CONSTRAINTS + if (GetAutoLayout()) + Layout(); +#endif + + AdjustScrollbars(); +} + +void wxToolBarSimple::OnKillFocus(wxFocusEvent& WXUNUSED(event)) +{ + OnMouseEnter(m_pressedTool = m_currentTool = -1); +} + +void wxToolBarSimple::OnMouseEvent(wxMouseEvent & event) +{ + wxCoord x, y; + event.GetPosition(&x, &y); + wxToolBarToolSimple *tool = (wxToolBarToolSimple *)FindToolForPosition(x, y); + + if (event.LeftDown()) + { + CaptureMouse(); + } + if (event.LeftUp()) + { + ReleaseMouse(); + } + + if (!tool) + { + if (m_currentTool > -1) + { + if (event.LeftIsDown()) + SpringUpButton(m_currentTool); + m_currentTool = -1; + OnMouseEnter(-1); + } + return; + } + + if (!event.IsButton()) + { + if ( tool->GetId() != m_currentTool ) + { + // If the left button is kept down and moved over buttons, + // press those buttons. + if ( event.LeftIsDown() && tool->IsEnabled() ) + { + SpringUpButton(m_currentTool); + + if ( tool->CanBeToggled() ) + { + tool->Toggle(); + } + + DrawTool(tool); + } + + m_currentTool = tool->GetId(); + OnMouseEnter(m_currentTool); + } + return; + } + + // Left button pressed. + if ( event.LeftDown() && tool->IsEnabled() ) + { + if ( tool->CanBeToggled() ) + { + tool->Toggle(); + } + + DrawTool(tool); + } + else if (event.RightDown()) + { + OnRightClick(tool->GetId(), x, y); + } + + // 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 ( event.LeftUp() && tool->IsEnabled() ) + { + // Pass the OnLeftClick event to tool + if ( !OnLeftClick(tool->GetId(), tool->IsToggled()) && + tool->CanBeToggled() ) + { + // If it was a toggle, and OnLeftClick says No Toggle allowed, + // then change it back + tool->Toggle(); + } + + DrawTool(tool); + } +} + +// ---------------------------------------------------------------------------- +// drawing +// ---------------------------------------------------------------------------- + +void wxToolBarSimple::DrawTool(wxToolBarToolBase *tool) +{ + wxClientDC dc(this); + DrawTool(dc, tool); +} + +void wxToolBarSimple::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase) +{ + wxToolBarToolSimple *tool = (wxToolBarToolSimple *)toolBase; + + wxMemoryDC memDC; + PrepareDC(dc); + + wxPen dark_grey_pen(wxColour( 85,85,85 ), 1, wxSOLID); + wxPen white_pen("WHITE", 1, wxSOLID); + wxPen black_pen("BLACK", 1, wxSOLID); + + wxBitmap bitmap = tool->GetBitmap(); + + if ( bitmap.Ok() ) + { +#ifndef __WXGTK__ + if (bitmap.GetPalette()) + memDC.SetPalette(*bitmap.GetPalette()); +#endif + + int ax = (int)tool->m_x, + ay = (int)tool->m_y, + bx = (int)(tool->m_x+tool->GetWidth()), + by = (int)(tool->m_y+tool->GetHeight()); + + memDC.SelectObject(bitmap); + if (m_windowStyle & wxTB_3DBUTTONS) + { + dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1)); + dc.Blit((ax+1), (ay+1), (bx-ax-2), (by-ay-2), &memDC, 0, 0); + wxPen * old_pen = & dc.GetPen(); + dc.SetPen( white_pen ); + dc.DrawLine(ax,(by-1),ax,ay); + dc.DrawLine(ax,ay,(bx-1),ay); + dc.SetPen( dark_grey_pen ); + dc.DrawLine((bx-1),(ay+1),(bx-1),(by-1)); + dc.DrawLine((bx-1),(by-1),(ax+1),(by-1)); + dc.SetPen( black_pen ); + dc.DrawLine(bx,ay,bx,by); + dc.DrawLine(bx,by,ax,by); + dc.SetPen( *old_pen ); + dc.DestroyClippingRegion(); + // Select bitmap out of the DC + } + else + { + dc.Blit(tool->m_x, tool->m_y, + bitmap.GetWidth(), bitmap.GetHeight(), + &memDC, 0, 0); + } + memDC.SelectObject(wxNullBitmap); +#ifndef __WXGTK__ + memDC.SetPalette(wxNullPalette); +#endif + } + // No second bitmap, so draw a thick line around bitmap, or invert if mono + else if ( tool->IsToggled() ) + { + bool drawBorder = FALSE; +#ifdef __X__ // X doesn't invert properly on colour + drawBorder = wxColourDisplay(); +#else // Inversion works fine under Windows + drawBorder = FALSE; +#endif + + if (!drawBorder) + { + memDC.SelectObject(tool->GetBitmap1()); + dc.Blit(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight(), + &memDC, 0, 0, wxSRC_INVERT); + memDC.SelectObject(wxNullBitmap); + } + else + { + bitmap = tool->GetBitmap1(); + + if (m_windowStyle & wxTB_3DBUTTONS) + { + int ax = (int)tool->m_x, + ay = (int)tool->m_y, + bx = (int)(tool->m_x+tool->GetWidth()), + by = (int)(tool->m_y+tool->GetHeight()); + + memDC.SelectObject(bitmap); + dc.SetClippingRegion(ax, ay, (bx-ax+1), (by-ay+1)); + dc.Blit((ax+2), (ay+2), (bx-ax-2), (by-ay-2), &memDC, 0, 0); + wxPen * old_pen = & dc.GetPen(); + dc.SetPen( black_pen ); + dc.DrawLine(ax,(by-1),ax,ay); + dc.DrawLine(ax,ay,(bx-1),ay); + dc.SetPen( dark_grey_pen ); + dc.DrawLine((ax+1),(by-2),(ax+1),(ay+1)); + dc.DrawLine((ax+1),(ay+1),(bx-2),(ay+1)); + dc.SetPen( white_pen ); + dc.DrawLine(bx,ay,bx,by); + dc.DrawLine(bx,by,ax,by); + dc.SetPen( *old_pen ); + dc.DestroyClippingRegion(); + memDC.SelectObject(wxNullBitmap); + } + else + { + long x = tool->m_x; + long y = tool->m_y; + long w = bitmap.GetWidth(); + long h = bitmap.GetHeight(); + wxPen thick_black_pen("BLACK", 3, wxSOLID); + + memDC.SelectObject(bitmap); + dc.SetClippingRegion(tool->m_x, tool->m_y, w, h); + dc.Blit(tool->m_x, tool->m_y, w, h, + &memDC, 0, 0); + dc.SetPen(thick_black_pen); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRectangle(x, y, w-1, h-1); + dc.DestroyClippingRegion(); + memDC.SelectObject(wxNullBitmap); + } + } + } +} + +// ---------------------------------------------------------------------------- +// toolbar geometry +// ---------------------------------------------------------------------------- + +void wxToolBarSimple::SetRows(int nRows) +{ + wxCHECK_RET( nRows != 0, _T("max number of rows must be > 0") ); + + m_maxCols = (GetToolsCount() + nRows - 1) / nRows; + + AdjustScrollbars(); + Refresh(); +} + +wxToolBarToolBase *wxToolBarSimple::FindToolForPosition(wxCoord x, + wxCoord y) const +{ + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while (node) + { + wxToolBarToolSimple *tool = (wxToolBarToolSimple *)node->GetData(); + if ((x >= tool->m_x) && (y >= tool->m_y) && + (x <= (tool->m_x + tool->GetWidth())) && + (y <= (tool->m_y + tool->GetHeight()))) + { + return tool; + } + + node = node->GetNext(); + } + + return (wxToolBarToolBase *)NULL; +} + +// ---------------------------------------------------------------------------- +// tool state change handlers +// ---------------------------------------------------------------------------- + +void wxToolBarSimple::DoEnableTool(wxToolBarToolBase *tool, + bool WXUNUSED(enable)) +{ + DrawTool(tool); +} + +void wxToolBarSimple::DoToggleTool(wxToolBarToolBase *tool, + bool WXUNUSED(toggle)) +{ + DrawTool(tool); +} + +void wxToolBarSimple::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) +{ + // nothing to do +} + +// 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 wxToolBarSimple::SpringUpButton(int id) +{ + wxToolBarToolBase *tool = FindById(id); + + if ( tool && tool->CanBeToggled() ) + { + tool->Toggle(); + + DrawTool(tool); + } +} + +// ---------------------------------------------------------------------------- +// scrolling implementation +// ---------------------------------------------------------------------------- + +/* + * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line) + * noUnitsX/noUnitsY: : no. units per scrollbar + */ +void wxToolBarSimple::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY, + int noUnitsX, int noUnitsY, + int xPos, int yPos) +{ + m_xScrollPixelsPerLine = pixelsPerUnitX; + m_yScrollPixelsPerLine = pixelsPerUnitY; + m_xScrollLines = noUnitsX; + m_yScrollLines = noUnitsY; + + int w, h; + GetSize(&w, &h); + + // Recalculate scroll bar range and position + if (m_xScrollLines > 0) + { + m_xScrollPosition = xPos; + SetScrollPos (wxHORIZONTAL, m_xScrollPosition, TRUE); + } + else + { + SetScrollbar(wxHORIZONTAL, 0, 0, 0, FALSE); + m_xScrollPosition = 0; + } + + if (m_yScrollLines > 0) + { + m_yScrollPosition = yPos; + SetScrollPos (wxVERTICAL, m_yScrollPosition, TRUE); + } + else + { + SetScrollbar(wxVERTICAL, 0, 0, 0, FALSE); + m_yScrollPosition = 0; + } + AdjustScrollbars(); + Refresh(); + +#if 0 //def __WXMSW__ + ::UpdateWindow ((HWND) GetHWND()); +#endif +} + +void wxToolBarSimple::OnScroll(wxScrollEvent& event) +{ + int orient = event.GetOrientation(); + + int nScrollInc = CalcScrollInc(event); + if (nScrollInc == 0) + return; + + if (orient == wxHORIZONTAL) + { + int newPos = m_xScrollPosition + nScrollInc; + SetScrollPos(wxHORIZONTAL, newPos, TRUE ); + } + else + { + int newPos = m_yScrollPosition + nScrollInc; + SetScrollPos(wxVERTICAL, newPos, TRUE ); + } + + if (orient == wxHORIZONTAL) + { + if (m_xScrollingEnabled) + ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, NULL); + else + Refresh(); + } + else + { + if (m_yScrollingEnabled) + ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, NULL); + else + Refresh(); + } + + if (orient == wxHORIZONTAL) + { + m_xScrollPosition += nScrollInc; + } + else + { + m_yScrollPosition += nScrollInc; + } + +} + +int wxToolBarSimple::CalcScrollInc(wxScrollEvent& event) +{ + int pos = event.GetPosition(); + int orient = event.GetOrientation(); + + int nScrollInc = 0; + switch (event.GetEventType()) + { + case wxEVT_SCROLL_TOP: + { + if (orient == wxHORIZONTAL) + nScrollInc = - m_xScrollPosition; + else + nScrollInc = - m_yScrollPosition; + break; + } + case wxEVT_SCROLL_BOTTOM: + { + if (orient == wxHORIZONTAL) + nScrollInc = m_xScrollLines - m_xScrollPosition; + else + nScrollInc = m_yScrollLines - m_yScrollPosition; + break; + } + case wxEVT_SCROLL_LINEUP: + { + nScrollInc = -1; + break; + } + case wxEVT_SCROLL_LINEDOWN: + { + nScrollInc = 1; + break; + } + case wxEVT_SCROLL_PAGEUP: + { + if (orient == wxHORIZONTAL) + nScrollInc = -GetScrollPageSize(wxHORIZONTAL); + else + nScrollInc = -GetScrollPageSize(wxVERTICAL); + break; + } + case wxEVT_SCROLL_PAGEDOWN: + { + if (orient == wxHORIZONTAL) + nScrollInc = GetScrollPageSize(wxHORIZONTAL); + else + nScrollInc = GetScrollPageSize(wxVERTICAL); + break; + } + case wxEVT_SCROLL_THUMBTRACK: + { + if (orient == wxHORIZONTAL) + nScrollInc = pos - m_xScrollPosition; + else + nScrollInc = pos - m_yScrollPosition; + break; + } + default: + { + break; + } + } + if (orient == wxHORIZONTAL) + { + int w, h; + GetClientSize(&w, &h); + + int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine; + int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 ); + if (noPositions < 0) + noPositions = 0; + + if ( (m_xScrollPosition + nScrollInc) < 0 ) + nScrollInc = -m_xScrollPosition; // As -ve as we can go + else if ( (m_xScrollPosition + nScrollInc) > noPositions ) + nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go + + return nScrollInc; + } + else + { + int w, h; + GetClientSize(&w, &h); + + int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine; + int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 ); + if (noPositions < 0) + noPositions = 0; + + if ( (m_yScrollPosition + nScrollInc) < 0 ) + nScrollInc = -m_yScrollPosition; // As -ve as we can go + else if ( (m_yScrollPosition + nScrollInc) > noPositions ) + nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go + + return nScrollInc; + } +} + +// Adjust the scrollbars - new version. +void wxToolBarSimple::AdjustScrollbars() +{ + int w, h; + GetClientSize(&w, &h); + + // Recalculate scroll bar range and position + if (m_xScrollLines > 0) + { + int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine; + int newRange = (int) ( ((nMaxWidth)/(float)m_xScrollPixelsPerLine) + 0.5 ); + if (newRange < 0) + newRange = 0; + + m_xScrollPosition = wxMin(newRange, m_xScrollPosition); + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) + noPagePositions = 1; + + SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, newRange); + SetScrollPageSize(wxHORIZONTAL, noPagePositions); + } + if (m_yScrollLines > 0) + { + int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine; + int newRange = (int) ( ((nMaxHeight)/(float)m_yScrollPixelsPerLine) + 0.5 ); + if (newRange < 0) + newRange = 0; + + m_yScrollPosition = wxMin(newRange, m_yScrollPosition); + + // Calculate page size i.e. number of scroll units you get on the + // current client window + int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 ); + if (noPagePositions < 1) + noPagePositions = 1; + + SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, newRange); + SetScrollPageSize(wxVERTICAL, noPagePositions); + } +} + +// Prepare the DC by translating it according to the current scroll position +void wxToolBarSimple::PrepareDC(wxDC& dc) +{ + dc.SetDeviceOrigin(- m_xScrollPosition * m_xScrollPixelsPerLine, - m_yScrollPosition * m_yScrollPixelsPerLine); +} + +void wxToolBarSimple::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const +{ + *x_unit = m_xScrollPixelsPerLine; + *y_unit = m_yScrollPixelsPerLine; +} + +int wxToolBarSimple::GetScrollPageSize(int orient) const +{ + if ( orient == wxHORIZONTAL ) + return m_xScrollLinesPerPage; + else + return m_yScrollLinesPerPage; +} + +void wxToolBarSimple::SetScrollPageSize(int orient, int pageSize) +{ + if ( orient == wxHORIZONTAL ) + m_xScrollLinesPerPage = pageSize; + else + m_yScrollLinesPerPage = pageSize; +} + +/* + * Scroll to given position (scroll position, not pixel position) + */ +void wxToolBarSimple::Scroll (int x_pos, int y_pos) +{ + int old_x, old_y; + ViewStart (&old_x, &old_y); + if (((x_pos == -1) || (x_pos == old_x)) && ((y_pos == -1) || (y_pos == old_y))) + return; + + if (x_pos > -1) + { + m_xScrollPosition = x_pos; + SetScrollPos (wxHORIZONTAL, x_pos, TRUE); + } + if (y_pos > -1) + { + m_yScrollPosition = y_pos; + SetScrollPos (wxVERTICAL, y_pos, TRUE); + } + Refresh(); + +#if 0 //def __WXMSW__ + UpdateWindow ((HWND) GetHWND()); +#endif +} + +void wxToolBarSimple::EnableScrolling (bool x_scroll, bool y_scroll) +{ + m_xScrollingEnabled = x_scroll; + m_yScrollingEnabled = y_scroll; +} + +void wxToolBarSimple::GetVirtualSize (int *x, int *y) const +{ + *x = m_xScrollPixelsPerLine * m_xScrollLines; + *y = m_yScrollPixelsPerLine * m_yScrollLines; +} + +// Where the current view starts from +void wxToolBarSimple::ViewStart (int *x, int *y) const +{ + *x = m_xScrollPosition; + *y = m_yScrollPosition; +} + +#endif // wxUSE_TOOLBAR_SIMPLE diff --git a/src/gtk/tbargtk.cpp b/src/gtk/tbargtk.cpp index a297e9653c..aa7574feca 100644 --- a/src/gtk/tbargtk.cpp +++ b/src/gtk/tbargtk.cpp @@ -2,18 +2,27 @@ // Name: tbargtk.cpp // Purpose: GTK toolbar // Author: Robert Roebling +// Modified: 13.12.99 by VZ to derive from wxToolBarBase // RCS-ID: $Id$ // Copyright: (c) Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "tbargtk.h" + #pragma implementation "tbargtk.h" #endif #include "wx/toolbar.h" -#if wxUSE_TOOLBAR +#if wxUSE_TOOLBAR_NATIVE #include "wx/frame.h" @@ -21,57 +30,99 @@ #include "gdk/gdk.h" #include "gtk/gtk.h" -//----------------------------------------------------------------------------- -// idle system -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- +// idle system extern void wxapp_install_idle_handler(); extern bool g_isIdle; -//----------------------------------------------------------------------------- // data -//----------------------------------------------------------------------------- - extern bool g_blockEventsOnDrag; extern wxCursor g_globalCursor; +// ---------------------------------------------------------------------------- +// wxToolBarTool +// ---------------------------------------------------------------------------- + +class wxToolBarTool : public wxToolBarToolBase +{ +public: + wxToolBarTool(wxToolBar *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) + : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString) + { + Init(); + } + + wxToolBarTool(wxToolBar *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + Init(); + } + + GtkWidget *m_item; + GtkWidget *m_pixmap; + +protected: + void Init(); +}; + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) + +// ============================================================================ +// implementation +// ============================================================================ + //----------------------------------------------------------------------------- // "clicked" (internal from gtk_toolbar) //----------------------------------------------------------------------------- -static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool ) +static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), + wxToolBarTool *tool ) { if (g_isIdle) wxapp_install_idle_handler(); - if (tool->m_owner->m_blockNextEvent) + wxToolBar *tbar = (wxToolBar *)tool->GetToolBar(); + if ( tbar->m_blockNextEvent ) { - tool->m_owner->m_blockNextEvent = FALSE; + tbar->m_blockNextEvent = FALSE; return; } if (g_blockEventsOnDrag) return; - if (!tool->m_enabled) return; + if (!tool->IsEnabled()) return; - if (tool->m_isToggle) + if (tool->CanBeToggled()) { - tool->m_toggleState = !tool->m_toggleState; - - if (tool->m_bitmap2.Ok()) - { - wxBitmap bitmap = tool->m_bitmap1; - if (tool->m_toggleState) bitmap = tool->m_bitmap2; - + tool->Toggle(); + + wxBitmap bitmap = tool->GetBitmap(); + if ( bitmap.Ok() ) + { GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap ); - - GdkBitmap *mask = (GdkBitmap *) NULL; - if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap(); - + + GdkBitmap *mask = bitmap.GetMask() ? bitmap.GetMask()->GetBitmap() + : (GdkBitmap *)NULL; + gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask ); - } + } } - tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState ); + tbar->OnLeftClick( tool->GetId(), tool->IsToggled() ); } //----------------------------------------------------------------------------- @@ -79,18 +130,18 @@ static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *to //----------------------------------------------------------------------------- static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget), - GdkEventCrossing *WXUNUSED(gdk_event), wxToolBarTool *tool ) + GdkEventCrossing *WXUNUSED(gdk_event), + wxToolBarTool *tool ) { if (g_isIdle) wxapp_install_idle_handler(); if (g_blockEventsOnDrag) return TRUE; - - wxToolBar *tb = tool->m_owner; + wxToolBar *tb = (wxToolBar *)tool->GetToolBar(); #if (GTK_MINOR_VERSION == 0) /* we grey-out the tip text of disabled tool in GTK 1.0 */ - if (tool->m_enabled) + if (tool->IsEnabled()) { if (tb->m_fg->red != 0) { @@ -117,7 +168,7 @@ static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget), /* emit the event */ - tb->OnMouseEnter( tool->m_index ); + tb->OnMouseEnter( tool->GetId() ); return FALSE; } @@ -126,30 +177,51 @@ static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget), // InsertChild callback for wxToolBar //----------------------------------------------------------------------------- -static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent), wxWindow* WXUNUSED(child) ) +static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent), + wxWindow* WXUNUSED(child) ) { /* we don't do anything here but pray */ } -//----------------------------------------------------------------------------- -// wxToolBar -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxToolBarTool +// ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxToolBar,wxControl) +void wxToolBarTool::Init() +{ + m_item = + m_pixmap = (GtkWidget *)NULL; +} -BEGIN_EVENT_TABLE(wxToolBar, wxControl) - EVT_IDLE(wxToolBar::OnIdle) -END_EVENT_TABLE() +wxToolBarToolBase *wxToolBar::CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString); +} -wxToolBar::wxToolBar() +wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) { + return new wxToolBarTool(this, control); } -wxToolBar::wxToolBar( wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style, const wxString& name ) +//----------------------------------------------------------------------------- +// wxToolBar construction +//----------------------------------------------------------------------------- + +void wxToolBar::Init() { - Create( parent, id, pos, size, style, name ); + m_fg = + m_bg = (GdkColor *)NULL; + + m_toolbar = (GtkToolbar *)NULL; + + m_blockNextEvent = FALSE; } wxToolBar::~wxToolBar() @@ -158,36 +230,36 @@ wxToolBar::~wxToolBar() delete m_bg; } -bool wxToolBar::Create( wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style, const wxString& name ) +bool wxToolBar::Create( wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name ) { m_needParent = TRUE; - m_blockNextEvent = FALSE; m_insertCallback = (wxInsertChildFunction)wxInsertChildInToolBar; - if (!PreCreation( parent, pos, size ) || - !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) + if ( !PreCreation( parent, pos, size ) || + !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxToolBar creation failed") ); - return FALSE; - } - m_tools.DeleteContents( TRUE ); + return FALSE; + } - m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL, - GTK_TOOLBAR_ICONS ) ); + GtkOrientation orient = style & wxTB_VERTICAL ? GTK_ORIENTATION_VERTICAL + : GTK_ORIENTATION_HORIZONTAL; + m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( orient, GTK_TOOLBAR_ICONS ) ); - m_separation = 7; - gtk_toolbar_set_space_size( m_toolbar, m_separation ); - m_hasToolAlready = FALSE; + SetToolSeparation(7); if (style & wxTB_DOCKABLE) { m_widget = gtk_handle_box_new(); gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) ); gtk_widget_show( GTK_WIDGET(m_toolbar) ); - + #if (GTK_MINOR_VERSION > 0) if (style & wxTB_FLAT) gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE ); @@ -197,9 +269,9 @@ bool wxToolBar::Create( wxWindow *parent, wxWindowID id, { m_widget = GTK_WIDGET(m_toolbar); } - + gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE ); - + #if (GTK_MINOR_VERSION > 0) if (style & wxTB_FLAT) gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE ); @@ -210,32 +282,29 @@ bool wxToolBar::Create( wxWindow *parent, wxWindowID id, m_fg->green = 0; m_fg->blue = 0; gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_fg ); - + m_bg = new GdkColor; m_bg->red = 65535; m_bg->green = 65535; m_bg->blue = 50000; gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_bg ); - + #if (GTK_MINOR_VERSION > 0) gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar)->tooltips ); GtkStyle *g_style = - gtk_style_copy( - gtk_widget_get_style( - GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) ); - + gtk_style_copy( + gtk_widget_get_style( + GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) ); + g_style->bg[GTK_STATE_NORMAL] = *m_bg; gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style ); #else gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar)->tooltips, m_bg, m_fg ); #endif - m_xMargin = 0; - m_yMargin = 0; - m_parent->DoAddChild( this ); - + PostCreation(); Show( TRUE ); @@ -243,277 +312,182 @@ bool wxToolBar::Create( wxWindow *parent, wxWindowID id, return TRUE; } -bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown ) -{ - wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex ); - event.SetEventObject(this); - event.SetInt( toolIndex ); - event.SetExtraLong((long) toggleDown); - - GetEventHandler()->ProcessEvent(event); - - return TRUE; -} - -void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) ) +bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) { - wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex ); - event.SetEventObject( this ); - event.SetInt( toolIndex ); - - GetEventHandler()->ProcessEvent(event); -} + wxToolBarTool *tool = (wxToolBarTool *)toolBase; -void wxToolBar::OnMouseEnter( int toolIndex ) -{ - wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() ); - event.SetEventObject(this); - event.SetInt( toolIndex ); - - GetEventHandler()->ProcessEvent(event); -} + if ( tool->IsButton() ) + { + wxBitmap bitmap = tool->GetBitmap1(); -wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap, - const wxBitmap& pushedBitmap, bool toggle, - wxCoord WXUNUSED(xPos), wxCoord WXUNUSED(yPos), wxObject *clientData, - const wxString& helpString1, const wxString& helpString2 ) -{ - m_hasToolAlready = TRUE; - - wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL, - wxT("invalid bitmap for wxToolBar icon") ); + wxCHECK_MSG( bitmap.Ok(), FALSE, + wxT("invalid bitmap for wxToolBar icon") ); - wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL, - wxT("wxToolBar doesn't support GdkBitmap") ); + wxCHECK_MSG( bitmap.GetBitmap() == NULL, FALSE, + wxT("wxToolBar doesn't support GdkBitmap") ); - wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL, - wxT("wxToolBar::Add needs a wxBitmap") ); - - GtkWidget *tool_pixmap = (GtkWidget *)NULL; - - GdkPixmap *pixmap = bitmap.GetPixmap(); + wxCHECK_MSG( bitmap.GetPixmap() != NULL, FALSE, + wxT("wxToolBar::Add needs a wxBitmap") ); + + GtkWidget *tool_pixmap = (GtkWidget *)NULL; + + GdkPixmap *pixmap = bitmap.GetPixmap(); - GdkBitmap *mask = (GdkBitmap *)NULL; - if ( bitmap.GetMask() ) - mask = bitmap.GetMask()->GetBitmap(); - - tool_pixmap = gtk_pixmap_new( pixmap, mask ); + GdkBitmap *mask = (GdkBitmap *)NULL; + if ( bitmap.GetMask() ) + mask = bitmap.GetMask()->GetBitmap(); + + tool_pixmap = gtk_pixmap_new( pixmap, mask ); #if (GTK_MINOR_VERSION > 0) - gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE ); + gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE ); #endif - - gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 ); - - wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap, - toggle, clientData, - helpString1, helpString2, - tool_pixmap ); - - GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON - : GTK_TOOLBAR_CHILD_BUTTON; - - GtkWidget *item = gtk_toolbar_append_element - ( - m_toolbar, - ctype, - (GtkWidget *)NULL, - (const char *)NULL, - helpString1.mbc_str(), - "", - tool_pixmap, - (GtkSignalFunc)gtk_toolbar_callback, - (gpointer)tool - ); - - tool->m_item = item; - - GtkRequisition req; - (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req ); - m_width = req.width + m_xMargin; - m_height = req.height + 2*m_yMargin + 4; - - gtk_signal_connect( GTK_OBJECT(tool->m_item), - "enter_notify_event", - GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback), - (gpointer)tool ); - - m_tools.Append( tool ); + + gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 ); - return tool; -} + tool->m_pixmap = tool_pixmap; + } -bool wxToolBar::AddControl(wxControl *control) -{ - wxCHECK_MSG( control, FALSE, wxT("toolbar: can't insert NULL control") ); + switch ( tool->GetStyle() ) + { + case wxTOOL_STYLE_BUTTON: + tool->m_item = gtk_toolbar_insert_element + ( + m_toolbar, + tool->CanBeToggled() + ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON + : GTK_TOOLBAR_CHILD_BUTTON, + (GtkWidget *)NULL, + (const char *)NULL, + tool->GetShortHelp().mbc_str(), + "", // tooltip_private_text (?) + tool->m_pixmap, + (GtkSignalFunc)gtk_toolbar_callback, + (gpointer)tool, + pos + ); + + if ( !tool->m_item ) + { + wxFAIL_MSG( _T("gtk_toolbar_insert_element() failed") ); + + return FALSE; + } + + gtk_signal_connect( GTK_OBJECT(tool->m_item), + "enter_notify_event", + GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback), + (gpointer)tool ); + break; + + case wxTOOL_STYLE_SEPARATOR: + gtk_toolbar_append_space( m_toolbar ); + + // skip the rest + return TRUE; - wxCHECK_MSG( control->GetParent() == this, FALSE, - wxT("control must have toolbar as parent") ); + case wxTOOL_STYLE_CONTROL: + gtk_toolbar_insert_widget( + m_toolbar, + tool->GetControl()->m_widget, + (const char *) NULL, + (const char *) NULL, + pos + ); + break; + } - m_hasToolAlready = TRUE; - - wxToolBarTool *tool = new wxToolBarTool(control); - - tool -> m_item = NULL; - gtk_toolbar_append_widget( m_toolbar, control->m_widget, (const char *) NULL, (const char *) NULL ); - GtkRequisition req; (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req ); m_width = req.width + m_xMargin; m_height = req.height + 2*m_yMargin + 4; - m_tools.Append( tool ); - return TRUE; } -void wxToolBar::AddSeparator() +bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *toolBase) { - gtk_toolbar_append_space( m_toolbar ); -} + wxToolBarTool *tool = (wxToolBarTool *)toolBase; -bool wxToolBar::DeleteTool(int toolIndex) -{ - wxNode *node = m_tools.First(); - while (node) + switch ( tool->GetStyle() ) { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - if (tool->m_control) - tool->m_control->Destroy(); - else - gtk_widget_destroy( tool->m_item ); - m_tools.DeleteNode( node ); - - return TRUE; - } - node = node->Next(); - } + case wxTOOL_STYLE_CONTROL: + tool->GetControl()->Destroy(); + break; - return FALSE; -} + case wxTOOL_STYLE_BUTTON: + gtk_widget_destroy( tool->m_item ); + break; -void wxToolBar::ClearTools() -{ - wxFAIL_MSG( wxT("wxToolBar::ClearTools not implemented") ); -} + //case wxTOOL_STYLE_SEPARATOR: -- nothing to do + } -bool wxToolBar::Realize() -{ return TRUE; } -void wxToolBar::EnableTool(int toolIndex, bool enable) +// ---------------------------------------------------------------------------- +// wxToolBar tools state +// ---------------------------------------------------------------------------- + +void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable) { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - tool->m_enabled = enable; - #if (GTK_MINOR_VERSION > 0) - /* we don't disable the tools for GTK 1.0 as the bitmaps don't get - greyed anyway and this also disables tooltips */ - if (tool->m_item) - gtk_widget_set_sensitive( tool->m_item, enable ); + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + + /* we don't disable the tools for GTK 1.0 as the bitmaps don't get + greyed anyway and this also disables tooltips */ + if (tool->m_item) + gtk_widget_set_sensitive( tool->m_item, enable ); #endif - - return; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); } -void wxToolBar::ToggleTool( int toolIndex, bool toggle ) +void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle ) { - wxNode *node = m_tools.First(); - while (node) + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + + GtkWidget *item = tool->m_item; + if ( item && GTK_IS_TOGGLE_BUTTON(item) ) { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - if ((tool->m_item) && (GTK_IS_TOGGLE_BUTTON(tool->m_item))) - { - tool->m_toggleState = toggle; - - if (tool->m_bitmap2.Ok()) - { - wxBitmap bitmap = tool->m_bitmap1; - if (tool->m_toggleState) bitmap = tool->m_bitmap2; - - GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap ); - - GdkBitmap *mask = (GdkBitmap *) NULL; - if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap(); - - gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask ); - } - - m_blockNextEvent = TRUE; // we cannot use gtk_signal_disconnect here - - gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool->m_item), toggle ); - } - - return; + wxBitmap bitmap = tool->GetBitmap(); + if ( bitmap.Ok() ) + { + GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap ); + + GdkBitmap *mask = bitmap.GetMask() ? bitmap.GetMask()->GetBitmap() + : (GdkBitmap *)NULL; + + gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask ); } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); -} -wxObject *wxToolBar::GetToolClientData( int index ) const -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == index) return tool->m_clientData;; - node = node->Next(); + m_blockNextEvent = TRUE; // we cannot use gtk_signal_disconnect here + + gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(item), toggle ); } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return (wxObject*)NULL; } -bool wxToolBar::GetToolState(int toolIndex) const +void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) return tool->m_toggleState; - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return FALSE; + // VZ: absolutely no idea about how to do it + wxFAIL_MSG( _T("not implemented") ); } -bool wxToolBar::GetToolEnabled(int toolIndex) const +// ---------------------------------------------------------------------------- +// wxToolBar geometry +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y)) const { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) return tool->m_enabled; - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return FALSE; + // VZ: GTK+ doesn't seem to have such thing + wxFAIL_MSG( _T("wxToolBar::FindToolForPosition() not implemented") ); + + return (wxToolBarToolBase *)NULL; } void wxToolBar::SetMargins( int x, int y ) { - wxCHECK_RET( !m_hasToolAlready, wxT("wxToolBar::SetMargins must be called before adding tool.") ); + wxCHECK_RET( GetToolsCount() == 0, + wxT("wxToolBar::SetMargins must be called before adding tools.") ); if (x > 1) gtk_toolbar_append_space( m_toolbar ); // oh well @@ -521,128 +495,15 @@ void wxToolBar::SetMargins( int x, int y ) m_yMargin = y; } -void wxToolBar::SetToolPacking( int WXUNUSED(packing) ) -{ - wxFAIL_MSG( wxT("wxToolBar::SetToolPacking not implemented") ); -} - void wxToolBar::SetToolSeparation( int separation ) { gtk_toolbar_set_space_size( m_toolbar, separation ); - m_separation = separation; + m_toolSeparation = separation; } -int wxToolBar::GetToolPacking() -{ - return 0; -} - -int wxToolBar::GetToolSeparation() -{ - return m_separation; -} - -wxString wxToolBar::GetToolLongHelp(int toolIndex) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - return tool->m_longHelpString; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return wxT(""); -} - -wxString wxToolBar::GetToolShortHelp(int toolIndex) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - return tool->m_shortHelpString; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return wxT(""); -} - -void wxToolBar::SetToolLongHelp(int toolIndex, const wxString& helpString) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - tool->m_longHelpString = helpString; - return; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return; -} - -void wxToolBar::SetToolShortHelp(int toolIndex, const wxString& helpString) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - tool->m_shortHelpString = helpString; - return; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return; -} - -void wxToolBar::OnIdle( wxIdleEvent &WXUNUSED(ievent) ) -{ - wxEvtHandler* evtHandler = GetEventHandler(); - - wxNode* node = m_tools.First(); - while (node) - { - wxToolBarTool* tool = (wxToolBarTool*) node->Data(); - - wxUpdateUIEvent event( tool->m_index ); - event.SetEventObject(this); - - if (evtHandler->ProcessEvent( event )) - { - if (event.GetSetEnabled()) - EnableTool(tool->m_index, event.GetEnabled()); - if (event.GetSetChecked()) - ToggleTool(tool->m_index, event.GetChecked()); -/* - if (event.GetSetText()) - // Set tooltip? -*/ - } - - node = node->Next(); - } -} +// ---------------------------------------------------------------------------- +// wxToolBar idle handling +// ---------------------------------------------------------------------------- void wxToolBar::OnInternalIdle() { @@ -652,31 +513,37 @@ void wxToolBar::OnInternalIdle() if (cursor.Ok()) { /* I now set the cursor the anew in every OnInternalIdle call - as setting the cursor in a parent window also effects the - windows above so that checking for the current cursor is - not possible. */ + as setting the cursor in a parent window also effects the + windows above so that checking for the current cursor is + not possible. */ if (HasFlag(wxTB_DOCKABLE) && (m_widget->window)) - { - /* if the toolbar is dockable, then m_widget stands for the - GtkHandleBox widget, which uses its own window so that we - can set the cursor for it. if the toolbar is not dockable, - m_widget comes from m_toolbar which uses its parent's - window ("windowless windows") and thus we cannot set the - cursor. */ - gdk_window_set_cursor( m_widget->window, cursor.GetCursor() ); - } - - wxNode *node = m_tools.First(); - while (node) { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - node = node->Next(); - - if (!tool->m_item || !tool->m_item->window) - continue; - else - gdk_window_set_cursor( tool->m_item->window, cursor.GetCursor() ); + /* if the toolbar is dockable, then m_widget stands for the + GtkHandleBox widget, which uses its own window so that we + can set the cursor for it. if the toolbar is not dockable, + m_widget comes from m_toolbar which uses its parent's + window ("windowless windows") and thus we cannot set the + cursor. */ + gdk_window_set_cursor( m_widget->window, cursor.GetCursor() ); + } + + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while ( node ) + { + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + node = node->GetNext(); + + GtkWidget *item = tool->m_item; + if ( item ) + { + GdkWindow *window = item->window; + + if ( window ) + { + gdk_window_set_cursor( window, cursor.GetCursor() ); + } + } } } diff --git a/src/gtk1/tbargtk.cpp b/src/gtk1/tbargtk.cpp index a297e9653c..aa7574feca 100644 --- a/src/gtk1/tbargtk.cpp +++ b/src/gtk1/tbargtk.cpp @@ -2,18 +2,27 @@ // Name: tbargtk.cpp // Purpose: GTK toolbar // Author: Robert Roebling +// Modified: 13.12.99 by VZ to derive from wxToolBarBase // RCS-ID: $Id$ // Copyright: (c) Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "tbargtk.h" + #pragma implementation "tbargtk.h" #endif #include "wx/toolbar.h" -#if wxUSE_TOOLBAR +#if wxUSE_TOOLBAR_NATIVE #include "wx/frame.h" @@ -21,57 +30,99 @@ #include "gdk/gdk.h" #include "gtk/gtk.h" -//----------------------------------------------------------------------------- -// idle system -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- +// idle system extern void wxapp_install_idle_handler(); extern bool g_isIdle; -//----------------------------------------------------------------------------- // data -//----------------------------------------------------------------------------- - extern bool g_blockEventsOnDrag; extern wxCursor g_globalCursor; +// ---------------------------------------------------------------------------- +// wxToolBarTool +// ---------------------------------------------------------------------------- + +class wxToolBarTool : public wxToolBarToolBase +{ +public: + wxToolBarTool(wxToolBar *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) + : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString) + { + Init(); + } + + wxToolBarTool(wxToolBar *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + Init(); + } + + GtkWidget *m_item; + GtkWidget *m_pixmap; + +protected: + void Init(); +}; + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) + +// ============================================================================ +// implementation +// ============================================================================ + //----------------------------------------------------------------------------- // "clicked" (internal from gtk_toolbar) //----------------------------------------------------------------------------- -static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *tool ) +static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), + wxToolBarTool *tool ) { if (g_isIdle) wxapp_install_idle_handler(); - if (tool->m_owner->m_blockNextEvent) + wxToolBar *tbar = (wxToolBar *)tool->GetToolBar(); + if ( tbar->m_blockNextEvent ) { - tool->m_owner->m_blockNextEvent = FALSE; + tbar->m_blockNextEvent = FALSE; return; } if (g_blockEventsOnDrag) return; - if (!tool->m_enabled) return; + if (!tool->IsEnabled()) return; - if (tool->m_isToggle) + if (tool->CanBeToggled()) { - tool->m_toggleState = !tool->m_toggleState; - - if (tool->m_bitmap2.Ok()) - { - wxBitmap bitmap = tool->m_bitmap1; - if (tool->m_toggleState) bitmap = tool->m_bitmap2; - + tool->Toggle(); + + wxBitmap bitmap = tool->GetBitmap(); + if ( bitmap.Ok() ) + { GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap ); - - GdkBitmap *mask = (GdkBitmap *) NULL; - if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap(); - + + GdkBitmap *mask = bitmap.GetMask() ? bitmap.GetMask()->GetBitmap() + : (GdkBitmap *)NULL; + gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask ); - } + } } - tool->m_owner->OnLeftClick( tool->m_index, tool->m_toggleState ); + tbar->OnLeftClick( tool->GetId(), tool->IsToggled() ); } //----------------------------------------------------------------------------- @@ -79,18 +130,18 @@ static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget), wxToolBarTool *to //----------------------------------------------------------------------------- static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget), - GdkEventCrossing *WXUNUSED(gdk_event), wxToolBarTool *tool ) + GdkEventCrossing *WXUNUSED(gdk_event), + wxToolBarTool *tool ) { if (g_isIdle) wxapp_install_idle_handler(); if (g_blockEventsOnDrag) return TRUE; - - wxToolBar *tb = tool->m_owner; + wxToolBar *tb = (wxToolBar *)tool->GetToolBar(); #if (GTK_MINOR_VERSION == 0) /* we grey-out the tip text of disabled tool in GTK 1.0 */ - if (tool->m_enabled) + if (tool->IsEnabled()) { if (tb->m_fg->red != 0) { @@ -117,7 +168,7 @@ static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget), /* emit the event */ - tb->OnMouseEnter( tool->m_index ); + tb->OnMouseEnter( tool->GetId() ); return FALSE; } @@ -126,30 +177,51 @@ static gint gtk_toolbar_enter_callback( GtkWidget *WXUNUSED(widget), // InsertChild callback for wxToolBar //----------------------------------------------------------------------------- -static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent), wxWindow* WXUNUSED(child) ) +static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent), + wxWindow* WXUNUSED(child) ) { /* we don't do anything here but pray */ } -//----------------------------------------------------------------------------- -// wxToolBar -//----------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxToolBarTool +// ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxToolBar,wxControl) +void wxToolBarTool::Init() +{ + m_item = + m_pixmap = (GtkWidget *)NULL; +} -BEGIN_EVENT_TABLE(wxToolBar, wxControl) - EVT_IDLE(wxToolBar::OnIdle) -END_EVENT_TABLE() +wxToolBarToolBase *wxToolBar::CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString); +} -wxToolBar::wxToolBar() +wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) { + return new wxToolBarTool(this, control); } -wxToolBar::wxToolBar( wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style, const wxString& name ) +//----------------------------------------------------------------------------- +// wxToolBar construction +//----------------------------------------------------------------------------- + +void wxToolBar::Init() { - Create( parent, id, pos, size, style, name ); + m_fg = + m_bg = (GdkColor *)NULL; + + m_toolbar = (GtkToolbar *)NULL; + + m_blockNextEvent = FALSE; } wxToolBar::~wxToolBar() @@ -158,36 +230,36 @@ wxToolBar::~wxToolBar() delete m_bg; } -bool wxToolBar::Create( wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, - long style, const wxString& name ) +bool wxToolBar::Create( wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name ) { m_needParent = TRUE; - m_blockNextEvent = FALSE; m_insertCallback = (wxInsertChildFunction)wxInsertChildInToolBar; - if (!PreCreation( parent, pos, size ) || - !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) + if ( !PreCreation( parent, pos, size ) || + !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxToolBar creation failed") ); - return FALSE; - } - m_tools.DeleteContents( TRUE ); + return FALSE; + } - m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( GTK_ORIENTATION_HORIZONTAL, - GTK_TOOLBAR_ICONS ) ); + GtkOrientation orient = style & wxTB_VERTICAL ? GTK_ORIENTATION_VERTICAL + : GTK_ORIENTATION_HORIZONTAL; + m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( orient, GTK_TOOLBAR_ICONS ) ); - m_separation = 7; - gtk_toolbar_set_space_size( m_toolbar, m_separation ); - m_hasToolAlready = FALSE; + SetToolSeparation(7); if (style & wxTB_DOCKABLE) { m_widget = gtk_handle_box_new(); gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar) ); gtk_widget_show( GTK_WIDGET(m_toolbar) ); - + #if (GTK_MINOR_VERSION > 0) if (style & wxTB_FLAT) gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(m_widget), GTK_SHADOW_NONE ); @@ -197,9 +269,9 @@ bool wxToolBar::Create( wxWindow *parent, wxWindowID id, { m_widget = GTK_WIDGET(m_toolbar); } - + gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE ); - + #if (GTK_MINOR_VERSION > 0) if (style & wxTB_FLAT) gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE ); @@ -210,32 +282,29 @@ bool wxToolBar::Create( wxWindow *parent, wxWindowID id, m_fg->green = 0; m_fg->blue = 0; gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_fg ); - + m_bg = new GdkColor; m_bg->red = 65535; m_bg->green = 65535; m_bg->blue = 50000; gdk_color_alloc( gtk_widget_get_colormap( GTK_WIDGET(m_toolbar) ), m_bg ); - + #if (GTK_MINOR_VERSION > 0) gtk_tooltips_force_window( GTK_TOOLBAR(m_toolbar)->tooltips ); GtkStyle *g_style = - gtk_style_copy( - gtk_widget_get_style( - GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) ); - + gtk_style_copy( + gtk_widget_get_style( + GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) ); + g_style->bg[GTK_STATE_NORMAL] = *m_bg; gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style ); #else gtk_tooltips_set_colors( GTK_TOOLBAR(m_toolbar)->tooltips, m_bg, m_fg ); #endif - m_xMargin = 0; - m_yMargin = 0; - m_parent->DoAddChild( this ); - + PostCreation(); Show( TRUE ); @@ -243,277 +312,182 @@ bool wxToolBar::Create( wxWindow *parent, wxWindowID id, return TRUE; } -bool wxToolBar::OnLeftClick( int toolIndex, bool toggleDown ) -{ - wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, toolIndex ); - event.SetEventObject(this); - event.SetInt( toolIndex ); - event.SetExtraLong((long) toggleDown); - - GetEventHandler()->ProcessEvent(event); - - return TRUE; -} - -void wxToolBar::OnRightClick( int toolIndex, float WXUNUSED(x), float WXUNUSED(y) ) +bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) { - wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, toolIndex ); - event.SetEventObject( this ); - event.SetInt( toolIndex ); - - GetEventHandler()->ProcessEvent(event); -} + wxToolBarTool *tool = (wxToolBarTool *)toolBase; -void wxToolBar::OnMouseEnter( int toolIndex ) -{ - wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() ); - event.SetEventObject(this); - event.SetInt( toolIndex ); - - GetEventHandler()->ProcessEvent(event); -} + if ( tool->IsButton() ) + { + wxBitmap bitmap = tool->GetBitmap1(); -wxToolBarTool *wxToolBar::AddTool( int toolIndex, const wxBitmap& bitmap, - const wxBitmap& pushedBitmap, bool toggle, - wxCoord WXUNUSED(xPos), wxCoord WXUNUSED(yPos), wxObject *clientData, - const wxString& helpString1, const wxString& helpString2 ) -{ - m_hasToolAlready = TRUE; - - wxCHECK_MSG( bitmap.Ok(), (wxToolBarTool *)NULL, - wxT("invalid bitmap for wxToolBar icon") ); + wxCHECK_MSG( bitmap.Ok(), FALSE, + wxT("invalid bitmap for wxToolBar icon") ); - wxCHECK_MSG( bitmap.GetBitmap() == NULL, (wxToolBarTool *)NULL, - wxT("wxToolBar doesn't support GdkBitmap") ); + wxCHECK_MSG( bitmap.GetBitmap() == NULL, FALSE, + wxT("wxToolBar doesn't support GdkBitmap") ); - wxCHECK_MSG( bitmap.GetPixmap() != NULL, (wxToolBarTool *)NULL, - wxT("wxToolBar::Add needs a wxBitmap") ); - - GtkWidget *tool_pixmap = (GtkWidget *)NULL; - - GdkPixmap *pixmap = bitmap.GetPixmap(); + wxCHECK_MSG( bitmap.GetPixmap() != NULL, FALSE, + wxT("wxToolBar::Add needs a wxBitmap") ); + + GtkWidget *tool_pixmap = (GtkWidget *)NULL; + + GdkPixmap *pixmap = bitmap.GetPixmap(); - GdkBitmap *mask = (GdkBitmap *)NULL; - if ( bitmap.GetMask() ) - mask = bitmap.GetMask()->GetBitmap(); - - tool_pixmap = gtk_pixmap_new( pixmap, mask ); + GdkBitmap *mask = (GdkBitmap *)NULL; + if ( bitmap.GetMask() ) + mask = bitmap.GetMask()->GetBitmap(); + + tool_pixmap = gtk_pixmap_new( pixmap, mask ); #if (GTK_MINOR_VERSION > 0) - gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE ); + gtk_pixmap_set_build_insensitive( GTK_PIXMAP(tool_pixmap), TRUE ); #endif - - gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 ); - - wxToolBarTool *tool = new wxToolBarTool( this, toolIndex, bitmap, pushedBitmap, - toggle, clientData, - helpString1, helpString2, - tool_pixmap ); - - GtkToolbarChildType ctype = toggle ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON - : GTK_TOOLBAR_CHILD_BUTTON; - - GtkWidget *item = gtk_toolbar_append_element - ( - m_toolbar, - ctype, - (GtkWidget *)NULL, - (const char *)NULL, - helpString1.mbc_str(), - "", - tool_pixmap, - (GtkSignalFunc)gtk_toolbar_callback, - (gpointer)tool - ); - - tool->m_item = item; - - GtkRequisition req; - (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req ); - m_width = req.width + m_xMargin; - m_height = req.height + 2*m_yMargin + 4; - - gtk_signal_connect( GTK_OBJECT(tool->m_item), - "enter_notify_event", - GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback), - (gpointer)tool ); - - m_tools.Append( tool ); + + gtk_misc_set_alignment( GTK_MISC(tool_pixmap), 0.5, 0.5 ); - return tool; -} + tool->m_pixmap = tool_pixmap; + } -bool wxToolBar::AddControl(wxControl *control) -{ - wxCHECK_MSG( control, FALSE, wxT("toolbar: can't insert NULL control") ); + switch ( tool->GetStyle() ) + { + case wxTOOL_STYLE_BUTTON: + tool->m_item = gtk_toolbar_insert_element + ( + m_toolbar, + tool->CanBeToggled() + ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON + : GTK_TOOLBAR_CHILD_BUTTON, + (GtkWidget *)NULL, + (const char *)NULL, + tool->GetShortHelp().mbc_str(), + "", // tooltip_private_text (?) + tool->m_pixmap, + (GtkSignalFunc)gtk_toolbar_callback, + (gpointer)tool, + pos + ); + + if ( !tool->m_item ) + { + wxFAIL_MSG( _T("gtk_toolbar_insert_element() failed") ); + + return FALSE; + } + + gtk_signal_connect( GTK_OBJECT(tool->m_item), + "enter_notify_event", + GTK_SIGNAL_FUNC(gtk_toolbar_enter_callback), + (gpointer)tool ); + break; + + case wxTOOL_STYLE_SEPARATOR: + gtk_toolbar_append_space( m_toolbar ); + + // skip the rest + return TRUE; - wxCHECK_MSG( control->GetParent() == this, FALSE, - wxT("control must have toolbar as parent") ); + case wxTOOL_STYLE_CONTROL: + gtk_toolbar_insert_widget( + m_toolbar, + tool->GetControl()->m_widget, + (const char *) NULL, + (const char *) NULL, + pos + ); + break; + } - m_hasToolAlready = TRUE; - - wxToolBarTool *tool = new wxToolBarTool(control); - - tool -> m_item = NULL; - gtk_toolbar_append_widget( m_toolbar, control->m_widget, (const char *) NULL, (const char *) NULL ); - GtkRequisition req; (* GTK_WIDGET_CLASS( GTK_OBJECT(m_widget)->klass )->size_request ) (m_widget, &req ); m_width = req.width + m_xMargin; m_height = req.height + 2*m_yMargin + 4; - m_tools.Append( tool ); - return TRUE; } -void wxToolBar::AddSeparator() +bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *toolBase) { - gtk_toolbar_append_space( m_toolbar ); -} + wxToolBarTool *tool = (wxToolBarTool *)toolBase; -bool wxToolBar::DeleteTool(int toolIndex) -{ - wxNode *node = m_tools.First(); - while (node) + switch ( tool->GetStyle() ) { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - if (tool->m_control) - tool->m_control->Destroy(); - else - gtk_widget_destroy( tool->m_item ); - m_tools.DeleteNode( node ); - - return TRUE; - } - node = node->Next(); - } + case wxTOOL_STYLE_CONTROL: + tool->GetControl()->Destroy(); + break; - return FALSE; -} + case wxTOOL_STYLE_BUTTON: + gtk_widget_destroy( tool->m_item ); + break; -void wxToolBar::ClearTools() -{ - wxFAIL_MSG( wxT("wxToolBar::ClearTools not implemented") ); -} + //case wxTOOL_STYLE_SEPARATOR: -- nothing to do + } -bool wxToolBar::Realize() -{ return TRUE; } -void wxToolBar::EnableTool(int toolIndex, bool enable) +// ---------------------------------------------------------------------------- +// wxToolBar tools state +// ---------------------------------------------------------------------------- + +void wxToolBar::DoEnableTool(wxToolBarToolBase *toolBase, bool enable) { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - tool->m_enabled = enable; - #if (GTK_MINOR_VERSION > 0) - /* we don't disable the tools for GTK 1.0 as the bitmaps don't get - greyed anyway and this also disables tooltips */ - if (tool->m_item) - gtk_widget_set_sensitive( tool->m_item, enable ); + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + + /* we don't disable the tools for GTK 1.0 as the bitmaps don't get + greyed anyway and this also disables tooltips */ + if (tool->m_item) + gtk_widget_set_sensitive( tool->m_item, enable ); #endif - - return; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); } -void wxToolBar::ToggleTool( int toolIndex, bool toggle ) +void wxToolBar::DoToggleTool( wxToolBarToolBase *toolBase, bool toggle ) { - wxNode *node = m_tools.First(); - while (node) + wxToolBarTool *tool = (wxToolBarTool *)toolBase; + + GtkWidget *item = tool->m_item; + if ( item && GTK_IS_TOGGLE_BUTTON(item) ) { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - if ((tool->m_item) && (GTK_IS_TOGGLE_BUTTON(tool->m_item))) - { - tool->m_toggleState = toggle; - - if (tool->m_bitmap2.Ok()) - { - wxBitmap bitmap = tool->m_bitmap1; - if (tool->m_toggleState) bitmap = tool->m_bitmap2; - - GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap ); - - GdkBitmap *mask = (GdkBitmap *) NULL; - if (bitmap.GetMask()) mask = bitmap.GetMask()->GetBitmap(); - - gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask ); - } - - m_blockNextEvent = TRUE; // we cannot use gtk_signal_disconnect here - - gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(tool->m_item), toggle ); - } - - return; + wxBitmap bitmap = tool->GetBitmap(); + if ( bitmap.Ok() ) + { + GtkPixmap *pixmap = GTK_PIXMAP( tool->m_pixmap ); + + GdkBitmap *mask = bitmap.GetMask() ? bitmap.GetMask()->GetBitmap() + : (GdkBitmap *)NULL; + + gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask ); } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); -} -wxObject *wxToolBar::GetToolClientData( int index ) const -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == index) return tool->m_clientData;; - node = node->Next(); + m_blockNextEvent = TRUE; // we cannot use gtk_signal_disconnect here + + gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(item), toggle ); } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return (wxObject*)NULL; } -bool wxToolBar::GetToolState(int toolIndex) const +void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) return tool->m_toggleState; - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return FALSE; + // VZ: absolutely no idea about how to do it + wxFAIL_MSG( _T("not implemented") ); } -bool wxToolBar::GetToolEnabled(int toolIndex) const +// ---------------------------------------------------------------------------- +// wxToolBar geometry +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y)) const { - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) return tool->m_enabled; - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return FALSE; + // VZ: GTK+ doesn't seem to have such thing + wxFAIL_MSG( _T("wxToolBar::FindToolForPosition() not implemented") ); + + return (wxToolBarToolBase *)NULL; } void wxToolBar::SetMargins( int x, int y ) { - wxCHECK_RET( !m_hasToolAlready, wxT("wxToolBar::SetMargins must be called before adding tool.") ); + wxCHECK_RET( GetToolsCount() == 0, + wxT("wxToolBar::SetMargins must be called before adding tools.") ); if (x > 1) gtk_toolbar_append_space( m_toolbar ); // oh well @@ -521,128 +495,15 @@ void wxToolBar::SetMargins( int x, int y ) m_yMargin = y; } -void wxToolBar::SetToolPacking( int WXUNUSED(packing) ) -{ - wxFAIL_MSG( wxT("wxToolBar::SetToolPacking not implemented") ); -} - void wxToolBar::SetToolSeparation( int separation ) { gtk_toolbar_set_space_size( m_toolbar, separation ); - m_separation = separation; + m_toolSeparation = separation; } -int wxToolBar::GetToolPacking() -{ - return 0; -} - -int wxToolBar::GetToolSeparation() -{ - return m_separation; -} - -wxString wxToolBar::GetToolLongHelp(int toolIndex) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - return tool->m_longHelpString; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return wxT(""); -} - -wxString wxToolBar::GetToolShortHelp(int toolIndex) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - return tool->m_shortHelpString; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return wxT(""); -} - -void wxToolBar::SetToolLongHelp(int toolIndex, const wxString& helpString) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - tool->m_longHelpString = helpString; - return; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return; -} - -void wxToolBar::SetToolShortHelp(int toolIndex, const wxString& helpString) -{ - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - if (tool->m_index == toolIndex) - { - tool->m_shortHelpString = helpString; - return; - } - node = node->Next(); - } - - wxFAIL_MSG( wxT("wrong toolbar index") ); - - return; -} - -void wxToolBar::OnIdle( wxIdleEvent &WXUNUSED(ievent) ) -{ - wxEvtHandler* evtHandler = GetEventHandler(); - - wxNode* node = m_tools.First(); - while (node) - { - wxToolBarTool* tool = (wxToolBarTool*) node->Data(); - - wxUpdateUIEvent event( tool->m_index ); - event.SetEventObject(this); - - if (evtHandler->ProcessEvent( event )) - { - if (event.GetSetEnabled()) - EnableTool(tool->m_index, event.GetEnabled()); - if (event.GetSetChecked()) - ToggleTool(tool->m_index, event.GetChecked()); -/* - if (event.GetSetText()) - // Set tooltip? -*/ - } - - node = node->Next(); - } -} +// ---------------------------------------------------------------------------- +// wxToolBar idle handling +// ---------------------------------------------------------------------------- void wxToolBar::OnInternalIdle() { @@ -652,31 +513,37 @@ void wxToolBar::OnInternalIdle() if (cursor.Ok()) { /* I now set the cursor the anew in every OnInternalIdle call - as setting the cursor in a parent window also effects the - windows above so that checking for the current cursor is - not possible. */ + as setting the cursor in a parent window also effects the + windows above so that checking for the current cursor is + not possible. */ if (HasFlag(wxTB_DOCKABLE) && (m_widget->window)) - { - /* if the toolbar is dockable, then m_widget stands for the - GtkHandleBox widget, which uses its own window so that we - can set the cursor for it. if the toolbar is not dockable, - m_widget comes from m_toolbar which uses its parent's - window ("windowless windows") and thus we cannot set the - cursor. */ - gdk_window_set_cursor( m_widget->window, cursor.GetCursor() ); - } - - wxNode *node = m_tools.First(); - while (node) { - wxToolBarTool *tool = (wxToolBarTool*)node->Data(); - node = node->Next(); - - if (!tool->m_item || !tool->m_item->window) - continue; - else - gdk_window_set_cursor( tool->m_item->window, cursor.GetCursor() ); + /* if the toolbar is dockable, then m_widget stands for the + GtkHandleBox widget, which uses its own window so that we + can set the cursor for it. if the toolbar is not dockable, + m_widget comes from m_toolbar which uses its parent's + window ("windowless windows") and thus we cannot set the + cursor. */ + gdk_window_set_cursor( m_widget->window, cursor.GetCursor() ); + } + + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while ( node ) + { + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + node = node->GetNext(); + + GtkWidget *item = tool->m_item; + if ( item ) + { + GdkWindow *window = item->window; + + if ( window ) + { + gdk_window_set_cursor( window, cursor.GetCursor() ); + } + } } } diff --git a/src/motif/toolbar.cpp b/src/motif/toolbar.cpp index 1864a875ef..56c79abbcc 100644 --- a/src/motif/toolbar.cpp +++ b/src/motif/toolbar.cpp @@ -1,16 +1,24 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: toolbar.cpp +// Name: motif/toolbar.cpp // Purpose: wxToolBar // Author: Julian Smart -// Modified by: +// Modified by: 13.12.99 by VZ during toolbar classes reorganization // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "toolbar.h" + #pragma implementation "toolbar.h" #endif #include "wx/wx.h" @@ -34,51 +42,147 @@ #include "wx/motif/private.h" -IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +#if !USE_SHARED_LIBRARY +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) +#endif -BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) -END_EVENT_TABLE() +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- static void wxToolButtonCallback (Widget w, XtPointer clientData, XtPointer ptr); static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, XEvent *event, Boolean *continue_to_dispatch); -class wxToolBarTimer: public wxTimer +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class wxToolBarTimer : public wxTimer { public: - wxToolBarTimer() { } - virtual void Notify(); + virtual void Notify(); - static Widget help_popup; - static Widget buttonWidget; - static wxString helpString; + static Widget help_popup; + static Widget buttonWidget; + static wxString helpString; }; +class wxToolBarTool : public wxToolBarToolBase +{ +public: + wxToolBarTool(wxToolBar *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) + : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString) + { + Init(); + } + + wxToolBarTool(wxToolBar *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + Init(); + } + + virtual ~wxToolBarTool(); + + // accessors + void SetWidget(Widget widget) { m_widget = widget; } + Widget GetButtonWidget() const { return m_widget; } + + void SetPixmap(Pixmap pixmap) { m_pixmap = pixmap; } + Pixmap GetPixmap() const { return m_pixmap; } + +protected: + void Init(); + + Widget m_widget; + Pixmap m_pixmap; +}; + +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- + static wxToolBarTimer* wxTheToolBarTimer = (wxToolBarTimer*) NULL; Widget wxToolBarTimer::help_popup = (Widget) 0; Widget wxToolBarTimer::buttonWidget = (Widget) 0; -wxString wxToolBarTimer::helpString = ""; +wxString wxToolBarTimer::helpString; + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxToolBarTool +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBarToolBase::New(wxToolBar *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarTool(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString); +} -wxToolBar::wxToolBar(): - m_widgets(wxKEY_INTEGER) +wxToolBarToolBase *wxToolBarToolBase::New(wxToolBar *tbar, wxControl *control) { - m_maxWidth = -1; - m_maxHeight = -1; - m_defaultWidth = 24; - m_defaultHeight = 22; + return new wxToolBarTool(tbar, control); } -bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, const wxString& name) +void wxToolBarTool::Init() +{ + m_widget = (Widget)0; + m_pixmap = (Pixmap)0; +} + +wxToolBarTool::~wxToolBarTool() +{ + XtDestroyWidget(m_widget); + XmDestroyPixmap(DefaultScreenOfDisplay((Display*)wxGetDisplay()), m_pixmap); +} + +// ---------------------------------------------------------------------------- +// wxToolBar construction +// ---------------------------------------------------------------------------- + +void wxToolBar::Init() { - m_windowId = id; m_maxWidth = -1; m_maxHeight = -1; - m_defaultWidth = 24; m_defaultHeight = 22; +} + +bool wxToolBar::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + Init(); + + m_windowId = id; + SetName(name); m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); m_foregroundColour = parent->GetForegroundColour(); @@ -126,14 +230,15 @@ wxToolBar::~wxToolBar() { delete wxTheToolBarTimer; wxTheToolBarTimer = NULL; - ClearTools(); - DestroyPixmaps(); } -bool wxToolBar::CreateTools() +bool wxToolBar::Realize() { - if (m_tools.Number() == 0) - return FALSE; + if ( m_tools.GetCount() == 0 ) + { + // nothing to do + return TRUE; + } // Separator spacing const int separatorSize = GetToolSeparation(); // 8; @@ -148,178 +253,193 @@ bool wxToolBar::CreateTools() int currentSpacing = 0; - m_widgets.Clear(); - Widget prevButton = (Widget) 0; - wxNode* node = m_tools.First(); - while (node) + Widget button; + Pixmap pixmap, insensPixmap; + wxBitmap bmp; + + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while ( node ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); - if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) - currentX += separatorSize; - else if (tool->m_bitmap1.Ok()) + switch ( tool->GetStyle() ) { - Widget button = (Widget) 0; - - if (tool->m_isToggle) - { - button = XtVaCreateWidget("toggleButton", - xmToggleButtonWidgetClass, (Widget) m_mainWidget, - XmNx, currentX, XmNy, currentY, - // XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - NULL); - XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback, - (XtPointer) this); - - XtVaSetValues ((Widget) button, - XmNselectColor, m_backgroundColour.AllocColour(XtDisplay((Widget) button)), - NULL); - } - else - { - button = XtVaCreateWidget("button", - xmPushButtonWidgetClass, (Widget) m_mainWidget, - XmNx, currentX, XmNy, currentY, - XmNpushButtonEnabled, True, - XmNmultiClick, XmMULTICLICK_KEEP, - XmNlabelType, XmPIXMAP, - NULL); - XtAddCallback (button, - XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback, - (XtPointer) this); - } - - DoChangeBackgroundColour((WXWidget) button, m_backgroundColour, TRUE); - - // For each button, if there is a mask, we must create - // a new wxBitmap that has the correct background colour - // for the button. Otherwise the background will just be - // e.g. black if a transparent XPM has been loaded. - wxBitmap originalBitmap = tool->m_bitmap1; - - if (tool->m_bitmap1.GetMask()) - { - int backgroundPixel; - XtVaGetValues(button, XmNbackground, &backgroundPixel, - NULL); + case wxTOOL_STYLE_CONTROL: + wxFAIL_MSG( _T("not implemented") ); + break; + case wxTOOL_STYLE_SEPARATOR: + currentX += separatorSize; + break; - wxColour col; - col.SetPixel(backgroundPixel); + case wxTOOL_STYLE_BUTTON: + button = (Widget) 0; - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap1, col); - - tool->m_bitmap1 = newBitmap; - } - - // Create a selected/toggled bitmap. If there isn't a m_bitmap2, - // we need to create it (with a darker, selected background) - int backgroundPixel; - if (tool->m_isToggle) - XtVaGetValues(button, XmNselectColor, &backgroundPixel, - NULL); - else - XtVaGetValues(button, XmNarmColor, &backgroundPixel, - NULL); - - wxColour col; - col.SetPixel(backgroundPixel); - - if (tool->m_bitmap2.Ok() && tool->m_bitmap2.GetMask()) - { - // Use what's there - wxBitmap newBitmap = wxCreateMaskedBitmap(tool->m_bitmap2, col); - tool->m_bitmap2 = newBitmap; - } - else - { - // Use unselected bitmap - if (originalBitmap.GetMask()) + if ( tool->CanBeToggled() ) { - wxBitmap newBitmap = wxCreateMaskedBitmap(originalBitmap, col); - tool->m_bitmap2 = newBitmap; + button = XtVaCreateWidget("toggleButton", + xmToggleButtonWidgetClass, (Widget) m_mainWidget, + XmNx, currentX, XmNy, currentY, + // XmNpushButtonEnabled, True, + XmNmultiClick, XmMULTICLICK_KEEP, + XmNlabelType, XmPIXMAP, + NULL); + XtAddCallback ((Widget) button, XmNvalueChangedCallback, (XtCallbackProc) wxToolButtonCallback, + (XtPointer) this); + + XtVaSetValues ((Widget) button, + XmNselectColor, m_backgroundColour.AllocColour(XtDisplay((Widget) button)), + NULL); } else - tool->m_bitmap2 = tool->m_bitmap1; - } + { + button = XtVaCreateWidget("button", + xmPushButtonWidgetClass, (Widget) m_mainWidget, + XmNx, currentX, XmNy, currentY, + XmNpushButtonEnabled, True, + XmNmultiClick, XmMULTICLICK_KEEP, + XmNlabelType, XmPIXMAP, + NULL); + XtAddCallback (button, + XmNactivateCallback, (XtCallbackProc) wxToolButtonCallback, + (XtPointer) this); + } - Pixmap pixmap = (Pixmap) tool->m_bitmap1.GetPixmap(); - Pixmap insensPixmap = (Pixmap) tool->m_bitmap1.GetInsensPixmap(); + DoChangeBackgroundColour((WXWidget) button, m_backgroundColour, TRUE); - if (tool->m_isToggle) - { - // Toggle button - Pixmap pixmap2 = (Pixmap) 0; - Pixmap insensPixmap2 = (Pixmap) 0; + tool->SetWidget(button); - // If there's a bitmap for the toggled state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) + // For each button, if there is a mask, we must create + // a new wxBitmap that has the correct background colour + // for the button. Otherwise the background will just be + // e.g. black if a transparent XPM has been loaded. + bmp = tool->GetBitmap1(); + if ( bmp.GetMask() ) { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); - insensPixmap2 = (Pixmap) tool->m_bitmap2.GetInsensPixmap(); + int backgroundPixel; + XtVaGetValues(button, XmNbackground, &backgroundPixel, + NULL); + + wxColour col; + col.SetPixel(backgroundPixel); + + wxBitmap newBitmap = wxCreateMaskedBitmap(bmp, col); + + tool->SetBitmap1(newBitmap); } + + // Create a selected/toggled bitmap. If there isn't a 2nd + // bitmap, we need to create it (with a darker, selected + // background) + int backgroundPixel; + if ( tool->CanBeToggled() ) + XtVaGetValues(button, XmNselectColor, &backgroundPixel, + NULL); else + XtVaGetValues(button, XmNarmColor, &backgroundPixel, + NULL); + + wxColour col; + col.SetPixel(backgroundPixel); + + if (tool->GetBitmap2().Ok() && tool->GetBitmap2().GetMask()) { - pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); - insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); - m_pixmaps.Append((wxObject*) insensPixmap2); // Store for later deletion + // Use what's there + wxBitmap newBitmap = wxCreateMaskedBitmap(tool->GetBitmap2(), col); + tool->SetBitmap2(newBitmap); } - XtVaSetValues (button, - XmNindicatorOn, False, - XmNshadowThickness, 2, - // XmNborderWidth, 0, - // XmNspacing, 0, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNfillOnSelect, True, - XmNlabelPixmap, pixmap, - XmNselectPixmap, pixmap2, - XmNlabelInsensitivePixmap, insensPixmap, - XmNselectInsensitivePixmap, insensPixmap2, - XmNlabelType, XmPIXMAP, - NULL); - } - else - { - Pixmap pixmap2 = (Pixmap) 0; - - // If there's a bitmap for the armed state, use it, - // otherwise generate one. - if (tool->m_bitmap2.Ok()) + else { - pixmap2 = (Pixmap) tool->m_bitmap2.GetPixmap(); + // Use unselected bitmap + if ( bmp.GetMask() ) + { + wxBitmap newBitmap = wxCreateMaskedBitmap(bmp, col); + tool->SetBitmap2(newBitmap); + } + else + tool->SetBitmap2(bmp); + } + + pixmap = (Pixmap) bmp.GetPixmap(); + insensPixmap = (Pixmap) bmp.GetInsensPixmap(); + + if (tool->CanBeToggled()) + { + // Toggle button + Pixmap pixmap2 = (Pixmap) 0; + Pixmap insensPixmap2 = (Pixmap) 0; + + // If there's a bitmap for the toggled state, use it, + // otherwise generate one. + if (tool->GetBitmap2().Ok()) + { + wxBitmap bmp2 = tool->GetBitmap2(); + pixmap2 = (Pixmap) bmp2.GetPixmap(); + insensPixmap2 = (Pixmap) bmp2.GetInsensPixmap(); + } + else + { + pixmap2 = (Pixmap) bmp.GetArmPixmap(button); + insensPixmap2 = XCreateInsensitivePixmap((Display*) wxGetDisplay(), pixmap2); + } + + XtVaSetValues (button, + XmNindicatorOn, False, + XmNshadowThickness, 2, + // XmNborderWidth, 0, + // XmNspacing, 0, + XmNmarginWidth, 0, + XmNmarginHeight, 0, + XmNfillOnSelect, True, + XmNlabelPixmap, pixmap, + XmNselectPixmap, pixmap2, + XmNlabelInsensitivePixmap, insensPixmap, + XmNselectInsensitivePixmap, insensPixmap2, + XmNlabelType, XmPIXMAP, + NULL); } else { - pixmap2 = (Pixmap) tool->m_bitmap1.GetArmPixmap(button); + Pixmap pixmap2 = (Pixmap) 0; + + // If there's a bitmap for the armed state, use it, + // otherwise generate one. + if (tool->GetBitmap2().Ok()) + { + pixmap2 = (Pixmap) tool->GetBitmap2().GetPixmap(); + } + else + { + pixmap2 = (Pixmap) bmp.GetArmPixmap(button); + + } + // Normal button + XtVaSetValues(button, + XmNlabelPixmap, pixmap, + XmNlabelInsensitivePixmap, insensPixmap, + XmNarmPixmap, pixmap2, + NULL); + } + XtManageChild(button); + { + Dimension width, height; + XtVaGetValues(button, + XmNwidth, &width, + XmNheight, & height, + NULL); + currentX += width + marginX; + buttonHeight = wxMax(buttonHeight, height); } - // Normal button - XtVaSetValues(button, - XmNlabelPixmap, pixmap, - XmNlabelInsensitivePixmap, insensPixmap, - XmNarmPixmap, pixmap2, - NULL); - } - XtManageChild(button); - - Dimension width, height; - XtVaGetValues(button, XmNwidth, & width, XmNheight, & height, - NULL); - currentX += width + marginX; - buttonHeight = wxMax(buttonHeight, height); - - XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, - False, wxToolButtonPopupCallback, (XtPointer) this); - m_widgets.Append(tool->m_index, (wxObject*) button); - - prevButton = button; - currentSpacing = 0; + + XtAddEventHandler (button, EnterWindowMask | LeaveWindowMask, + False, wxToolButtonPopupCallback, (XtPointer) this); + + currentSpacing = 0; + break; } - node = node->Next(); + + node = node->GetNext(); } SetSize(-1, -1, currentX, buttonHeight + 2*marginY); @@ -327,199 +447,107 @@ bool wxToolBar::CreateTools() return TRUE; } -void wxToolBar::SetToolBitmapSize(const wxSize& size) -{ - // TODO not necessary? - m_defaultWidth = size.x; m_defaultHeight = size.y; -} - -wxSize wxToolBar::GetMaxSize() const +wxToolBarTool *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y)) const { - int w, h; - GetSize(& w, & h); + wxFAIL_MSG( _T("TODO") ); - return wxSize(w, h); + return (wxToolBarTool *)NULL; } -// The button size is bigger than the bitmap size -wxSize wxToolBar::GetToolSize() const +bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarTool *tool) { - // TODO not necessary? - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); -} + tool->Attach(this); -void wxToolBar::EnableTool(int toolIndex, bool enable) -{ - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_enabled = enable; - - WXWidget widget = FindWidgetForIndex(tool->m_index); - if (widget == (WXWidget) 0) - return; - - XtSetSensitive((Widget) widget, (Boolean) enable); - } -} - -void wxToolBar::ToggleTool(int toolIndex, bool toggle) -{ - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) - { - tool->m_toggleState = toggle; - - WXWidget widget = FindWidgetForIndex(tool->m_index); - if (widget == (WXWidget) 0) - return; - - XmToggleButtonSetState((Widget) widget, (Boolean) toggle, False); - } - } + return TRUE; } -void wxToolBar::ClearTools() +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarTool *tool) { - wxNode* node = m_widgets.First(); - while (node) - { - Widget button = (Widget) node->Data(); - XtDestroyWidget(button); - node = node->Next(); - } - m_widgets.Clear(); - DestroyPixmaps(); + tool->Detach(); - wxToolBarBase::ClearTools(); + return TRUE; } -void wxToolBar::DestroyPixmaps() +void wxToolBar::DoEnableTool(wxToolBarTool *tool, bool enable) { - wxNode* node = m_pixmaps.First(); - while (node) - { - Pixmap pixmap = (Pixmap) node->Data(); - XmDestroyPixmap (DefaultScreenOfDisplay ((Display*) GetXDisplay()), pixmap); - node = node->Next(); - } - m_pixmaps.Clear(); + XtSetSensitive(tool->GetButtonWidget(), (Boolean) enable); } -// If pushedBitmap is NULL, a reversed version of bitmap is -// created and used as the pushed/toggled image. -// If toggle is TRUE, the button toggles between the two states. - -wxToolBarTool *wxToolBar::AddTool(int index, const wxBitmap& bitmap, const wxBitmap& WXUNUSED(pushedBitmap), - bool toggle, wxCoord xPos, wxCoord yPos, wxObject *clientData, const wxString& helpString1, const wxString& helpString2) +void wxToolBar::DoToggleTool(wxToolBarTool *tool, bool toggle) { - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2); - tool->m_clientData = clientData; - - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; - - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; - - wxSize size = GetToolSize(); - tool->SetSize(size.x, size.y); - - m_tools.Append((long)index, tool); - return tool; + XmToggleButtonSetState(tool->GetButtonWidget(), (Boolean) toggle, False); } -int wxToolBar::FindIndexForWidget(WXWidget w) +void wxToolBar::DoSetToggle(wxToolBarTool *tool, bool toggle) { - wxNode* node = m_widgets.First(); - while (node) - { - WXWidget widget = (WXWidget) node->Data(); - if (widget == w) - return (int) node->GetKeyInteger(); - node = node->Next(); - } - return -1; + wxFAIL_MSG( _T("TODO") ); } -WXWidget wxToolBar::FindWidgetForIndex(int index) -{ - wxNode* node = m_widgets.Find((long) index); - if (!node) - return (WXWidget) 0; - else - return (WXWidget) node->Data(); -} +// ---------------------------------------------------------------------------- +// Motif callbacks +// ---------------------------------------------------------------------------- -WXWidget wxToolBar::GetTopWidget() const +wxToolBarTool *wxToolBar::FindToolByWidget(WXWidget w) const { - return m_mainWidget; -} + wxToolBarToolsList::Node* node = m_tools.GetFirst(); + while ( node ) + { + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + if ( tool->GetButtonWidget() == w) + { + return tool; + } -WXWidget wxToolBar::GetClientWidget() const -{ - return m_mainWidget; -} + node = node->GetNext(); + } -WXWidget wxToolBar::GetMainWidget() const -{ - return m_mainWidget; + return (wxToolBarTool *)NULL; } - -void wxToolButtonCallback (Widget w, XtPointer clientData, - XtPointer WXUNUSED(ptr)) +static void wxToolButtonCallback(Widget w, + XtPointer clientData, + XtPointer WXUNUSED(ptr)) { wxToolBar *toolBar = (wxToolBar *) clientData; - int index = toolBar->FindIndexForWidget((WXWidget) w); + wxToolBarTool *tool = toolBar->FindToolByWidget((WXWidget) w); + if ( !tool ) + return; - if (index != -1) + if ( tool->CanBeToggled() ) + tool->Toggle(); + + if ( !toolBar->OnLeftClick(tool->GetId(), tool->IsToggled()) ) { - wxNode *node = toolBar->GetTools().Find((long)index); - if (!node) - return; - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) - tool->m_toggleState = !tool->m_toggleState; - - (void) toolBar->OnLeftClick(index, tool->m_toggleState); + // revert + tool->Toggle(); } - } -static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, - XEvent *event, Boolean *WXUNUSED(continue_to_dispatch)) +static void wxToolButtonPopupCallback(Widget w, + XtPointer client_data, + XEvent *event, + Boolean *WXUNUSED(continue_to_dispatch)) { // TODO: retrieve delay before popping up tooltip from wxSystemSettings. - int delayMilli = 800; - wxToolBar* toolBar = (wxToolBar*) client_data; + static const int delayMilli = 800; - int index = toolBar->FindIndexForWidget((WXWidget) w); + wxToolBar* toolBar = (wxToolBar*) client_data; + wxToolBarTool *tool = toolBar->FindToolByWidget((WXWidget) w); - if (index != -1) - { - wxNode *node = toolBar->GetTools().Find((long)index); - if (!node) - return; - wxString str(toolBar->GetToolShortHelp(index)); - if (str.IsNull() || str == "") - return; + if ( !tool ) + return; - if (!wxTheToolBarTimer) - wxTheToolBarTimer = new wxToolBarTimer; + wxString tooltip = tool->GetShortHelp(); + if ( !tooltip ) + return; - wxToolBarTimer::buttonWidget = w; - wxToolBarTimer::helpString = str; + if (!wxTheToolBarTimer) + wxTheToolBarTimer = new wxToolBarTimer; + wxToolBarTimer::buttonWidget = w; + wxToolBarTimer::helpString = tooltip; /************************************************************/ /* Popup help label */ @@ -551,7 +579,6 @@ static void wxToolButtonPopupCallback (Widget w, XtPointer client_data, } wxToolBarTimer::help_popup = (Widget) 0; } - } } void wxToolBarTimer::Notify() diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index 36755cdc63..77bc8885dc 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: msw/tbar95.cpp -// Purpose: wxToolBar95 +// Purpose: wxToolBar // Author: Julian Smart // Modified by: // Created: 04/01/98 @@ -29,6 +29,7 @@ #endif #ifndef WX_PRECOMP + #include "wx/frame.h" #include "wx/log.h" #include "wx/intl.h" #include "wx/dynarray.h" @@ -36,7 +37,9 @@ #include "wx/bitmap.h" #endif -#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR && defined(__WIN95__) +#if wxUSE_TOOLBAR && defined(__WIN95__) && wxUSE_TOOLBAR_NATIVE + +#include "wx/toolbar.h" #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) #include "malloc.h" @@ -55,7 +58,6 @@ #endif // __TWIN32__ #include "wx/msw/dib.h" -#include "wx/msw/tbar95.h" #include "wx/app.h" // for GetComCtl32Version // ---------------------------------------------------------------------------- @@ -74,8 +76,12 @@ // Messages #ifndef TB_GETSTYLE - #define TB_GETSTYLE (WM_USER + 57) #define TB_SETSTYLE (WM_USER + 56) + #define TB_GETSTYLE (WM_USER + 57) +#endif + +#ifndef TB_HITTEST + #define TB_HITTEST (WM_USER + 69) #endif // these values correspond to those used by comctl32.dll @@ -86,7 +92,7 @@ #define DEFAULTBARHEIGHT 27 // ---------------------------------------------------------------------------- -// function prototypes +// private function prototypes // ---------------------------------------------------------------------------- static void wxMapBitmap(HBITMAP hBitmap, int width, int height); @@ -95,41 +101,96 @@ static void wxMapBitmap(HBITMAP hBitmap, int width, int height); // wxWin macros // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) -BEGIN_EVENT_TABLE(wxToolBar95, wxToolBarBase) - EVT_MOUSE_EVENTS(wxToolBar95::OnMouseEvent) - EVT_SYS_COLOUR_CHANGED(wxToolBar95::OnSysColourChanged) +BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) + EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) + EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged) END_EVENT_TABLE() +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class wxToolBarTool : public wxToolBarToolBase +{ +public: + wxToolBarTool(wxToolBar *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) + : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString) + { + m_nSepCount = 0; + } + + wxToolBarTool(wxToolBar *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + m_nSepCount = 1; + } + + // set/get the number of separators which we use to cover the space used by + // a control in the toolbar + void SetSeparatorsCount(size_t count) { m_nSepCount = count; } + size_t GetSeparatorsCount() const { return m_nSepCount; } + +private: + size_t m_nSepCount; +}; + + // ============================================================================ // implementation // ============================================================================ // ---------------------------------------------------------------------------- -// wxToolBar95 construction +// wxToolBarTool // ---------------------------------------------------------------------------- -void wxToolBar95::Init() +wxToolBarToolBase *wxToolBar::CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString); +} + +wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) +{ + return new wxToolBarTool(this, control); +} + +// ---------------------------------------------------------------------------- +// wxToolBar construction +// ---------------------------------------------------------------------------- + +void wxToolBar::Init() { - m_maxWidth = -1; - m_maxHeight = -1; m_hBitmap = 0; + + m_nButtons = 0; + m_defaultWidth = DEFAULTBITMAPX; m_defaultHeight = DEFAULTBITMAPY; } -bool wxToolBar95::Create(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +bool wxToolBar::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { - wxASSERT_MSG( (style & wxTB_VERTICAL) == 0, - wxT("Sorry, wxToolBar95 under Windows 95 only " - "supports horizontal orientation.") ); - // common initialisation if ( !CreateControl(parent, id, pos, size, style, name) ) return FALSE; @@ -179,10 +240,8 @@ bool wxToolBar95::Create(wxWindow *parent, return TRUE; } -wxToolBar95::~wxToolBar95() +wxToolBar::~wxToolBar() { - UnsubclassWin(); - if (m_hBitmap) { ::DeleteObject((HBITMAP) m_hBitmap); @@ -190,106 +249,109 @@ wxToolBar95::~wxToolBar95() } // ---------------------------------------------------------------------------- -// adding/removing buttons +// adding/removing tools // ---------------------------------------------------------------------------- -void wxToolBar95::ClearTools() +bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), + wxToolBarToolBase *tool) { - // TODO: Don't know how to reset the toolbar bitmap, as yet. - // But adding tools and calling CreateTools should probably - // recreate a buttonbar OK. - wxToolBarBase::ClearTools(); + // nothing special to do here - we really create the toolbar buttons in + // Realize() later + tool->Attach(this); + + return TRUE; } -bool wxToolBar95::DeleteTool(int id) +bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) { - int index = GetIndexFromId(id); - wxASSERT_MSG( index != wxNOT_FOUND, _T("invalid toolbar button id") ); + // 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; - if ( !SendMessage(GetHwnd(), TB_DELETEBUTTON, index, 0) ) + // get the size of the button we're going to delete + RECT r; + if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) ) { - wxLogLastError("TB_DELETEBUTTON"); - - return FALSE; + wxLogLastError(_T("TB_GETITEMRECT")); } - wxNode *node = m_tools.Nth(index); - delete (wxToolBarTool *)node->Data(); - m_tools.DeleteNode(node); + int width = r.right - r.left; - m_ids.RemoveAt(index); + if ( tool->IsControl() ) + { + nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount(); - return TRUE; -} + width *= nButtonsToDelete; + } -bool wxToolBar95::AddControl(wxControl *control) -{ - wxCHECK_MSG( control, FALSE, _T("toolbar: can't insert NULL control") ); + while ( nButtonsToDelete-- > 0 ) + { + if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) ) + { + wxLogLastError("TB_DELETEBUTTON"); - wxCHECK_MSG( control->GetParent() == this, FALSE, - _T("control must have toolbar as parent") ); + return FALSE; + } + } - wxToolBarTool *tool = new wxToolBarTool(control); + tool->Detach(); - m_tools.Append(control->GetId(), tool); - m_ids.Add(control->GetId()); + 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() ) + { + wxToolBarToolBase *tool2 = node->GetData(); + if ( tool2->IsControl() ) + { + int x; + wxControl *control = tool2->GetControl(); + control->GetPosition(&x, NULL); + control->Move(x - width, -1); + } + } return TRUE; } -wxToolBarTool *wxToolBar95::AddTool(int index, - const wxBitmap& bitmap, - const wxBitmap& pushedBitmap, - bool toggle, - long xPos, long yPos, - wxObject *clientData, - const wxString& helpString1, - const wxString& helpString2) +bool wxToolBar::Realize() { - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, - toggle, xPos, yPos, - helpString1, helpString2); - tool->m_clientData = clientData; - - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; - - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; - - tool->SetSize(GetToolSize().x, GetToolSize().y); - - m_tools.Append((long)index, tool); - m_ids.Add(index); + size_t nTools = GetToolsCount(); + if ( nTools == 0 ) + { + // nothing to do + return TRUE; + } - return tool; -} + bool isVertical = (GetWindowStyle() & wxTB_VERTICAL) != 0; -bool wxToolBar95::CreateTools() -{ - size_t nTools = m_tools.GetCount(); - if ( nTools == 0 ) - return FALSE; + // First, add the bitmap: we use one bitmap for all toolbar buttons + // ---------------------------------------------------------------- - HBITMAP oldToolBarBitmap = (HBITMAP) m_hBitmap; + // 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; // Create a bitmap for all the tool bitmaps - HDC dc = ::GetDC(NULL); - m_hBitmap = (WXHBITMAP) ::CreateCompatibleBitmap(dc, - totalBitmapWidth, - totalBitmapHeight); - ::ReleaseDC(NULL, dc); + HBITMAP hBitmap = ::CreateCompatibleBitmap(ScreenHDC(), + totalBitmapWidth, + totalBitmapHeight); + if ( !hBitmap ) + { + wxLogLastError(_T("CreateCompatibleBitmap")); + + return FALSE; + } + + m_hBitmap = (WXHBITMAP)hBitmap; // Now blit all the tools onto this bitmap HDC memoryDC = ::CreateCompatibleDC(NULL); - HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, (HBITMAP)m_hBitmap); + HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, hBitmap); HDC memoryDC2 = ::CreateCompatibleDC(NULL); @@ -297,15 +359,15 @@ bool wxToolBar95::CreateTools() wxCoord x = 0; // the number of buttons (not separators) - int noButtons = 0; + int nButtons = 0; - wxNode *node = m_tools.First(); - while (node) + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while ( node ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if ( tool->m_toolStyle == wxTOOL_STYLE_BUTTON && tool->m_bitmap1.Ok() ) + wxToolBarToolBase *tool = node->GetData(); + if ( tool->IsButton() ) { - HBITMAP hbmp = GetHbitmapOf(tool->m_bitmap1); + HBITMAP hbmp = GetHbitmapOf(tool->GetBitmap1()); if ( hbmp ) { HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp); @@ -316,12 +378,20 @@ bool wxToolBar95::CreateTools() } ::SelectObject(memoryDC2, oldBitmap2); - - x += m_defaultWidth; - noButtons++; } + else + { + wxFAIL_MSG( _T("invalid tool button bitmap") ); + } + + // 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->Next(); + + node = node->GetNext(); } ::SelectObject(memoryDC, oldBitmap); @@ -329,7 +399,7 @@ bool wxToolBar95::CreateTools() ::DeleteDC(memoryDC2); // Map to system colours - wxMapBitmap((HBITMAP) m_hBitmap, totalBitmapWidth, totalBitmapHeight); + wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight); if ( oldToolBarBitmap ) { @@ -337,59 +407,64 @@ bool wxToolBar95::CreateTools() replaceBitmap.hInstOld = NULL; replaceBitmap.hInstNew = NULL; replaceBitmap.nIDOld = (UINT) oldToolBarBitmap; - replaceBitmap.nIDNew = (UINT) (HBITMAP) m_hBitmap; - replaceBitmap.nButtons = noButtons; - if ( ::SendMessage(GetHwnd(), TB_REPLACEBITMAP, - 0, (LPARAM) &replaceBitmap) == -1 ) + 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((HBITMAP) oldToolBarBitmap); + ::DeleteObject(oldToolBarBitmap); // Now delete all the buttons - int i = 0; - while ( TRUE ) + for ( size_t pos = 0; pos < m_nButtons; pos++ ) { - // TODO: What about separators???? They don't have an id! - if ( ! ::SendMessage( GetHwnd(), TB_DELETEBUTTON, i, 0 ) ) - break; + if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) ) + { + wxLogLastError("TB_DELETEBUTTON"); + } } } - else + else // no old bitmap { TBADDBITMAP addBitmap; addBitmap.hInst = 0; - addBitmap.nID = (UINT)m_hBitmap; + addBitmap.nID = (UINT) hBitmap; if ( ::SendMessage(GetHwnd(), TB_ADDBITMAP, - (WPARAM) noButtons, (LPARAM)&addBitmap) == -1 ) + (WPARAM) nButtons, (LPARAM)&addBitmap) == -1 ) { wxFAIL_MSG(wxT("Could not add bitmap to toolbar")); } } - // Now add the buttons. + // Next add the buttons and separators + // ----------------------------------- + TBBUTTON *buttons = new TBBUTTON[nTools]; - // this array will holds the indices of all controls in the toolbar + // this array will hold the indices of all controls in the toolbar wxArrayInt controlIds; int i = 0; int bitmapId = 0; - node = m_tools.First(); - while (node) + for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + wxToolBarToolBase *tool = node->GetData(); + + // don't add separators to the vertical toolbar - looks ugly + if ( isVertical && tool->IsSeparator() ) + continue; + TBBUTTON& button = buttons[i]; wxZeroMemory(button); - switch ( tool->m_toolStyle ) + switch ( tool->GetStyle() ) { case wxTOOL_STYLE_CONTROL: - controlIds.Add(i); - button.idCommand = tool->m_index; + button.idCommand = tool->GetId(); // fall through: create just a separator too case wxTOOL_STYLE_SEPARATOR: @@ -399,21 +474,21 @@ bool wxToolBar95::CreateTools() case wxTOOL_STYLE_BUTTON: button.iBitmap = bitmapId; - button.idCommand = tool->m_index; + button.idCommand = tool->GetId(); - if (tool->m_enabled) + if ( tool->IsEnabled() ) button.fsState |= TBSTATE_ENABLED; - if (tool->m_toggleState) + if ( tool->IsToggled() ) button.fsState |= TBSTATE_CHECKED; - button.fsStyle = tool->m_isToggle ? TBSTYLE_CHECK - : TBSTYLE_BUTTON; + + button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK + : TBSTYLE_BUTTON; bitmapId++; break; } i++; - node = node->Next(); } if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS, @@ -424,12 +499,17 @@ bool wxToolBar95::CreateTools() delete [] buttons; + // Deal with the controls finally + // ------------------------------ + // adjust the controls size to fit nicely in the toolbar - size_t nControls = controlIds.GetCount(); - for ( size_t nCtrl = 0; nCtrl < nControls; nCtrl++ ) + size_t index = 0; + for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ ) { - wxToolBarTool *tool = (wxToolBarTool *) - m_tools.Nth(controlIds[nCtrl])->Data(); + wxToolBarToolBase *tool = node->GetData(); + if ( !tool->IsControl() ) + continue; + wxControl *control = tool->GetControl(); wxSize size = control->GetSize(); @@ -437,6 +517,15 @@ bool wxToolBar95::CreateTools() // 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) ) + { + wxLogLastError("TB_GETITEMRECT"); + } + // 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 @@ -450,9 +539,9 @@ bool wxToolBar95::CreateTools() tbbi.dwMask = TBIF_SIZE; tbbi.cx = size.x; if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO, - tool->m_index, (LPARAM)&tbbi) ) + tool->GetId(), (LPARAM)&tbbi) ) { - // the index is probably invalid + // the id is probably invalid? wxLogLastError("TB_SETBUTTONINFO"); } @@ -461,18 +550,7 @@ bool wxToolBar95::CreateTools() #endif // comctl32.dll 4.71 // TB_SETBUTTONINFO unavailable { - int index = GetIndexFromId(tool->m_index); - wxASSERT_MSG( index != wxNOT_FOUND, - _T("control wasn't added to the tbar?") ); - // try adding several separators to fit the controls width - RECT r; - if ( !SendMessage(GetHwnd(), TB_GETRECT, - tool->m_index, (LPARAM)(LPRECT)&r) ) - { - wxLogLastError("TB_GETITEMRECT"); - } - int widthSep = r.right - r.left; left = r.left; @@ -485,27 +563,24 @@ bool wxToolBar95::CreateTools() size_t nSeparators = size.x / widthSep; for ( size_t nSep = 0; nSep < nSeparators; nSep++ ) { - m_ids.Insert(0, (size_t)index); - 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); } // and position the control itself correctly vertically - RECT r; - if ( !SendMessage(GetHwnd(), TB_GETRECT, - tool->m_index, (LPARAM)(LPRECT)&r) ) - { - wxLogLastError("TB_GETRECT"); - } - int height = r.bottom - r.top; int diff = height - size.y; if ( diff < 0 ) @@ -516,12 +591,29 @@ bool wxToolBar95::CreateTools() diff = 2; } - control->Move(left == -1 ? r.left : left, r.top + diff / 2); + control->Move(left == -1 ? r.left : left, r.top + (diff + 1) / 2); } - (void)::SendMessage(GetHwnd(), TB_AUTOSIZE, (WPARAM)0, (LPARAM) 0); + // 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; - SetRows(m_maxRows); + if ( !isVertical ) + { + if ( m_maxRows == 0 ) + { + // if not set yet, only one row + SetRows(1); + } + } + else if ( m_nButtons > 0 ) // vertical non empty toolbar + { + if ( m_maxRows == 0 ) + { + // if not set yet, have one column + SetRows(m_nButtons); + } + } return TRUE; } @@ -530,31 +622,35 @@ bool wxToolBar95::CreateTools() // message handlers // ---------------------------------------------------------------------------- -bool wxToolBar95::MSWCommand(WXUINT cmd, WXWORD id) +bool wxToolBar::MSWCommand(WXUINT cmd, WXWORD id) { - wxNode *node = m_tools.Find((long)id); - if (!node) + wxToolBarToolBase *tool = FindById((int)id); + if ( !tool ) return FALSE; - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) + if ( tool->CanBeToggled() ) { LRESULT state = ::SendMessage(GetHwnd(), TB_GETSTATE, id, 0); - tool->m_toggleState = state & TBSTATE_CHECKED; + tool->SetToggle((state & TBSTATE_CHECKED) != 0); } - BOOL ret = OnLeftClick((int)id, tool->m_toggleState); - if ( ret == FALSE && tool->m_isToggle ) + bool toggled = tool->IsToggled(); + + // OnLeftClick() can veto the button state change - for buttons which may + // be toggled only, of couse + if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() ) { - tool->m_toggleState = !tool->m_toggleState; - ::SendMessage(GetHwnd(), TB_CHECKBUTTON, - (WPARAM)id, (LPARAM)MAKELONG(tool->m_toggleState, 0)); + // revert back + toggled = !toggled; + tool->SetToggle(toggled); + + ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0)); } return TRUE; } -bool wxToolBar95::MSWOnNotify(int WXUNUSED(idCtrl), +bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), WXLPARAM lParam, WXLPARAM *result) { @@ -573,13 +669,12 @@ bool wxToolBar95::MSWOnNotify(int WXUNUSED(idCtrl), LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam; int id = (int)ttText->hdr.idFrom; - wxNode *node = m_tools.Find((long)id); - if (!node) - return FALSE; - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); + wxToolBarToolBase *tool = FindById(id); + if ( !tool ) + return FALSE; - const wxString& help = tool->m_shortHelpString; + const wxString& help = tool->GetShortHelp(); if ( !help.IsEmpty() ) { @@ -617,91 +712,116 @@ bool wxToolBar95::MSWOnNotify(int WXUNUSED(idCtrl), } // For backward compatibility... - OnMouseEnter(tool->m_index); + OnMouseEnter(tool->GetId()); return TRUE; } // ---------------------------------------------------------------------------- -// sizing stuff +// toolbar geometry // ---------------------------------------------------------------------------- -void wxToolBar95::SetToolBitmapSize(const wxSize& size) +void wxToolBar::SetToolBitmapSize(const wxSize& size) { wxToolBarBase::SetToolBitmapSize(size); ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y)); } -void wxToolBar95::SetRows(int nRows) +void wxToolBar::SetRows(int nRows) { - // TRUE in wParam means to create at least as many rows + if ( nRows == m_maxRows ) + { + // avoid resizing the frame uselessly + return; + } + + // TRUE in wParam means to create at least as many rows, FALSE - + // at most as many RECT rect; ::SendMessage(GetHwnd(), TB_SETROWS, - MAKEWPARAM(nRows, TRUE), (LPARAM) &rect); - - m_maxWidth = (rect.right - rect.left + 2); - m_maxHeight = (rect.bottom - rect.top + 2); + MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)), + (LPARAM) &rect); m_maxRows = nRows; + + UpdateSize(); +} + +// The button size is bigger than the bitmap size +wxSize wxToolBar::GetToolSize() const +{ + // 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); + + return wxSize(LOWORD(dw), HIWORD(dw)); + } + else +#endif // comctl32.dll 4.70+ + { + // defaults + return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); + } } -wxSize wxToolBar95::GetMaxSize() const +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const { - if ( (m_maxWidth == -1) || (m_maxHeight == -1) ) + POINT pt; + pt.x = x; + pt.y = y; + int index = (int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt); + if ( index < 0 ) { - // it has a side effect of filling m_maxWidth/Height variables - ((wxToolBar95 *)this)->SetRows(m_maxRows); // const_cast + // it's a separator or there is no tool at all there + return (wxToolBarToolBase *)NULL; } - return wxSize(m_maxWidth, m_maxHeight); + return m_tools.Item((size_t)index)->GetData(); } -// The button size is bigger than the bitmap size -wxSize wxToolBar95::GetToolSize() const +void wxToolBar::UpdateSize() { - // FIXME: this is completely bogus (VZ) - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); + // we must refresh the frame after the toolbar size (possibly) changed + wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); + if ( frame ) + { + // don't change the size, we just need to generate a WM_SIZE + RECT r; + if ( !GetWindowRect(GetHwndOf(frame), &r) ) + { + wxLogLastError(_T("GetWindowRect")); + } + + (void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED, + MAKELPARAM(r.right - r.left, r.bottom - r.top)); + } + } // ---------------------------------------------------------------------------- // tool state // ---------------------------------------------------------------------------- -void wxToolBar95::EnableTool(int toolIndex, bool enable) +void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - tool->m_enabled = enable; - ::SendMessage(GetHwnd(), TB_ENABLEBUTTON, - (WPARAM)toolIndex, (LPARAM)MAKELONG(enable, 0)); - } + ::SendMessage(GetHwnd(), TB_ENABLEBUTTON, + (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0)); } -void wxToolBar95::ToggleTool(int toolIndex, bool toggle) +void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool toggle) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_isToggle) - { - tool->m_toggleState = toggle; - ::SendMessage(GetHwnd(), TB_CHECKBUTTON, - (WPARAM)toolIndex, (LPARAM)MAKELONG(toggle, 0)); - } - } + ::SendMessage(GetHwnd(), TB_CHECKBUTTON, + (WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0)); } -bool wxToolBar95::GetToolState(int toolIndex) const +void wxToolBar::DoSetToggle(wxToolBarToolBase *tool, bool toggle) { - wxASSERT_MSG( GetIndexFromId(toolIndex) != wxNOT_FOUND, - _T("invalid toolbar button id") ); - - return ::SendMessage(GetHwnd(), TB_ISBUTTONCHECKED, - (WPARAM)toolIndex, (LPARAM)0) != 0; + // 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") ); } // ---------------------------------------------------------------------------- @@ -709,13 +829,13 @@ bool wxToolBar95::GetToolState(int toolIndex) const // ---------------------------------------------------------------------------- // Responds to colour changes, and passes event on to children. -void wxToolBar95::OnSysColourChanged(wxSysColourChangedEvent& event) +void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event) { m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)), GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE))); // Remap the buttons - CreateTools(); + Realize(); Refresh(); @@ -723,7 +843,7 @@ void wxToolBar95::OnSysColourChanged(wxSysColourChangedEvent& event) wxWindow::OnSysColourChanged(event); } -void wxToolBar95::OnMouseEvent(wxMouseEvent& event) +void wxToolBar::OnMouseEvent(wxMouseEvent& event) { if (event.RightDown()) { @@ -737,21 +857,50 @@ void wxToolBar95::OnMouseEvent(wxMouseEvent& event) } } - -// ---------------------------------------------------------------------------- -// helpers -// ---------------------------------------------------------------------------- - -int wxToolBar95::GetIndexFromId(int id) const +long wxToolBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { - size_t count = m_ids.GetCount(); - for ( size_t n = 0; n < count; n++ ) + if ( nMsg == WM_SIZE ) { - if ( m_ids[n] == id ) - return n; + // 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; + + 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; + } + } + + if ( MAKELPARAM(w, h) != lParam ) + { + // size really changed + SetSize(w, h); + } + + // message processed + return 0; + } } - return wxNOT_FOUND; + return wxControl::MSWWindowProc(nMsg, wParam, lParam); } // ---------------------------------------------------------------------------- @@ -766,7 +915,7 @@ int wxToolBar95::GetIndexFromId(int id) const #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(000,000,255)) // blue +#define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue #define BGR_BACKGROUND (RGB(255,000,255)) // magenta void wxMapBitmap(HBITMAP hBitmap, int width, int height) @@ -856,4 +1005,4 @@ void wxMapBitmap(HBITMAP hBitmap, int width, int height) #endif -#endif // !(wxUSE_TOOLBAR && Win95) +#endif // wxUSE_TOOLBAR && Win95 diff --git a/src/msw/tbarmsw.cpp b/src/msw/tbarmsw.cpp index 9f2470286e..e7ab1de5c8 100644 --- a/src/msw/tbarmsw.cpp +++ b/src/msw/tbarmsw.cpp @@ -1,37 +1,49 @@ ///////////////////////////////////////////////////////////////////////////// // Name: tbarmsw.cpp -// Purpose: wxToolBarMSW +// Purpose: wxToolBar // Author: Julian Smart -// Modified by: +// Modified by: 13.12.99 by VZ during toolbar classes reorganization // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "tbarmsw.h" + #pragma implementation "tbarmsw.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #ifndef WX_PRECOMP -#include "wx/wx.h" + #include "wx/wx.h" #endif -#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR +#if wxUSE_BUTTONBAR && wxUSE_TOOLBAR && !wxUSE_TOOLBAR_SIMPLE + +#if !defined(__WIN32__) && !wxUSE_IMAGE_LOADING_IN_MSW + #error wxToolBar needs wxUSE_IMAGE_LOADING_IN_MSW under Win16 +#endif #if !defined(__GNUWIN32__) && !defined(__SALFORDC__) -#include "malloc.h" + #include "malloc.h" #endif #if !defined(__MWERKS__) && !defined(__SALFORDC__) -#include + #include #endif #include @@ -43,482 +55,621 @@ #include "wx/msw/private.h" #include "wx/msw/dib.h" +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + #define DEFAULTBITMAPX 16 #define DEFAULTBITMAPY 15 #define DEFAULTBUTTONX 24 #define DEFAULTBUTTONY 22 #define DEFAULTBARHEIGHT 27 -/////// Non-Windows 95 implementation +// +// States (not all of them currently used) +// +#define wxTBSTATE_CHECKED 0x01 // radio button is checked +#define wxTBSTATE_PRESSED 0x02 // button is being depressed (any style) +#define wxTBSTATE_ENABLED 0x04 // button is enabled +#define wxTBSTATE_HIDDEN 0x08 // button is hidden +#define wxTBSTATE_INDETERMINATE 0x10 // button is indeterminate -#if !wxUSE_IMAGE_LOADING_IN_MSW -#error If wxUSE_IMAGE_LOADING_IN_MSW is set to 0, then wxUSE_BUTTONBAR must be set to 0 too. -#endif +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase) +class WXDLLEXPORT wxToolBarTool : public wxToolBarToolBase +{ +public: + wxToolBarTool(wxToolBar *tbar, + int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) + : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString) + { + } + + wxToolBarTool(wxToolBar *tbar, wxControl *control) + : wxToolBarToolBase(tbar, control) + { + } -BEGIN_EVENT_TABLE(wxToolBarMSW, wxToolBarBase) - EVT_SIZE(wxToolBarMSW::OnSize) - EVT_PAINT(wxToolBarMSW::OnPaint) - EVT_MOUSE_EVENTS(wxToolBarMSW::OnMouseEvent) + void SetSize(const wxSize& size) + { + m_width = size.x; + m_height = size.y; + } + + long GetWidth() const { return m_width; } + long GetHeight() const { return m_height; } + + wxCoord m_x; + wxCoord m_y; + wxCoord m_width; + wxCoord m_height; +}; + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +#if !USE_SHARED_LIBRARY +IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) + +BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) + EVT_PAINT(wxToolBar::OnPaint) + EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent) END_EVENT_TABLE() +#endif + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxToolBarTool +// ---------------------------------------------------------------------------- + +wxToolBarToolBase *wxToolBar::CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString) +{ + return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle, + clientData, shortHelpString, longHelpString); +} -wxToolBarMSW::wxToolBarMSW(void) +wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) { - m_hbrDither = 0; - m_rgbFace = 0; - m_rgbShadow = 0; - m_rgbHilight = 0; - m_rgbFrame = 0; - m_hdcMono = 0; - m_hbmMono = 0; - m_hbmDefault = 0; - m_defaultWidth = DEFAULTBITMAPX; - m_defaultHeight = DEFAULTBITMAPY; + return new wxToolBarTool(this, control); } -bool wxToolBarMSW::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, const wxString& name) +// ---------------------------------------------------------------------------- +// wxToolBar +// ---------------------------------------------------------------------------- + +void wxToolBar::Init() { - if ( ! wxWindow::Create(parent, id, pos, size, style, name) ) - return FALSE; + m_hbrDither = 0; + m_rgbFace = 0; + m_rgbShadow = 0; + m_rgbHilight = 0; + m_rgbFrame = 0; + m_hdcMono = 0; + m_hbmMono = 0; + m_hbmDefault = 0; + + m_defaultWidth = DEFAULTBITMAPX; + m_defaultHeight = DEFAULTBITMAPY; - if ( style & wxTB_HORIZONTAL ) - { m_lastX = 3; m_lastY = 7; } - else - { m_lastX = 7; m_lastY = 3; } - m_maxWidth = m_maxHeight = 0; - m_pressedTool = m_currentTool = -1; - m_xMargin = 0; - m_yMargin = 0; - m_toolPacking = 1; - m_toolSeparation = 5; + m_xPos = + m_yPos = -1; - // Set it to grey - SetBackgroundColour(wxColour(192, 192, 192)); + m_maxWidth = m_maxHeight = 0; + m_pressedTool = m_currentTool = -1; + m_toolPacking = 1; + m_toolSeparation = 5; +} - m_hbrDither = 0; - m_rgbFace = 0; - m_rgbShadow = 0; - m_rgbHilight = 0; - m_rgbFrame = 0; - m_hdcMono = 0; - m_hbmMono = 0; - m_hbmDefault = 0; - m_defaultWidth = DEFAULTBITMAPX; - m_defaultHeight = DEFAULTBITMAPY; +bool wxToolBar::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + if ( !wxWindow::Create(parent, id, pos, size, style, name) ) + return FALSE; - InitGlobalObjects(); + if ( style & wxTB_HORIZONTAL ) + { + m_lastX = 3; + m_lastY = 7; + } + else + { + m_lastX = 7; + m_lastY = 3; + } - return TRUE; + // Set it to grey + SetBackgroundColour(wxColour(192, 192, 192)); + + InitGlobalObjects(); + + return TRUE; } -wxToolBarMSW::~wxToolBarMSW(void) +wxToolBar::~wxToolBar() { - FreeGlobalObjects(); + FreeGlobalObjects(); } -void wxToolBarMSW::SetToolBitmapSize(const wxSize& size) +void wxToolBar::SetToolBitmapSize(const wxSize& size) { - m_defaultWidth = size.x; m_defaultHeight = size.y; - FreeGlobalObjects(); - InitGlobalObjects(); + m_defaultWidth = size.x; + m_defaultHeight = size.y; + + FreeGlobalObjects(); + InitGlobalObjects(); } // The button size is bigger than the bitmap size -wxSize wxToolBarMSW::GetToolSize(void) const +wxSize wxToolBar::GetToolSize() const { - return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); + return wxSize(m_defaultWidth + 8, m_defaultHeight + 7); } -void wxToolBarMSW::OnPaint(wxPaintEvent& event) +wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const { - wxPaintDC dc(this); + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while (node) + { + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + if ((x >= tool->m_x) && (y >= tool->m_y) && + (x <= (tool->m_x + tool->GetWidth())) && + (y <= (tool->m_y + tool->GetHeight()))) + { + return tool; + } - static int wxOnPaintCount = 0; + node = node->GetNext(); + } - // Prevent reentry of OnPaint which would cause - // wxMemoryDC errors. - if (wxOnPaintCount > 0) - return; - wxOnPaintCount ++; + return (wxToolBarToolBase *)NULL; +} - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_toolStyle != wxTOOL_STYLE_SEPARATOR) - { - int state = wxTBSTATE_ENABLED; - if (!tool->m_enabled) - state = 0; - if (tool->m_isToggle && tool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, tool, state); - } - node = node->Next(); - } - wxOnPaintCount --; +wxToolBarToolBase *wxToolBar::AddTool(int id, + const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + bool toggle, + wxCoord xPos, + wxCoord yPos, + wxObject *clientData, + const wxString& helpString1, + const wxString& helpString2) +{ + // rememeber the position for DoInsertTool() + m_xPos = xPos; + m_yPos = yPos; + + return wxToolBarBase::AddTool(id, bitmap, pushedBitmap, toggle, + xPos, yPos, clientData, + helpString1, helpString2); } -void wxToolBarMSW::OnSize(wxSizeEvent& event) +void wxToolBar::OnPaint(wxPaintEvent& event) { - wxToolBarBase::OnSize(event); + wxPaintDC dc(this); + + static int wxOnPaintCount = 0; + + // Prevent reentry of OnPaint which would cause + // wxMemoryDC errors. + if (wxOnPaintCount > 0) + return; + wxOnPaintCount++; + + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while (node) + { + wxToolBarToolBase *tool = node->GetData(); + if ( tool->GetStyle()!= wxTOOL_STYLE_BUTTON ) + { + int state = tool->IsEnabled() ? wxTBSTATE_ENABLED : 0; + if ( tool->IsToggled() ) + state |= wxTBSTATE_CHECKED; + + DrawTool(dc, tool, state); + } + + node = node->GetNext(); + } + + wxOnPaintCount--; } // If a Button is disabled, then NO function (besides leaving // or entering) should be carried out. Therefore the additions // of 'enabled' testing (Stefan Hammes). -void wxToolBarMSW::OnMouseEvent(wxMouseEvent& event) +void wxToolBar::OnMouseEvent(wxMouseEvent& event) { - static wxToolBarTool *eventCurrentTool = NULL; - wxClientDC dc(this); + static wxToolBarToolBase *eventCurrentTool = NULL; + wxClientDC dc(this); - if (event.Leaving()) - { - m_currentTool = -1; - if (eventCurrentTool && eventCurrentTool->m_enabled) + if (event.Leaving()) { - ::ReleaseCapture(); - int state = wxTBSTATE_ENABLED; - if (eventCurrentTool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, eventCurrentTool, state); - eventCurrentTool = NULL; + m_currentTool = -1; + if (eventCurrentTool && eventCurrentTool->IsEnabled()) + { + ::ReleaseCapture(); + int state = wxTBSTATE_ENABLED; + if (eventCurrentTool->IsToggled()) + state |= wxTBSTATE_CHECKED; + DrawTool(dc, eventCurrentTool, state); + eventCurrentTool = NULL; + } + OnMouseEnter(-1); + return; } - OnMouseEnter(-1); - return; - } - long x, y; - event.GetPosition(&x, &y); - wxToolBarTool *tool = FindToolForPosition(x, y); + wxCoord x, y; + event.GetPosition(&x, &y); + wxToolBarToolBase *tool = FindToolForPosition(x, y); - if (!tool) - { - if (eventCurrentTool && eventCurrentTool->m_enabled) + if (!tool) { - ::ReleaseCapture(); - - int state = wxTBSTATE_ENABLED; - if (eventCurrentTool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, eventCurrentTool, state); - eventCurrentTool = NULL; - } - if (m_currentTool > -1) - { - m_currentTool = -1; - OnMouseEnter(-1); + if (eventCurrentTool && eventCurrentTool->IsEnabled()) + { + ::ReleaseCapture(); + + int state = wxTBSTATE_ENABLED; + if (eventCurrentTool->IsToggled()) + state |= wxTBSTATE_CHECKED; + DrawTool(dc, eventCurrentTool, state); + eventCurrentTool = NULL; + } + if (m_currentTool > -1) + { + m_currentTool = -1; + OnMouseEnter(-1); + } + return; } - return; - } - - if (!event.Dragging() && !event.IsButton()) - { - if (tool->m_index != m_currentTool) + + if (!event.Dragging() && !event.IsButton()) { - OnMouseEnter(tool->m_index); - m_currentTool = tool->m_index; - return; + if (tool->GetId() != m_currentTool) + { + OnMouseEnter(m_currentTool = tool->GetId()); + return; + } } - } - if (event.Dragging() && tool->m_enabled) - { - if (eventCurrentTool) + if (event.Dragging() && tool->IsEnabled()) { - // Might have dragged outside tool - if (eventCurrentTool != tool) - { - int state = wxTBSTATE_ENABLED; - if (tool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, tool, state); - eventCurrentTool = NULL; - return; - } + if (eventCurrentTool) + { + // Might have dragged outside tool + if (eventCurrentTool != tool) + { + int state = wxTBSTATE_ENABLED; + if (tool->IsToggled()) + state |= wxTBSTATE_CHECKED; + DrawTool(dc, tool, state); + eventCurrentTool = NULL; + return; + } + } + else + { + if (tool && event.LeftIsDown() && tool->IsEnabled()) + { + eventCurrentTool = tool; + ::SetCapture((HWND) GetHWND()); + int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED; + if (tool->IsToggled()) + state |= wxTBSTATE_CHECKED; + DrawTool(dc, tool, state); + } + } } - else + if (event.LeftDown() && tool->IsEnabled()) { - if (tool && event.LeftIsDown() && tool->m_enabled) - { eventCurrentTool = tool; ::SetCapture((HWND) GetHWND()); int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED; - if (tool->m_toggleState) - state |= wxTBSTATE_CHECKED; + if (tool->IsToggled()) + state |= wxTBSTATE_CHECKED; DrawTool(dc, tool, state); - } } - } - if (event.LeftDown() && tool->m_enabled) - { - eventCurrentTool = tool; - ::SetCapture((HWND) GetHWND()); - int state = wxTBSTATE_ENABLED|wxTBSTATE_PRESSED; - if (tool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, tool, state); - } - else if (event.LeftUp() && tool->m_enabled) - { - if (eventCurrentTool) - ::ReleaseCapture(); - if (eventCurrentTool == tool) + else if (event.LeftUp() && tool->IsEnabled()) { - if (tool->m_isToggle) - { - tool->m_toggleState = !tool->m_toggleState; - if (!OnLeftClick(tool->m_index, tool->m_toggleState)) + if (eventCurrentTool) + ::ReleaseCapture(); + if (eventCurrentTool == tool) { - tool->m_toggleState = !tool->m_toggleState; + if (tool->CanBeToggled()) + { + tool->Toggle(); + if (!OnLeftClick(tool->GetId(), tool->IsToggled())) + { + tool->Toggle(); + } + int state = wxTBSTATE_ENABLED; + if (tool->IsToggled()) + state |= wxTBSTATE_CHECKED; + DrawTool(dc, tool, state); + } + else + { + int state = wxTBSTATE_ENABLED; + if (tool->IsToggled()) + state |= wxTBSTATE_CHECKED; + DrawTool(dc, tool, state); + OnLeftClick(tool->GetId(), tool->IsToggled()); + } } - int state = wxTBSTATE_ENABLED; - if (tool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, tool, state); - } - else - { - int state = wxTBSTATE_ENABLED; - if (tool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, tool, state); - OnLeftClick(tool->m_index, tool->m_toggleState); - } + eventCurrentTool = NULL; + } + else if (event.RightDown() && tool->IsEnabled()) + { + OnRightClick(tool->GetId(), x, y); } - eventCurrentTool = NULL; - } - else if (event.RightDown() && tool->m_enabled) - { - OnRightClick(tool->m_index, x, y); - } } -// This function enables/disables a toolbar tool and redraws it. -// If that would not be done, the enabling/disabling wouldn't be -// visible on the screen. -void wxToolBarMSW::EnableTool(int toolIndex, bool enable) +void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool WXUNUSED(enable)) { - wxNode *node = m_tools.Find((long)toolIndex); - if (node) - { - wxClientDC dc(this); - - // at first do the enabling/disabling in the base class - wxToolBarBase::EnableTool(toolIndex,enable); - // then calculate the state of the tool and draw it - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - int state = 0; - if(tool->m_toggleState) state |= wxTBSTATE_CHECKED; - if(tool->m_enabled) state |= wxTBSTATE_ENABLED; - // how can i access the PRESSED state??? - DrawTool(dc, tool,state); - } + DoRedrawTool(tool); } -void wxToolBarMSW::DrawTool(wxDC& dc, wxToolBarTool *tool, int state) +void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool WXUNUSED(toggle)) { - DrawButton(dc.GetHDC(), (int)tool->m_x, (int)tool->m_y, (int)tool->GetWidth(), (int)tool->GetHeight(), tool, state); + DoRedrawTool(tool); } -void wxToolBarMSW::DrawTool(wxDC& dc, wxMemoryDC& , wxToolBarTool *tool) +void wxToolBar::DoSetToggle(wxToolBarToolBase * WXUNUSED(tool), + bool WXUNUSED(toggle)) { - int state = wxTBSTATE_ENABLED; - if (!tool->m_enabled) - state = 0; - if (tool->m_toggleState) - state |= wxTBSTATE_CHECKED; - DrawTool(dc, tool, state); + // nothing to do } -// If pushedBitmap is NULL, a reversed version of bitmap is -// created and used as the pushed/toggled image. -// If toggle is TRUE, the button toggles between the two states. -wxToolBarTool *wxToolBarMSW::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::DoRedrawTool(wxToolBarToolBase *tool) { - // Using bitmap2 can cause problems (don't know why!) + wxClientDC dc(this); - // TODO: use the mapping code from wxToolBar95 to get it right in this class -#if !defined(__WIN32__) && !defined(__WIN386__) - wxBitmap bitmap2; - if (toggle) - { - bitmap2.SetHBITMAP( (WXHBITMAP) CreateMappedBitmap((WXHINSTANCE)wxGetInstance(), (WXHBITMAP) ((wxBitmap& )bitmap).GetHBITMAP())); - } + DrawTool(dc, tool); +} - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, bitmap2, toggle, xPos, yPos, helpString1, helpString2); -#else - wxToolBarTool *tool = new wxToolBarTool(index, bitmap, wxNullBitmap, toggle, xPos, yPos, helpString1, helpString2); -#endif +void wxToolBar::DrawTool(wxDC& dc, wxToolBarToolBase *toolBase, int state) +{ + wxToolBarTool *tool = (wxToolBarTool *)toolBase; - tool->m_clientData = clientData; + DrawButton(dc.GetHDC(), + tool->m_x, tool->m_y, + tool->GetWidth(), tool->GetHeight(), + tool, state); +} - if (xPos > -1) - tool->m_x = xPos; - else - tool->m_x = m_xMargin; +void wxToolBar::DrawTool(wxDC& dc, wxToolBarToolBase *tool) +{ + int state = 0; + if (tool->IsEnabled()) + state |= wxTBSTATE_ENABLED; + if (tool->IsToggled()) + state |= wxTBSTATE_CHECKED; + // how can i access the PRESSED state??? - if (yPos > -1) - tool->m_y = yPos; - else - tool->m_y = m_yMargin; + DrawTool(dc, tool, state); +} - tool->m_deleteSecondBitmap = TRUE; - tool->SetSize(GetToolSize().x, GetToolSize().y); - - // Calculate reasonable max size in case Layout() not called - if ((tool->m_x + bitmap.GetWidth() + m_xMargin) > m_maxWidth) - m_maxWidth = (tool->m_x + tool->GetWidth() + m_xMargin); +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), + wxToolBarToolBase *tool) +{ + // VZ: didn't test whether it works, but why not... + tool->Detach(); - if ((tool->m_y + bitmap.GetHeight() + m_yMargin) > m_maxHeight) - m_maxHeight = (tool->m_y + tool->GetHeight() + m_yMargin); + Refresh(); - m_tools.Append((long)index, tool); - return tool; + return TRUE; } -void wxToolBarMSW::LayoutTools() +bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) { - m_currentRowsOrColumns = 0; - m_lastX = m_xMargin; - m_lastY = m_yMargin; - int maxToolWidth = 0; - int maxToolHeight = 0; - m_maxWidth = 0; - m_maxHeight = 0; + wxToolBarTool *tool = (wxToolBarTool *)toolBase; - // Find the maximum tool width and height - wxNode *node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->GetWidth() > maxToolWidth) - maxToolWidth = (int)tool->GetWidth(); - if (tool->GetHeight() > maxToolHeight) - maxToolHeight = (int)tool->GetHeight(); - node = node->Next(); - } + wxCHECK_MSG( !tool->IsControl(), FALSE, + _T("generic wxToolBar doesn't support controls") ); + + // TODO: use the mapping code from wxToolBar95 to get it right in this class +#if !defined(__WIN32__) && !defined(__WIN386__) + wxBitmap bitmap2; + if (toggle) + { + HBITMAP hbmp = CreateMappedBitmap((WXHINSTANCE)wxGetInstance(), + GetHbitmapOf(tool->GetBitmap1())); + + wxBitmap bmp; + bmp.SetHBITMAP((WXHBITMAP)hbmp); + tool->SetBitmap2(bmp); + } +#endif - int separatorSize = m_toolSeparation; + tool->m_x = m_xPos; + if ( tool->m_x == -1 ) + tool->m_x = m_xMargin; - node = m_tools.First(); - while (node) - { - wxToolBarTool *tool = (wxToolBarTool *)node->Data(); - if (tool->m_toolStyle == wxTOOL_STYLE_SEPARATOR) + tool->m_y = m_yPos; + if ( tool->m_y == -1 ) + tool->m_y = m_yMargin; + + tool->SetSize(GetToolSize()); + + if ( tool->IsButton() ) { - if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) - { - if (m_currentRowsOrColumns >= m_maxCols) - m_lastY += separatorSize; - else - m_lastX += separatorSize; - } - else - { - if (m_currentRowsOrColumns >= m_maxRows) - m_lastX += separatorSize; - else - m_lastY += separatorSize; - } + // Calculate reasonable max size in case Layout() not called + if ((tool->m_x + tool->GetBitmap1().GetWidth() + m_xMargin) > m_maxWidth) + m_maxWidth = (tool->m_x + tool->GetWidth() + m_xMargin); + + if ((tool->m_y + tool->GetBitmap1().GetHeight() + m_yMargin) > m_maxHeight) + m_maxHeight = (tool->m_y + tool->GetHeight() + m_yMargin); } - else if (tool->m_toolStyle == wxTOOL_STYLE_BUTTON) + + return TRUE; +} + +bool wxToolBar::Realize() +{ + m_currentRowsOrColumns = 0; + m_lastX = m_xMargin; + m_lastY = m_yMargin; + int maxToolWidth = 0; + int maxToolHeight = 0; + m_maxWidth = 0; + m_maxHeight = 0; + + // Find the maximum tool width and height + wxToolBarToolsList::Node *node = m_tools.GetFirst(); + while (node) { - if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) - { - if (m_currentRowsOrColumns >= m_maxCols) + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + if (tool->GetWidth() > maxToolWidth) + maxToolWidth = tool->GetWidth(); + if (tool->GetHeight() > maxToolHeight) + maxToolHeight = tool->GetHeight(); + node = node->GetNext(); + } + + int separatorSize = m_toolSeparation; + + node = m_tools.GetFirst(); + while (node) + { + wxToolBarTool *tool = (wxToolBarTool *)node->GetData(); + if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR) { - m_currentRowsOrColumns = 0; - m_lastX = m_xMargin; - m_lastY += maxToolHeight + m_toolPacking; + if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) + { + if (m_currentRowsOrColumns >= m_maxCols) + m_lastY += separatorSize; + else + m_lastX += separatorSize; + } + else + { + if (m_currentRowsOrColumns >= m_maxRows) + m_lastX += separatorSize; + else + m_lastY += separatorSize; + } } - tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); - tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); - - m_lastX += maxToolWidth + m_toolPacking; - } - else - { - if (m_currentRowsOrColumns >= m_maxRows) + else if (tool->GetStyle() == wxTOOL_STYLE_BUTTON) { - m_currentRowsOrColumns = 0; - m_lastX += (maxToolWidth + m_toolPacking); - m_lastY = m_yMargin; + if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) + { + if (m_currentRowsOrColumns >= m_maxCols) + { + m_currentRowsOrColumns = 0; + m_lastX = m_xMargin; + m_lastY += maxToolHeight + m_toolPacking; + } + tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); + tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); + + m_lastX += maxToolWidth + m_toolPacking; + } + else + { + if (m_currentRowsOrColumns >= m_maxRows) + { + m_currentRowsOrColumns = 0; + m_lastX += (maxToolWidth + m_toolPacking); + m_lastY = m_yMargin; + } + tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); + tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); + + m_lastY += maxToolHeight + m_toolPacking; + } + m_currentRowsOrColumns ++; } - tool->m_x = (long) (m_lastX + (maxToolWidth - tool->GetWidth())/2.0); - tool->m_y = (long) (m_lastY + (maxToolHeight - tool->GetHeight())/2.0); - - m_lastY += maxToolHeight + m_toolPacking; - } - m_currentRowsOrColumns ++; + + if (m_lastX > m_maxWidth) + m_maxWidth = m_lastX; + if (m_lastY > m_maxHeight) + m_maxHeight = m_lastY; + + node = node->GetNext(); } - - if (m_lastX > m_maxWidth) - m_maxWidth = m_lastX; - if (m_lastY > m_maxHeight) - m_maxHeight = m_lastY; - node = node->Next(); - } - if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) - { - m_maxWidth += maxToolWidth; - m_maxHeight += maxToolHeight; - } - else - { - m_maxWidth += maxToolWidth; - m_maxHeight += maxToolHeight; - } + if ( GetWindowStyleFlag() & wxTB_HORIZONTAL ) + { + m_maxWidth += maxToolWidth; + m_maxHeight += maxToolHeight; + } + else + { + m_maxWidth += maxToolWidth; + m_maxHeight += maxToolHeight; + } - m_maxWidth += m_xMargin; - m_maxHeight += m_yMargin; + m_maxWidth += m_xMargin; + m_maxHeight += m_yMargin; - SetSize(m_maxWidth, m_maxHeight); -} + SetSize(m_maxWidth, m_maxHeight); + return TRUE; +} -bool wxToolBarMSW::InitGlobalObjects(void) +bool wxToolBar::InitGlobalObjects() { - GetSysColors(); - if (!CreateDitherBrush()) - return FALSE; + GetSysColors(); + if (!CreateDitherBrush()) + return FALSE; - m_hdcMono = (WXHDC) CreateCompatibleDC(NULL); - if (!m_hdcMono) - return FALSE; + m_hdcMono = (WXHDC) CreateCompatibleDC(NULL); + if (!m_hdcMono) + return FALSE; - m_hbmMono = (WXHBITMAP) CreateBitmap((int)GetToolSize().x, (int)GetToolSize().y, 1, 1, NULL); - if (!m_hbmMono) - return FALSE; + m_hbmMono = (WXHBITMAP) CreateBitmap((int)GetToolSize().x, (int)GetToolSize().y, 1, 1, NULL); + if (!m_hbmMono) + return FALSE; - m_hbmDefault = (WXHBITMAP) SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmMono); - return TRUE; + m_hbmDefault = (WXHBITMAP) SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmMono); + return TRUE; } -void wxToolBarMSW::FreeGlobalObjects(void) +void wxToolBar::FreeGlobalObjects() { FreeDitherBrush(); if (m_hdcMono) { - if (m_hbmDefault) - { - SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmDefault); - m_hbmDefault = 0; - } - DeleteDC((HDC) m_hdcMono); // toast the DCs + if (m_hbmDefault) + { + SelectObject((HDC) m_hdcMono, (HBITMAP) m_hbmDefault); + m_hbmDefault = 0; + } + DeleteDC((HDC) m_hdcMono); // toast the DCs } m_hdcMono = 0; if (m_hbmMono) - DeleteObject((HBITMAP) m_hbmMono); + DeleteObject((HBITMAP) m_hbmMono); m_hbmMono = 0; } +// ---------------------------------------------------------------------------- +// drawing routines +// ---------------------------------------------------------------------------- -void wxToolBarMSW::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb) +void wxToolBar::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb) { RECT rc; @@ -536,7 +687,7 @@ void wxToolBarMSW::PatB(WXHDC hdc,int x,int y,int dx,int dy, long rgb) // 1's where color == COLOR_BTNFACE || COLOR_HILIGHT // 0's everywhere else -void wxToolBarMSW::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int dy) +void wxToolBar::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int dy) { HDC globalDC = ::GetDC(NULL); HDC hdcGlyphs = CreateCompatibleDC((HDC) globalDC); @@ -567,36 +718,36 @@ void wxToolBarMSW::CreateMask(WXHDC hdc, int xoffset, int yoffset, int dx, int d DeleteDC(hdcGlyphs); } -void wxToolBarMSW::DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state) +void wxToolBar::DrawBlankButton(WXHDC hdc, int x, int y, int dx, int dy, int state) { // face color PatB(hdc, x, y, dx, dy, m_rgbFace); if (state & wxTBSTATE_PRESSED) { - PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame); - PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame); - PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame); - PatB(hdc, x + dx - 1, y +1, 1, dy - 2, m_rgbFrame); - PatB(hdc, x + 1, y + 1, 1, dy-2, m_rgbShadow); - PatB(hdc, x + 1, y + 1, dx-2, 1, m_rgbShadow); + PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame); + PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame); + PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame); + PatB(hdc, x + dx - 1, y +1, 1, dy - 2, m_rgbFrame); + PatB(hdc, x + 1, y + 1, 1, dy-2, m_rgbShadow); + PatB(hdc, x + 1, y + 1, dx-2, 1, m_rgbShadow); } else { - PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame); - PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame); - PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame); - PatB(hdc, x + dx - 1, y + 1, 1, dy - 2, m_rgbFrame); - dx -= 2; - dy -= 2; - PatB(hdc, x + 1, y + 1, 1, dy - 1, m_rgbHilight); - PatB(hdc, x + 1, y + 1, dx - 1, 1, m_rgbHilight); - PatB(hdc, x + dx, y + 1, 1, dy, m_rgbShadow); - PatB(hdc, x + 1, y + dy, dx, 1, m_rgbShadow); - PatB(hdc, x + dx - 1, y + 2, 1, dy - 2, m_rgbShadow); - PatB(hdc, x + 2, y + dy - 1, dx - 2, 1, m_rgbShadow); + PatB(hdc, x + 1, y, dx - 2, 1, m_rgbFrame); + PatB(hdc, x + 1, y + dy - 1, dx - 2, 1, m_rgbFrame); + PatB(hdc, x, y + 1, 1, dy - 2, m_rgbFrame); + PatB(hdc, x + dx - 1, y + 1, 1, dy - 2, m_rgbFrame); + dx -= 2; + dy -= 2; + PatB(hdc, x + 1, y + 1, 1, dy - 1, m_rgbHilight); + PatB(hdc, x + 1, y + 1, dx - 1, 1, m_rgbHilight); + PatB(hdc, x + dx, y + 1, 1, dy, m_rgbShadow); + PatB(hdc, x + 1, y + dy, dx, 1, m_rgbShadow); + PatB(hdc, x + dx - 1, y + 2, 1, dy - 2, m_rgbShadow); + PatB(hdc, x + 2, y + dy - 1, dx - 2, 1, m_rgbShadow); } } -void wxToolBarMSW::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBarTool *tool, int state) +void wxToolBar::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBarTool *tool, int state) { int yOffset; HBRUSH hbrOld, hbr; @@ -633,14 +784,16 @@ void wxToolBarMSW::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBar // Using bitmap2 can cause problems (don't know why!) #if !defined(__WIN32__) && !defined(__WIN386__) HBITMAP bitmapOld; - if (tool->m_bitmap2.Ok()) - bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, (HBITMAP) tool->m_bitmap2.GetHBITMAP()); + if (tool->GetBitmap2().Ok()) + bitmapOld = GetHbitmapOf(tool->GetBitmap2()); else - bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, (HBITMAP) tool->m_bitmap1.GetHBITMAP()); + bitmapOld = GetHbitmapOf(tool->GetBitmap1()); #else - HBITMAP bitmapOld = (HBITMAP) SelectObject(hdcGlyphs, (HBITMAP) tool->m_bitmap1.GetHBITMAP()); + HBITMAP bitmapOld = GetHbitmapOf(tool->GetBitmap1()); #endif + bitmapOld = (HBITMAP)SelectObject(hdcGlyphs, bitmapOld); + // calculate offset of face from (x,y). y is always from the top, // so the offset is easy. x needs to be centered in face. yOffset = 1; @@ -719,7 +872,11 @@ void wxToolBarMSW::DrawButton(WXHDC hdc, int x, int y, int dx, int dy, wxToolBar DeleteDC(hdcGlyphs); } -void wxToolBarMSW::GetSysColors(void) +// ---------------------------------------------------------------------------- +// drawing helpers +// ---------------------------------------------------------------------------- + +void wxToolBar::GetSysColors() { static COLORREF rgbSaveFace = 0xffffffffL, rgbSaveShadow = 0xffffffffL, @@ -751,7 +908,7 @@ void wxToolBarMSW::GetSysColors(void) } } -WXHBITMAP wxToolBarMSW::CreateDitherBitmap() +WXHBITMAP wxToolBar::CreateDitherBitmap() { BITMAPINFO* pbmi; HBITMAP hbm; @@ -804,7 +961,7 @@ WXHBITMAP wxToolBarMSW::CreateDitherBitmap() return (WXHBITMAP)hbm; } -bool wxToolBarMSW::CreateDitherBrush(void) +bool wxToolBar::CreateDitherBrush() { HBITMAP hbmGray; HBRUSH hbrSave; @@ -834,7 +991,7 @@ bool wxToolBarMSW::CreateDitherBrush(void) return FALSE; } -bool wxToolBarMSW::FreeDitherBrush(void) +bool wxToolBar::FreeDitherBrush(void) { if (m_hbrDither) DeleteObject((HBRUSH) m_hbrDither); @@ -856,11 +1013,11 @@ typedef struct tagCOLORMAP2 #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(000,000,255)) // blue +#define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue #define BGR_BACKGROUND (RGB(255,000,255)) // magenta #define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb))) -WXHBITMAP wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void *info) +WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void *info) { LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)info; HDC hdc, hdcMem = NULL; @@ -940,7 +1097,7 @@ WXHBITMAP wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void return (WXHBITMAP) hbm; } -WXHBITMAP wxToolBarMSW::CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap) +WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap) { HANDLE hDIB = wxBitmapToDIB((HBITMAP) hBitmap, 0); if (hDIB) -- 2.45.2