Implemented PocketPC menubar/toolbar as wxToolMenuBar derived

from wxToolBar, solving the problem of how normal toolbars
can co-exist with combined ones. Tidied up WinCE toolbar code.
Implemented wxToolBar as 'dummy' toolbar under Smartphone.
Dialogs now show an empty menubar to hide inactive one
underneath.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32853 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2005-03-16 17:51:41 +00:00
parent 2ecf902bc8
commit a9102b3671
13 changed files with 263 additions and 512 deletions

View File

@@ -186,14 +186,14 @@ XLife is (c) 1989 by Jon Bennett et al.")),
sizer->Add( new wxStaticLine(this, wxID_ANY), 0, wxGROW | wxLEFT | wxRIGHT, 5 ); sizer->Add( new wxStaticLine(this, wxID_ANY), 0, wxGROW | wxLEFT | wxRIGHT, 5 );
#endif // wxUSE_STATLINE #endif // wxUSE_STATLINE
#ifndef __WXWINCE__ #if ! (defined(__SMARTPHONE__) || defined(__POCKETPC__))
sizer->Add( CreateButtonSizer(wxOK), 0, wxCENTRE | wxALL, 10 ); sizer->Add( CreateButtonSizer(wxOK), 0, wxCENTRE | wxALL, 10 );
#endif #endif
// activate // activate
SetSizer(sizer); SetSizer(sizer);
#ifndef __WXWINCE__ #if ! (defined(__SMARTPHONE__) || defined(__POCKETPC__))
sizer->SetSizeHints(this); sizer->SetSizeHints(this);
sizer->Fit(this); sizer->Fit(this);
Centre(wxBOTH | wxCENTRE_ON_SCREEN); Centre(wxBOTH | wxCENTRE_ON_SCREEN);

View File

@@ -199,7 +199,7 @@ LifeFrame::LifeFrame() :
menuFile->Append(wxID_NEW, wxGetStockLabel(wxID_NEW), _("Start a new game")); menuFile->Append(wxID_NEW, wxGetStockLabel(wxID_NEW), _("Start a new game"));
menuFile->Append(wxID_OPEN, wxGetStockLabel(wxID_OPEN), _("Open an existing Life pattern")); menuFile->Append(wxID_OPEN, wxGetStockLabel(wxID_OPEN), _("Open an existing Life pattern"));
menuFile->Append(ID_SAMPLES, _("&Sample game..."), _("Select a sample configuration")); menuFile->Append(ID_SAMPLES, _("&Sample game..."), _("Select a sample configuration"));
#ifndef __WXWINCE__ #if ! (defined(__SMARTPHONE__) || defined(__POCKETPC__))
menuFile->AppendSeparator(); menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT, true, _T("Alt-X")), _("Quit this program")); menuFile->Append(wxID_EXIT, wxGetStockLabel(wxID_EXIT, true, _T("Alt-X")), _("Quit this program"));

View File

@@ -241,6 +241,11 @@ with \helpref{wxFrame::SetToolBar}{wxframesettoolbar}, the frame will manage the
position and adjust the return value from \helpref{wxWindow::GetClientSize}{wxwindowgetclientsize} to position and adjust the return value from \helpref{wxWindow::GetClientSize}{wxwindowgetclientsize} to
reflect the available space for application windows. reflect the available space for application windows.
Under Pocket PC, you should {\it always} use this function for creating the toolbar
to be managed by the frame, so that wxWidgets can use a combined
menubar and toolbar. Where you manage your own toolbars, create a wxToolBar
as usual.
\wxheading{See also} \wxheading{See also}
\helpref{wxFrame::CreateStatusBar}{wxframecreatestatusbar},\rtfsp \helpref{wxFrame::CreateStatusBar}{wxframecreatestatusbar},\rtfsp

View File

@@ -23,19 +23,18 @@ wxToolBarBase\\
\wxheading{Include files} \wxheading{Include files}
<wx/toolbar.h> (to allow wxWidgets to select an appropriate toolbar class)\\ <wx/toolbar.h> (to allow wxWidgets to select an appropriate toolbar class)\\
<wx/tbarbase.h> (the base class)\\ <wx/tbarbase.h> (the base class)
<wx/tbarmsw.h> (the non-Windows 95 Windows toolbar class)\\
<wx/tbar95.h> (the Windows 95/98 toolbar class)\\
\wxheading{Remarks} \wxheading{Remarks}
You may also create a toolbar that is managed by the frame, by You may also create a toolbar that is managed by the frame, by
calling \helpref{wxFrame::CreateToolBar}{wxframecreatetoolbar}. calling \helpref{wxFrame::CreateToolBar}{wxframecreatetoolbar}. Under Pocket PC,
you should {\it always} use this function for creating the toolbar
to be managed by the frame, so that wxWidgets can use a combined
menubar and toolbar. Where you manage your own toolbars, create a wxToolBar
as usual.
Due to the use of native toolbars on the various platforms, certain adaptions will The meaning of a "separator" is a vertical line under Windows and simple space under GTK+.
often have to be made in order to get optimal look on all platforms as some platforms
ignore the values for explicit placement and use their own layout and the meaning
of a "separator" is a vertical line under Windows95 vs. simple space under GTK etc.
{\bf wxToolBar95:} Note that this toolbar paints tools to reflect system-wide colours. {\bf wxToolBar95:} Note that this toolbar paints tools to reflect system-wide colours.
If you use more than 16 colours in your tool bitmaps, you may wish to suppress If you use more than 16 colours in your tool bitmaps, you may wish to suppress

