From 3c55b3652b16f892e9064460bbeea94769f3d27c Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Mon, 30 Jan 2006 15:35:04 +0000 Subject: [PATCH] Added wxToolbook class git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37214 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/classes.tex | 1 + docs/latex/wx/tbook.tex | 7 +- docs/latex/wx/toolbook.tex | 48 +++++ include/wx/toolbook.h | 147 ++++++++++++++ src/generic/toolbkg.cpp | 405 +++++++++++++++++++++++++++++++++++++ 5 files changed, 606 insertions(+), 2 deletions(-) create mode 100644 docs/latex/wx/toolbook.tex create mode 100644 include/wx/toolbook.h create mode 100644 src/generic/toolbkg.cpp diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex index ffbe9e6dcc..158edda4be 100644 --- a/docs/latex/wx/classes.tex +++ b/docs/latex/wx/classes.tex @@ -346,6 +346,7 @@ \input tipwin.tex \input tglbtn.tex \input toolbar.tex +\input toolbook.tex \input tooltip.tex \input tlw.tex \input treebook.tex diff --git a/docs/latex/wx/tbook.tex b/docs/latex/wx/tbook.tex index 4e25b09c47..1b10d024cd 100644 --- a/docs/latex/wx/tbook.tex +++ b/docs/latex/wx/tbook.tex @@ -11,17 +11,20 @@ \section{wxBookCtrl overview}\label{wxbookctrloverview} -Classes: \helpref{wxNotebook}{wxnotebook}, \helpref{wxListbook}{wxlistbook}, \helpref{wxChoicebook}{wxchoicebook} +Classes: \helpref{wxNotebook}{wxnotebook}, \helpref{wxListbook}{wxlistbook}, \helpref{wxChoicebook}{wxchoicebook}, +\helpref{wxTreebook}{wxtreebook}, \helpref{wxToolbook}{wxtoolbook} \subsection{Introduction}\label{wxbookctrlintro} A book control is a convenient way of displaying multiple pages of information, -displayed one page at a time. wxWidgets has three variants of this control: +displayed one page at a time. wxWidgets has five variants of this control: \begin{itemize}\itemsep=0pt \item \helpref{wxNotebook}{wxnotebook}: uses a row of tabs \item \helpref{wxListbook}{wxlistbook}: controlled by a \helpref{wxListCtrl}{wxlistctrl} \item \helpref{wxChoicebook}{wxchoicebook}: controlled by a \helpref{wxChoice}{wxchoice} +\item \helpref{wxTreebook}{wxtreebook}: controlled by a \helpref{wxTreeCtrl}{wxtreectrl} +\item \helpref{wxToolbook}{wxtoolbook}: controlled by a \helpref{wxToolBar}{wxtoolbar} \end{itemize} \subsection{Best book}\label{wxbestbookctrl} diff --git a/docs/latex/wx/toolbook.tex b/docs/latex/wx/toolbook.tex new file mode 100644 index 0000000000..4621496d18 --- /dev/null +++ b/docs/latex/wx/toolbook.tex @@ -0,0 +1,48 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: toolbook.tex +%% Purpose: wxToolbook documentation +%% Author: Julian Smart +%% Modified by: +%% Created: 2006-01-30 +%% RCS-ID: $Id$ +%% Copyright: (c) 2006 Julian Smart +%% License: wxWindows license +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxToolbook}}\label{wxtoolbook} + +wxToolbook is a class similar to \helpref{wxNotebook}{wxnotebook} but which +uses a \helpref{wxToolBar}{wxtoolbar} to show the labels instead of the +tabs. + +There is no documentation for this class yet but its usage is +identical to wxNotebook (except for the features clearly related to tabs +only), so please refer to that class documentation for now. You can also +use the \helpref{notebook sample}{samplenotebook} to see wxToolbook in action. + +\wxheading{Derived from} + +wxBookCtrlBase\\ +\helpref{wxControl}{wxcontrol}\\ +\helpref{wxControl}{wxcontrol}\\ +\helpref{wxWindow}{wxwindow}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\wxheading{Include files} + + + +\wxheading{Window styles} + +\twocolwidtha{5cm} +\begin{twocollist}\itemsep=0pt + +\twocolitem{\windowstyle{wxLB\_DEFAULT}}{Choose the default location for the +labels depending on the current platform (currently always the top).} +\end{twocollist} + +\wxheading{See also} + +\helpref{wxBookCtrl}{wxbookctrloverview}, \helpref{wxNotebook}{wxnotebook}, \helpref{notebook sample}{samplenotebook} + diff --git a/include/wx/toolbook.h b/include/wx/toolbook.h new file mode 100644 index 0000000000..f5b6fc8f1e --- /dev/null +++ b/include/wx/toolbook.h @@ -0,0 +1,147 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/toolbook.h +// Purpose: wxToolbook: wxToolBar and wxNotebook combination +// Author: Julian Smart +// Modified by: +// Created: 2006-01-29 +// RCS-ID: $Id$ +// Copyright: (c) 2006 Julian Smart +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_TOOLBOOK_H_ +#define _WX_TOOLBOOK_H_ + +#include "wx/defs.h" + +#if wxUSE_TOOLBOOK + +#include "wx/bookctrl.h" + +class WXDLLEXPORT wxToolBarBase; +class WXDLLEXPORT wxCommandEvent; + +// ---------------------------------------------------------------------------- +// wxToolbook +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxToolbook : public wxBookCtrlBase +{ +public: + wxToolbook() + { + Init(); + } + + wxToolbook(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxEmptyString) + { + Init(); + + (void)Create(parent, id, pos, size, style, name); + } + + // quasi ctor + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxEmptyString); + + + virtual int GetSelection() const; + virtual bool SetPageText(size_t n, const wxString& strText); + virtual wxString GetPageText(size_t n) const; + virtual int GetPageImage(size_t n) const; + virtual bool SetPageImage(size_t n, int imageId); + virtual wxSize CalcSizeFromPage(const wxSize& sizePage) const; + virtual bool InsertPage(size_t n, + wxWindow *page, + const wxString& text, + bool bSelect = false, + int imageId = -1); + virtual int SetSelection(size_t n); + virtual void SetImageList(wxImageList *imageList); + + virtual bool DeleteAllPages(); + + wxToolBarBase* GetToolBar() const { return (wxToolBarBase*)m_bookctrl; } + + // Not part of the wxBookctrl API, but must be called in OnIdle or + // by application to realize the toolbar and select the initial page. + void Realize(); + +protected: + virtual wxWindow *DoRemovePage(size_t page); + + // get the size which the list control should have + virtual wxSize GetControllerSize() const; + + // event handlers + void OnToolSelected(wxCommandEvent& event); + void OnSize(wxSizeEvent& event); + void OnIdle(wxIdleEvent& event); + + // the currently selected page or wxNOT_FOUND if none + int m_selection; + + // whether the toolbar needs to be realized + bool m_needsRealizing; + + // maximum bitmap size + wxSize m_maxBitmapSize; + +private: + // common part of all constructors + void Init(); + + DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS_NO_COPY(wxToolbook) +}; + +// ---------------------------------------------------------------------------- +// listbook event class and related stuff +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxToolbookEvent : public wxBookCtrlBaseEvent +{ +public: + wxToolbookEvent(wxEventType commandType = wxEVT_NULL, int id = 0, + int nSel = wxNOT_FOUND, int nOldSel = wxNOT_FOUND) + : wxBookCtrlBaseEvent(commandType, id, nSel, nOldSel) + { + } + + wxToolbookEvent(const wxToolbookEvent& event) + : wxBookCtrlBaseEvent(event) + { + } + + virtual wxEvent *Clone() const { return new wxToolbookEvent(*this); } + +private: + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxToolbookEvent) +}; + +extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED; +extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING; + +typedef void (wxEvtHandler::*wxToolbookEventFunction)(wxToolbookEvent&); + +#define wxToolbookEventHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxToolbookEventFunction, &func) + +#define EVT_TOOLBOOK_PAGE_CHANGED(winid, fn) \ + wx__DECLARE_EVT1(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED, winid, wxToolbookEventHandler(fn)) + +#define EVT_TOOLBOOK_PAGE_CHANGING(winid, fn) \ + wx__DECLARE_EVT1(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING, winid, wxToolbookEventHandler(fn)) + +#endif // wxUSE_TOOLBOOK + +#endif // _WX_TOOLBOOK_H_ diff --git a/src/generic/toolbkg.cpp b/src/generic/toolbkg.cpp new file mode 100644 index 0000000000..611db38af5 --- /dev/null +++ b/src/generic/toolbkg.cpp @@ -0,0 +1,405 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/generic/toolbkg.cpp +// Purpose: generic implementation of wxToolbook +// Author: Julian Smart +// Modified by: +// Created: 2006-01-29 +// RCS-ID: $Id$ +// Copyright: (c) 2006 Julian Smart +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_LISTBOOK + +#include "wx/toolbar.h" +#include "wx/toolbook.h" +#include "wx/settings.h" +#include "wx/sysopt.h" + +// ---------------------------------------------------------------------------- +// various wxWidgets macros +// ---------------------------------------------------------------------------- + +// check that the page index is valid +#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount()) + +// ---------------------------------------------------------------------------- +// event table +// ---------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxToolbook, wxBookCtrlBase) +IMPLEMENT_DYNAMIC_CLASS(wxToolbookEvent, wxNotifyEvent) + +const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING = wxNewEventType(); +const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED = wxNewEventType(); +const int wxID_TOOLBOOKTOOLBAR = wxNewId(); + +BEGIN_EVENT_TABLE(wxToolbook, wxBookCtrlBase) + EVT_SIZE(wxToolbook::OnSize) + EVT_TOOL_RANGE(1, 50, wxToolbook::OnToolSelected) + EVT_IDLE(wxToolbook::OnIdle) +END_EVENT_TABLE() + +// ============================================================================ +// wxToolbook implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxToolbook creation +// ---------------------------------------------------------------------------- + +void wxToolbook::Init() +{ + m_selection = wxNOT_FOUND; + m_needsRealizing = false; +} + +bool +wxToolbook::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT ) + { + style |= wxBK_TOP; + } + + // no border for this control + style &= ~wxBORDER_MASK; + style |= wxBORDER_NONE; + + if ( !wxControl::Create(parent, id, pos, size, style, + wxDefaultValidator, name) ) + return false; + + // TODO: make configurable + m_bookctrl = new wxToolBar + ( + this, + wxID_TOOLBOOKTOOLBAR, + wxDefaultPosition, + wxDefaultSize, + wxTB_HORIZONTAL|wxTB_TEXT|wxTB_FLAT|wxTB_NODIVIDER + ); + + return true; +} + +// ---------------------------------------------------------------------------- +// wxToolbook geometry management +// ---------------------------------------------------------------------------- + +wxSize wxToolbook::GetControllerSize() const +{ + const wxSize sizeClient = GetClientSize(), + sizeBorder = m_bookctrl->GetSize() - m_bookctrl->GetClientSize(), + sizeToolBar = GetToolBar()->GetSize() + sizeBorder; + + wxSize size; + + if ( IsVertical() ) + { + size.x = sizeClient.x; + size.y = sizeToolBar.y; + } + else // left/right aligned + { + size.x = sizeToolBar.x; + size.y = sizeClient.y; + } + + return size; +} + +void wxToolbook::OnSize(wxSizeEvent& event) +{ + if (m_needsRealizing) + Realize(); + + wxBookCtrlBase::OnSize(event); +} + +wxSize wxToolbook::CalcSizeFromPage(const wxSize& sizePage) const +{ + // we need to add the size of the list control and the border between + const wxSize sizeToolBar = GetControllerSize(); + + wxSize size = sizePage; + if ( IsVertical() ) + { + size.y += sizeToolBar.y + GetInternalBorder(); + } + else // left/right aligned + { + size.x += sizeToolBar.x + GetInternalBorder(); + } + + return size; +} + + +// ---------------------------------------------------------------------------- +// accessing the pages +// ---------------------------------------------------------------------------- + +bool wxToolbook::SetPageText(size_t n, const wxString& strText) +{ + // Assume tool ids start from 1 + wxToolBarToolBase* tool = GetToolBar()->FindById(n+1); + if (tool) + { + tool->SetLabel(strText); + return true; + } + else + return false; +} + +wxString wxToolbook::GetPageText(size_t n) const +{ + wxToolBarToolBase* tool = GetToolBar()->FindById(n+1); + if (tool) + { + return tool->GetLabel(); + } + else + return wxEmptyString; +} + +int wxToolbook::GetPageImage(size_t WXUNUSED(n)) const +{ + wxFAIL_MSG( _T("wxToolbook::GetPageImage() not implemented") ); + + return wxNOT_FOUND; +} + +bool wxToolbook::SetPageImage(size_t n, int imageId) +{ + wxASSERT( GetImageList() != NULL ); + if (!GetImageList()) + return false; + + wxToolBarToolBase* tool = GetToolBar()->FindById(n+1); + if (tool) + { + // Find the image list index for this tool + wxBitmap bitmap = GetImageList()->GetBitmap(imageId); + tool->SetNormalBitmap(bitmap); + return true; + } + else + return false; +} + +// ---------------------------------------------------------------------------- +// image list stuff +// ---------------------------------------------------------------------------- + +void wxToolbook::SetImageList(wxImageList *imageList) +{ + wxBookCtrlBase::SetImageList(imageList); +} + +// ---------------------------------------------------------------------------- +// selection +// ---------------------------------------------------------------------------- + +int wxToolbook::GetSelection() const +{ + return m_selection; +} + +int wxToolbook::SetSelection(size_t n) +{ + wxCHECK_MSG( IS_VALID_PAGE(n), wxNOT_FOUND, + wxT("invalid page index in wxToolbook::SetSelection()") ); + + const int oldSel = m_selection; + + if ( int(n) != m_selection ) + { + wxToolbookEvent event(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING, m_windowId); + event.SetSelection(n); + event.SetOldSelection(m_selection); + event.SetEventObject(this); + if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() ) + { + if ( m_selection != wxNOT_FOUND ) + m_pages[m_selection]->Hide(); + + wxWindow *page = m_pages[n]; + page->SetSize(GetPageRect()); + page->Show(); + + // change m_selection now to ignore the selection change event + m_selection = n; + GetToolBar()->ToggleTool(n+1, true); + + // program allows the page change + event.SetEventType(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED); + (void)GetEventHandler()->ProcessEvent(event); + } + } + + return oldSel; +} + +// Not part of the wxBookctrl API, but must be called in OnIdle or +// by application to realize the toolbar and select the initial page. +void wxToolbook::Realize() +{ + if (m_needsRealizing) + { + GetToolBar()->SetToolBitmapSize(m_maxBitmapSize); + + wxSystemOptions::SetOption(wxT("msw.remap"), 0); + GetToolBar()->Realize(); + wxSystemOptions::SetOption(wxT("msw.remap"), 1); + } + + m_needsRealizing = false; + + if (m_selection == -1) + m_selection = 0; + + if (GetPageCount() > 0) + { + int sel = m_selection; + m_selection = -1; + SetSelection(sel); + } + + DoSize(); +} + +void wxToolbook::OnIdle(wxIdleEvent& event) +{ + if (m_needsRealizing) + Realize(); + event.Skip(); +} + +// ---------------------------------------------------------------------------- +// adding/removing the pages +// ---------------------------------------------------------------------------- + +bool +wxToolbook::InsertPage(size_t n, + wxWindow *page, + const wxString& text, + bool bSelect, + int imageId) +{ + if ( !wxBookCtrlBase::InsertPage(n, page, text, bSelect, imageId) ) + return false; + + m_needsRealizing = true; + + wxASSERT(GetImageList() != NULL); + + if (!GetImageList()) + return false; + + // On Windows, we can lose information by using GetBitmap, so extract icon instead + wxIcon icon = GetImageList()->GetIcon(imageId); + wxBitmap bitmap; + bitmap.CopyFromIcon(icon); + + m_maxBitmapSize.x = wxMax(bitmap.GetWidth(), m_maxBitmapSize.x); + m_maxBitmapSize.y = wxMax(bitmap.GetHeight(), m_maxBitmapSize.y); + + GetToolBar()->SetToolBitmapSize(m_maxBitmapSize); + GetToolBar()->AddRadioTool(n+1, text, bitmap, wxNullBitmap, text); + + if (bSelect) + { + // GetToolBar()->ToggleTool(n, true); + m_selection = n; + } + else + page->Hide(); + + InvalidateBestSize(); + return true; +} + +wxWindow *wxToolbook::DoRemovePage(size_t page) +{ + const size_t page_count = GetPageCount(); + wxWindow *win = wxBookCtrlBase::DoRemovePage(page); + + if ( win ) + { + GetToolBar()->DeleteTool(page+1); + + if (m_selection >= (int)page) + { + // force new sel valid if possible + int sel = m_selection - 1; + if (page_count == 1) + sel = wxNOT_FOUND; + else if ((page_count == 2) || (sel == -1)) + sel = 0; + + // force sel invalid if deleting current page - don't try to hide it + m_selection = (m_selection == (int)page) ? wxNOT_FOUND : m_selection - 1; + + if ((sel != wxNOT_FOUND) && (sel != m_selection)) + SetSelection(sel); + } + } + + return win; +} + + +bool wxToolbook::DeleteAllPages() +{ + GetToolBar()->ClearTools(); + return wxBookCtrlBase::DeleteAllPages(); +} + +// ---------------------------------------------------------------------------- +// wxToolbook events +// ---------------------------------------------------------------------------- + +void wxToolbook::OnToolSelected(wxCommandEvent& event) +{ + const int selNew = event.GetId() -1; + + if ( selNew == m_selection ) + { + // this event can only come from our own Select(m_selection) below + // which we call when the page change is vetoed, so we should simply + // ignore it + return; + } + + SetSelection(selNew); + + // change wasn't allowed, return to previous state + if (m_selection != selNew) + { + GetToolBar()->ToggleTool(m_selection, false); + } +} + +#endif // wxUSE_TOOLBOOK -- 2.47.2