View File

@@ -136,16 +136,38 @@ provided, to show settings in the correct style on PocketPC and on other platfor
Notifications (bubble HTML text with optional buttons and links) will also be Notifications (bubble HTML text with optional buttons and links) will also be
implemented in the future for PocketPC. implemented in the future for PocketPC.
Modeless dialogs probably don't make sense for PocketPC and Smartphone, since
frames and dialogs are normally full-screen, and a modeless dialog is normally
intended to co-exist with the main application frame.
\subsubsection{Menubars and toolbars in wxWinCE} \subsubsection{Menubars and toolbars in wxWinCE}
Menubars and toolbars can only be implemented using a combined control, \wxheading{Menubars and toolbars in PocketPC}
but you can use the same syntax as before; wxWidgets will combine the menubar
and toolbar.
On PocketPC, a frame must always have a menubar, even if it's empty. On PocketPC, a frame must always have a menubar, even if it's empty.
An empty menubar is automatically provided for dialogs, to hide
any existing menubar for the duration of the dialog.
Menubars and toolbars are implemented using a combined control,
but you can use essentially the usual wxWidgets API; wxWidgets will combine the menubar
and toolbar. However, there are some restrictions:
\itemsep=0pt
\begin{itemize}
\item You must create the frame's primary toolbar with wxFrame::CreateToolBar,
because this uses the special wxToolMenuBar class (derived from wxToolBar)
to implement the combined toolbar and menubar. Otherwise, you can create and manage toolbars
using the wxToolBar class as usual, for example to implement an optional
formatting toolbar above the menubar as Pocket Word does. But don't assign
a wxToolBar to a frame using SetToolBar - you should always use CreateToolBar
for the main frame toolbar.
\item Deleting and adding tools to wxToolMenuBar is not supported.
\end{itemize}
\wxheading{Menubars and toolbars in Smartphone}
On Smartphone, there are only two menu buttons, so a menubar is simulated On Smartphone, there are only two menu buttons, so a menubar is simulated
using a nested menu on the right menu button. Toolbars are simply ignored on using a nested menu on the right menu button. Any toolbars are simply ignored on
Smartphone. Smartphone.
\subsubsection{Closing windows in wxWinCE} \subsubsection{Closing windows in wxWinCE}
@@ -160,9 +182,15 @@ wxID\_EXIT, it will do the right thing.
\subsubsection{Control differences on wxWinCE} \subsubsection{Control differences on wxWinCE}
This section is to be written. These controls are missing from wxWinCE:
Can someone remind us why wxChoice was rewritten for Smartphone? \itemsep=0pt
\begin{itemize}
\item {\bf wxCheckListBox} This can be implemented using a wxListCtrl in report mode
with checked/unchecked images.
\end{itemize}
This section is currently incomplete.
\subsubsection{Online help in wxWinCE} \subsubsection{Online help in wxWinCE}
@@ -197,6 +225,9 @@ Win32.
the correct size on the emulator, but too small on a VGA Pocket Loox device. the correct size on the emulator, but too small on a VGA Pocket Loox device.
\item {\bf wxStaticLine.} Lines don't show up, and the documentation suggests that \item {\bf wxStaticLine.} Lines don't show up, and the documentation suggests that
missing styles are implemented with WM\_PAINT. missing styles are implemented with WM\_PAINT.
\item {\bf wxCheckListBox.} This class needs to be implemented in terms of a wxListCtrl
in report mode, using icons for checkbox states. This is necessary because owner-draw listboxes
are not supported on Windows CE.
\item {\bf OK button.} We should allow the OK button on a dialog to be optional, perhaps \item {\bf OK button.} We should allow the OK button on a dialog to be optional, perhaps
by using wxCLOSE\_BOX to indicate when the OK button should be displayed. by using wxCLOSE\_BOX to indicate when the OK button should be displayed.
\item {\bf Dynamic adaptation.} We should probably be using run-time tests more \item {\bf Dynamic adaptation.} We should probably be using run-time tests more

View File

@@ -165,6 +165,11 @@ protected:
void ReloadAllButtons(); void ReloadAllButtons();
#endif // __SMARTPHONE__ && __WXWINCE__ #endif // __SMARTPHONE__ && __WXWINCE__
// Empty menubar for dialogs
#ifdef __POCKETPC__
WXHWND m_menuBarHWND;
#endif
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW) DECLARE_NO_COPY_CLASS(wxTopLevelWindowMSW)
}; };

View File

@@ -20,13 +20,74 @@
#include "wx/dynarray.h" #include "wx/dynarray.h"
// Smartphones don't have toolbars, so use a dummy class
#ifdef __SMARTPHONE__
class WXDLLEXPORT wxToolBar : public wxToolBarBase class WXDLLEXPORT wxToolBar : public wxToolBarBase
{ {
public: public:
// ctors and dtor // ctors and dtor
wxToolBar() { Init(); } wxToolBar() { }
wxToolBar(wxWindow *parent, wxToolBar(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);
}
bool Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxNO_BORDER | wxTB_HORIZONTAL,
const wxString& name = wxToolBarNameStr);
// override/implement base class virtuals
virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const;
virtual bool Realize() { return true; }
protected:
// 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 wxString& label,
const wxBitmap& bmpNormal,
const wxBitmap& bmpDisabled,
wxItemKind kind,
wxObject *clientData,
const wxString& shortHelp,
const wxString& longHelp);
virtual wxToolBarToolBase *CreateTool(wxControl *control);
private:
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxToolBar)
DECLARE_NO_COPY_CLASS(wxToolBar)
};
#else
// For __POCKETPC__
#include "wx/msw/tbar95.h"
class WXDLLEXPORT wxToolMenuBar : public wxToolBar
{
public:
// ctors and dtor
wxToolMenuBar() { Init(); }
wxToolMenuBar(wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
@@ -47,32 +108,15 @@ public:
const wxString& name = wxToolBarNameStr, const wxString& name = wxToolBarNameStr,
wxMenuBar* menuBar = NULL); wxMenuBar* menuBar = NULL);
virtual ~wxToolBar(); virtual ~wxToolMenuBar();
// override/implement base class virtuals // override/implement base class virtuals
virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, wxCoord y) const;
virtual bool Realize(); virtual bool Realize();
virtual void SetToolBitmapSize(const wxSize& size);
virtual wxSize GetToolSize() const;
virtual void SetRows(int nRows);
// implementation only from now on // implementation only from now on
// ------------------------------- // -------------------------------
virtual void SetWindowStyleFlag(long style);
virtual bool MSWCommand(WXUINT param, WXWORD id); virtual bool MSWCommand(WXUINT param, WXWORD id);
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
void OnMouseEvent(wxMouseEvent& event);
void OnSysColourChanged(wxSysColourChangedEvent& event);
void SetFocus() {}
static WXHBITMAP MapBitmap(WXHBITMAP bitmap, int width, int height);
// Return HMENU for the menu associated with the commandbar // Return HMENU for the menu associated with the commandbar
WXHMENU GetHMenu(); WXHMENU GetHMenu();
@@ -97,10 +141,6 @@ protected:
virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool);
virtual bool DoDeleteTool(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, virtual wxToolBarToolBase *CreateTool(int id,
const wxString& label, const wxString& label,
const wxBitmap& bmpNormal, const wxBitmap& bmpNormal,
@@ -111,34 +151,18 @@ protected:
const wxString& longHelp); const wxString& longHelp);
virtual wxToolBarToolBase *CreateTool(wxControl *control); virtual wxToolBarToolBase *CreateTool(wxControl *control);
// override WndProc mainly to process WM_SIZE
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
// return the appropriate size and flags for the toolbar control
virtual wxSize DoGetBestSize() const;
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
// handlers for various events
void HandleMouseMove(WXWPARAM wParam, WXLPARAM lParam);
// should be called whenever the toolbar size changes
void UpdateSize();
// the total number of toolbar elements
size_t m_nButtons;
// the tool the cursor is in
wxToolBarToolBase *m_pInTool;
// The menubar associated with this toolbar // The menubar associated with this toolbar
wxMenuBar* m_menuBar; wxMenuBar* m_menuBar;
private: private:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxToolBar) DECLARE_DYNAMIC_CLASS(wxToolMenuBar)
DECLARE_NO_COPY_CLASS(wxToolBar) DECLARE_NO_COPY_CLASS(wxToolMenuBar)
}; };
#endif
// __SMARTPHONE__
#endif // wxUSE_TOOLBAR #endif // wxUSE_TOOLBAR
#endif #endif

View File

@@ -489,9 +489,15 @@ wxToolBar* wxFrameBase::OnCreateToolBar(long style,
wxWindowID id, wxWindowID id,
const wxString& name) const wxString& name)
{ {
#if defined(__WXWINCE__) && defined(__POCKETPC__)
return new wxToolMenuBar(this, id,
wxDefaultPosition, wxDefaultSize,
style, name);
#else
return new wxToolBar(this, id, return new wxToolBar(this, id,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
style, name); style, name);
#endif
} }
void wxFrameBase::SetToolBar(wxToolBar *toolbar) void wxFrameBase::SetToolBar(wxToolBar *toolbar)

View File

@@ -357,7 +357,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar)
#elif defined(WINCE_WITHOUT_COMMANDBAR) #elif defined(WINCE_WITHOUT_COMMANDBAR)
if (!GetToolBar()) if (!GetToolBar())
{ {
wxToolBar* toolBar = new wxToolBar(this, wxID_ANY, wxToolMenuBar* toolBar = new wxToolMenuBar(this, wxID_ANY,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
wxBORDER_NONE | wxTB_HORIZONTAL, wxBORDER_NONE | wxTB_HORIZONTAL,
wxToolBarNameStr, menubar); wxToolBarNameStr, menubar);

View File

@@ -716,9 +716,13 @@ wxMenuBar::~wxMenuBar()
{ {
// In Windows CE (not .NET), the menubar is always associated // In Windows CE (not .NET), the menubar is always associated
// with a toolbar, which destroys the menu implicitly. // with a toolbar, which destroys the menu implicitly.
#if defined(WINCE_WITHOUT_COMMANDBAR) #if defined(WINCE_WITHOUT_COMMANDBAR) && defined(__POCKETPC__)
if (GetToolBar()) if (GetToolBar())
GetToolBar()->SetMenuBar(NULL); {
wxToolMenuBar* toolMenuBar = wxDynamicCast(GetToolBar(), wxToolMenuBar);
if (toolMenuBar)
toolMenuBar->SetMenuBar(NULL);
}
#else #else
// we should free Windows resources only if Windows doesn't do it for us // we should free Windows resources only if Windows doesn't do it for us
// which happens if we're attached to a frame // which happens if we're attached to a frame

View File

@@ -39,7 +39,7 @@
#include "wx/control.h" #include "wx/control.h"
#endif #endif
#if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE && (!defined(_WIN32_WCE) || (_WIN32_WCE >= 400 && !defined(__POCKETPC__) && !defined(__SMARTPHONE__))) #if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE && !defined(__SMARTPHONE__)
#include "wx/toolbar.h" #include "wx/toolbar.h"
#include "wx/sysopt.h" #include "wx/sysopt.h"

View File

@@ -148,6 +148,10 @@ void wxTopLevelWindowMSW::Init()
#if defined(__SMARTPHONE__) && defined(__WXWINCE__) #if defined(__SMARTPHONE__) && defined(__WXWINCE__)
m_MenuBarHWND = 0; m_MenuBarHWND = 0;
#endif #endif
#ifdef __POCKETPC__
// A dummy menubar for dialogs
m_menuBarHWND = 0;
#endif
} }
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
@@ -415,6 +419,27 @@ bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
::SetWindowText(GetHwnd(), title); ::SetWindowText(GetHwnd(), title);
} }
#ifdef __POCKETPC__
// Create an empty menubar so that we don't see the menubar underneath
SHMENUBARINFO mbi;
memset (&mbi, 0, sizeof (SHMENUBARINFO));
mbi.cbSize = sizeof (SHMENUBARINFO);
mbi.hwndParent = (HWND) GetParent()->GetHWND();
mbi.nToolBarId = 5000;
mbi.nBmpId = 0;
mbi.cBmpImages = 0;
mbi.dwFlags = 0 ; // SHCMBF_EMPTYBAR;
mbi.hInstRes = wxGetInstance();
if (!SHCreateMenuBar(&mbi))
{
wxFAIL_MSG( _T("SHCreateMenuBar failed") );
}
m_menuBarHWND = (WXHWND) mbi.hwndMB;
#endif
SubclassWin(m_hWnd); SubclassWin(m_hWnd);
#ifdef __SMARTPHONE__ #ifdef __SMARTPHONE__
@@ -563,6 +588,15 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
wxTopLevelWindowMSW::~wxTopLevelWindowMSW() wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
{ {
#ifdef __POCKETPC__
// Destroy the dummy menubar for dialogs
if (m_menuBarHWND)
{
::DestroyWindow((HWND) m_menuBarHWND);
m_menuBarHWND = 0;
}
#endif
// after destroying an owned window, Windows activates the next top level // after destroying an owned window, Windows activates the next top level
// window in Z order but it may be different from our owner (to reproduce // window in Z order but it may be different from our owner (to reproduce
// this simply Alt-TAB to another application and back before closing the // this simply Alt-TAB to another application and back before closing the

View File

@@ -63,73 +63,28 @@
#include "wx/msw/winundef.h" #include "wx/msw/winundef.h"
#if defined(__MWERKS__) && defined(__WXMSW__) #if !defined(__SMARTPHONE__)
// including <windef.h> for max definition doesn't seem
// to work using CodeWarrior 6 Windows. So we define it
// here. (Otherwise we get a undefined identifier 'max'
// later on in this file.) (Added by dimitri@shortcut.nl)
# ifndef max
# define max(a,b) (((a) > (b)) ? (a) : (b))
# endif
#endif ///////////// This implementation is for PocketPC.
///////////// See later for the Smartphone dummy toolbar class.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// constants // Event table
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// these standard constants are not always defined in compilers headers IMPLEMENT_DYNAMIC_CLASS(wxToolMenuBar, wxToolBar)
// Styles BEGIN_EVENT_TABLE(wxToolMenuBar, wxToolBar)
#ifndef TBSTYLE_FLAT
#define TBSTYLE_LIST 0x1000
#define TBSTYLE_FLAT 0x0800
#endif
#ifndef TBSTYLE_TRANSPARENT
#define TBSTYLE_TRANSPARENT 0x8000
#endif
#ifndef TBSTYLE_TOOLTIPS
#define TBSTYLE_TOOLTIPS 0x0100
#endif
// Messages
#ifndef TB_GETSTYLE
#define TB_SETSTYLE (WM_USER + 56)
#define TB_GETSTYLE (WM_USER + 57)
#endif
#ifndef TB_HITTEST
#define TB_HITTEST (WM_USER + 69)
#endif
// these values correspond to those used by comctl32.dll
#define DEFAULTBITMAPX 16
#define DEFAULTBITMAPY 15
#define DEFAULTBUTTONX 24
#define DEFAULTBUTTONY 24
#define DEFAULTBARHEIGHT 27
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent)
EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged)
END_EVENT_TABLE() END_EVENT_TABLE()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// private classes // private classes
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class wxToolBarTool : public wxToolBarToolBase class wxToolMenuBarTool : public wxToolBarToolBase
{ {
public: public:
wxToolBarTool(wxToolBar *tbar, wxToolMenuBarTool(wxToolBar *tbar,
int id, int id,
const wxString& label, const wxString& label,
const wxBitmap& bmpNormal, const wxBitmap& bmpNormal,
@@ -145,7 +100,7 @@ public:
m_bitmapIndex = -1; m_bitmapIndex = -1;
} }
wxToolBarTool(wxToolBar *tbar, wxControl *control) wxToolMenuBarTool(wxToolBar *tbar, wxControl *control)
: wxToolBarToolBase(tbar, control) : wxToolBarToolBase(tbar, control)
{ {
m_nSepCount = 1; m_nSepCount = 1;
@@ -187,7 +142,7 @@ private:
// wxToolBarTool // wxToolBarTool
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxToolBarToolBase *wxToolBar::CreateTool(int id, wxToolBarToolBase *wxToolMenuBar::CreateTool(int id,
const wxString& label, const wxString& label,
const wxBitmap& bmpNormal, const wxBitmap& bmpNormal,
const wxBitmap& bmpDisabled, const wxBitmap& bmpDisabled,
@@ -196,31 +151,28 @@ wxToolBarToolBase *wxToolBar::CreateTool(int id,
const wxString& shortHelp, const wxString& shortHelp,
const wxString& longHelp) const wxString& longHelp)
{ {
return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind, return new wxToolMenuBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
clientData, shortHelp, longHelp); clientData, shortHelp, longHelp);
} }
wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control) wxToolBarToolBase *wxToolMenuBar::CreateTool(wxControl *control)
{ {
return new wxToolBarTool(this, control); return new wxToolMenuBarTool(this, control);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxToolBar construction // wxToolBar construction
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxToolBar::Init() void wxToolMenuBar::Init()
{ {
wxToolBar::Init();
m_nButtons = 0; m_nButtons = 0;
m_defaultWidth = DEFAULTBITMAPX;
m_defaultHeight = DEFAULTBITMAPY;
m_pInTool = 0;
m_menuBar = NULL; m_menuBar = NULL;
} }
bool wxToolBar::Create(wxWindow *parent, bool wxToolMenuBar::Create(wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxPoint& pos, const wxPoint& pos,
const wxSize& size, const wxSize& size,
@@ -243,20 +195,12 @@ bool wxToolBar::Create(wxWindow *parent,
return true; return true;
} }
#ifndef TBSTYLE_NO_DROPDOWN_ARROW bool wxToolMenuBar::MSWCreateToolbar(const wxPoint& WXUNUSED(pos), const wxSize& WXUNUSED(size), wxMenuBar* menuBar)
#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080
#endif
bool wxToolBar::MSWCreateToolbar(const wxPoint& WXUNUSED(pos), const wxSize& WXUNUSED(size), wxMenuBar* menuBar)
{ {
SetMenuBar(menuBar); SetMenuBar(menuBar);
if (m_menuBar) if (m_menuBar)
m_menuBar->SetToolBar(this); m_menuBar->SetToolBar(this);
// Smartphone doesn't show a toolbar, it uses menu buttons.
#if !defined(__SMARTPHONE__)
#if defined(WINCE_WITHOUT_COMMANDBAR) #if defined(WINCE_WITHOUT_COMMANDBAR)
// Create the menubar. // Create the menubar.
SHMENUBARINFO mbi; SHMENUBARINFO mbi;
@@ -291,83 +235,25 @@ bool wxToolBar::MSWCreateToolbar(const wxPoint& WXUNUSED(pos), const wxSize& WXU
if (menuBar) if (menuBar)
menuBar->Create(); menuBar->Create();
#endif
// __SMARTPHONE__
return true; return true;
} }
void wxToolBar::Recreate() void wxToolMenuBar::Recreate()
{ {
#if 0 // TODO
const HWND hwndOld = GetHwnd();
if ( !hwndOld )
{
// we haven't been created yet, no need to recreate
return;
} }
// get the position and size before unsubclassing the old toolbar wxToolMenuBar::~wxToolMenuBar()
const wxPoint pos = GetPosition();
const wxSize size = GetSize();
UnsubclassWin();
if ( !MSWCreateToolbar(pos, size) )
{
// what can we do?
wxFAIL_MSG( _T("recreating the toolbar failed") );
return;
}
// reparent all our children under the new toolbar
for ( wxWindowList::compatibility_iterator node = m_children.GetFirst();
node;
node = node->GetNext() )
{
wxWindow *win = node->GetData();
if ( !win->IsTopLevel() )
::SetParent(GetHwndOf(win), GetHwnd());
}
// only destroy the old toolbar now -- after all the children had been
// reparented
::DestroyWindow(hwndOld);
Realize();
UpdateSize();
#endif
}
wxToolBar::~wxToolBar()
{ {
if (GetMenuBar()) if (GetMenuBar())
GetMenuBar()->SetToolBar(NULL); GetMenuBar()->SetToolBar(NULL);
// we must refresh the frame size when the toolbar is deleted but the frame
// is not - otherwise toolbar leaves a hole in the place it used to occupy
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
if ( frame && !frame->IsBeingDeleted() )
{
frame->SendSizeEvent();
}
}
wxSize wxToolBar::DoGetBestSize() const
{
wxSize sizeBest = GetToolSize();
sizeBest.x *= GetToolsCount();
// reverse horz and vertical components if necessary
return HasFlag(wxTB_VERTICAL) ? wxSize(sizeBest.y, sizeBest.x) : sizeBest;
} }
// Return HMENU for the menu associated with the commandbar // Return HMENU for the menu associated with the commandbar
WXHMENU wxToolBar::GetHMenu() WXHMENU wxToolMenuBar::GetHMenu()
{ {
#if defined(__HANDHELDPC__) #if defined(__HANDHELDPC__)
// TODO ???
return 0; return 0;
#else #else
if (GetHWND()) if (GetHWND())
@@ -379,57 +265,11 @@ WXHMENU wxToolBar::GetHMenu()
#endif #endif
} }
WXDWORD wxToolBar::MSWGetStyle(long style, WXDWORD *exstyle) const
{
// toolbars never have border, giving one to them results in broken
// appearance
WXDWORD msStyle = wxControl::MSWGetStyle
(
(style & ~wxBORDER_MASK) | wxBORDER_NONE, exstyle
);
// always include this one, it never hurts and setting it later only if we
// do have tooltips wouldn't work
msStyle |= TBSTYLE_TOOLTIPS;
if ( style & (wxTB_FLAT | wxTB_HORZ_LAYOUT) )
{
// static as it doesn't change during the program lifetime
static int s_verComCtl = wxTheApp->GetComCtl32Version();
// comctl32.dll 4.00 doesn't support the flat toolbars and using this
// style with 6.00 (part of Windows XP) leads to the toolbar with
// incorrect background colour - and not using it still results in the
// correct (flat) toolbar, so don't use it there
if ( s_verComCtl > 400 && s_verComCtl < 600 )
{
msStyle |= TBSTYLE_FLAT | TBSTYLE_TRANSPARENT;
}
if ( s_verComCtl >= 470 && style & wxTB_HORZ_LAYOUT )
{
msStyle |= TBSTYLE_LIST;
}
}
if ( style & wxTB_NODIVIDER )
msStyle |= CCS_NODIVIDER;
if ( style & wxTB_NOALIGN )
msStyle |= CCS_NOPARENTALIGN;
if ( style & wxTB_VERTICAL )
msStyle |= CCS_VERT;
return msStyle;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// adding/removing tools // adding/removing tools
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) bool wxToolMenuBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
{ {
// nothing special to do here - we really create the toolbar buttons in // nothing special to do here - we really create the toolbar buttons in
// Realize() later // Realize() later
@@ -438,7 +278,7 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
return true; return true;
} }
bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool) bool wxToolMenuBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
{ {
// the main difficulty we have here is with the controls in the toolbars: // the main difficulty we have here is with the controls in the toolbars:
// as we (sometimes) use several separators to cover up the space used by // as we (sometimes) use several separators to cover up the space used by
@@ -461,7 +301,7 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
if ( tool2->IsControl() ) if ( tool2->IsControl() )
{ {
pos += ((wxToolBarTool *)tool2)->GetSeparatorsCount() - 1; pos += ((wxToolMenuBarTool *)tool2)->GetSeparatorsCount() - 1;
} }
} }
@@ -479,7 +319,7 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
if ( tool->IsControl() ) if ( tool->IsControl() )
{ {
nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount(); nButtonsToDelete = ((wxToolMenuBarTool *)tool)->GetSeparatorsCount();
width *= nButtonsToDelete; width *= nButtonsToDelete;
} }
@@ -515,11 +355,8 @@ bool wxToolBar::DoDeleteTool(size_t pos, wxToolBarToolBase *tool)
return true; return true;
} }
bool wxToolBar::Realize() bool wxToolMenuBar::Realize()
{ {
#if defined(__SMARTPHONE__)
return true;
#else
const size_t nTools = GetToolsCount(); const size_t nTools = GetToolsCount();
if ( nTools == 0 ) if ( nTools == 0 )
{ {
@@ -542,7 +379,7 @@ bool wxToolBar::Realize()
wxToolBarToolsList::Node* node; wxToolBarToolsList::Node* node;
for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
{ {
wxToolBarTool *tool = (wxToolBarTool*) node->GetData(); wxToolMenuBarTool *tool = (wxToolMenuBarTool*) node->GetData();
TBBUTTON buttons[1] ; TBBUTTON buttons[1] ;
@@ -648,15 +485,9 @@ bool wxToolBar::Realize()
} }
return true; return true;
#endif
// __SMARTPHONE__
} }
// ---------------------------------------------------------------------------- bool wxToolMenuBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id)
// message handlers
// ----------------------------------------------------------------------------
bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id)
{ {
wxToolBarToolBase *tool = FindById((int)id); wxToolBarToolBase *tool = FindById((int)id);
if ( !tool ) if ( !tool )
@@ -696,285 +527,97 @@ bool wxToolBar::MSWCommand(WXUINT WXUNUSED(cmd), WXWORD id)
return true; return true;
} }
bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl),
WXLPARAM lParam,
WXLPARAM *WXUNUSED(result))
{
#if wxUSE_TOOLTIPS
// First check if this applies to us
NMHDR *hdr = (NMHDR *)lParam;
// the tooltips control created by the toolbar is sometimes Unicode, even
// in an ANSI application - this seems to be a bug in comctl32.dll v5
UINT code = hdr->code;
if ( (code != (UINT) TTN_NEEDTEXTA) && (code != (UINT) TTN_NEEDTEXTW) )
return false;
HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
if ( toolTipWnd != hdr->hwndFrom )
return false;
LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
int id = (int)ttText->hdr.idFrom;
wxToolBarToolBase *tool = FindById(id);
if ( !tool )
return false;
return HandleTooltipNotify(code, lParam, tool->GetShortHelp());
#else #else
wxUnusedVar(lParam);
return false; ////////////// For Smartphone
#endif
// ----------------------------------------------------------------------------
// Event table
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxToolBarBase)
BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
END_EVENT_TABLE()
wxToolBarToolBase *wxToolBar::CreateTool(int id,
const wxString& label,
const wxBitmap& bmpNormal,
const wxBitmap& bmpDisabled,
wxItemKind kind,
wxObject *clientData,
const wxString& shortHelp,
const wxString& longHelp)
{
return new wxToolBarToolBase(this, id, label, bmpNormal, bmpDisabled, kind,
clientData, shortHelp, longHelp);
}
wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
{
return new wxToolBarToolBase(this, control);
}
bool wxToolBar::Create(wxWindow *parent,
wxWindowID WXUNUSED(id),
const wxPoint& WXUNUSED(pos),
const wxSize& WXUNUSED(size),
long style,
const wxString& name)
{
// TODO: we may need to make this a dummy hidden window to
// satisfy other parts of wxWidgets.
parent->AddChild(this);
SetWindowStyle(style);
SetName(name);
return true;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// toolbar geometry // adding/removing tools
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxToolBar::SetToolBitmapSize(const wxSize& size) bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
{ {
wxToolBarBase::SetToolBitmapSize(size); tool->Attach(this);
return true;
::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y));
} }
void wxToolBar::SetRows(int nRows) bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
{ {
if ( nRows == m_maxRows ) tool->Detach();
{ return true;
// avoid resizing the frame uselessly
return;
} }
// TRUE in wParam means to create at least as many rows, FALSE - wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const
// at most as many
RECT rect;
::SendMessage(GetHwnd(), TB_SETROWS,
MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)),
(LPARAM) &rect);
m_maxRows = nRows;
UpdateSize();
}
// The button size is bigger than the bitmap size
wxSize wxToolBar::GetToolSize() const
{ {
// TB_GETBUTTONSIZE is supported from version 4.70 return NULL;
#if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 ) \
&& !( defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 1, 0 ) )
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);
}
}
static
wxToolBarToolBase *GetItemSkippingDummySpacers(const wxToolBarToolsList& tools,
size_t index )
{
wxToolBarToolsList::compatibility_iterator current = tools.GetFirst();
for ( ; current != 0; current = current->GetNext() )
{
if ( index == 0 )
return current->GetData();
wxToolBarTool *tool = (wxToolBarTool *)current->GetData();
size_t separators = tool->GetSeparatorsCount();
// if it is a normal button, sepcount == 0, so skip 1 item (the button)
// otherwise, skip as many items as the separator count, plus the
// control itself
index -= separators ? separators + 1 : 1;
}
return 0;
}
wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
{
POINT pt;
pt.x = x;
pt.y = y;
int index = (int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt);
// MBN: when the point ( x, y ) is close to the toolbar border
// TB_HITTEST returns m_nButtons ( not -1 )
if ( index < 0 || (size_t)index >= m_nButtons )
{
// it's a separator or there is no tool at all there
return (wxToolBarToolBase *)NULL;
}
// if comctl32 version < 4.71 wxToolBar95 adds dummy spacers
#if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
if ( wxTheApp->GetComCtl32Version() >= 471 )
{
return m_tools.Item((size_t)index)->GetData();
}
else
#endif
{
return GetItemSkippingDummySpacers( m_tools, (size_t) index );
}
}
void wxToolBar::UpdateSize()
{
// the toolbar size changed
::SendMessage(GetHwnd(), TB_AUTOSIZE, 0, 0);
// we must also refresh the frame after the toolbar size (possibly) changed
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
if ( frame )
{
frame->SendSizeEvent();
}
}
// ----------------------------------------------------------------------------
// toolbar styles
// ---------------------------------------------------------------------------
void wxToolBar::SetWindowStyleFlag(long style)
{
// the style bits whose changes force us to recreate the toolbar
static const long MASK_NEEDS_RECREATE = wxTB_TEXT | wxTB_NOICONS;
const long styleOld = GetWindowStyle();
wxToolBarBase::SetWindowStyleFlag(style);
// don't recreate an empty toolbar: not only this is unnecessary, but it is
// also fatal as we'd then try to recreate the toolbar when it's just being
// created
if ( GetToolsCount() &&
(style & MASK_NEEDS_RECREATE) != (styleOld & MASK_NEEDS_RECREATE) )
{
// to remove the text labels, simply re-realizing the toolbar is enough
// but I don't know of any way to add the text to an existing toolbar
// other than by recreating it entirely
Recreate();
}
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// tool state // tool state
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable) void wxToolBar::DoEnableTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(enable))
{ {
::SendMessage(GetHwnd(), TB_ENABLEBUTTON,
(WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0));
} }
void wxToolBar::DoToggleTool(wxToolBarToolBase *tool, bool toggle) void wxToolBar::DoToggleTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
{ {
::SendMessage(GetHwnd(), TB_CHECKBUTTON,
(WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0));
} }
void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle)) void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
{ {
// 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") ); wxFAIL_MSG( _T("not implemented") );
} }
// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------
// Responds to colour changes, and passes event on to children.
void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event)
{
wxRGBToColour(m_backgroundColour, ::GetSysColor(COLOR_BTNFACE));
// Remap the buttons
Realize();
// Relayout the toolbar
int nrows = m_maxRows;
m_maxRows = 0; // otherwise SetRows() wouldn't do anything
SetRows(nrows);
Refresh();
// let the event propagate further
event.Skip();
}
void wxToolBar::OnMouseEvent(wxMouseEvent& event)
{
if (event.Leaving() && m_pInTool)
{
OnMouseEnter( -1 );
event.Skip();
return;
}
if (event.RightDown())
{
// For now, we don't have an id. Later we could
// try finding the tool.
OnRightClick((int)-1, event.GetX(), event.GetY());
}
else
{
event.Skip();
}
}
void wxToolBar::HandleMouseMove(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam)
{
wxCoord x = GET_X_LPARAM(lParam),
y = GET_Y_LPARAM(lParam);
wxToolBarToolBase* tool = FindToolForPosition( x, y );
// cursor left current tool
if( tool != m_pInTool && !tool )
{
m_pInTool = 0;
OnMouseEnter( -1 );
}
// cursor entered a tool
if( tool != m_pInTool && tool )
{
m_pInTool = tool;
OnMouseEnter( tool->GetId() );
}
}
WXLRESULT wxToolBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
#if 0
switch ( nMsg )
{
case WM_SIZE:
if ( HandleSize(wParam, lParam) )
return 0;
break;
case WM_MOUSEMOVE:
// we don't handle mouse moves, so always pass the message to
// wxControl::MSWWindowProc
HandleMouseMove(wParam, lParam);
break;
}
#endif #endif
return wxControl::MSWWindowProc(nMsg, wParam, lParam); // !__SMARTPHONE__
}
#endif // wxUSE_TOOLBAR && Win95 #endif // wxUSE_TOOLBAR && Win95