Added wxTreebook:

- added the control itself
- added protected wxBookCtrlBase::AllowNullPage() to accommodate it
- big changes to the sample to get rid of (most) ugly macros
- added XRC handler for the control
- added docs
- and wxUSE_TREEBOOK everywhere


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@35862 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2005-10-09 18:40:36 +00:00
parent 97c58531bf
commit eca15c0d54
27 changed files with 2250 additions and 332 deletions

View File

@ -627,6 +627,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/generic/textdlgg.cpp
src/generic/tipwin.cpp
src/generic/treectlg.cpp
src/generic/treebkg.cpp
src/generic/vlbox.cpp
src/generic/vscroll.cpp
</set>
@ -793,6 +794,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/tooltip.h
wx/toplevel.h
wx/treebase.h
wx/treebook.h
wx/treectrl.h
wx/valgen.h
wx/vidmode.h
@ -2610,6 +2612,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/xrc/xh_tglbtn.cpp
src/xrc/xh_toolb.cpp
src/xrc/xh_tree.cpp
src/xrc/xh_treebk.cpp
src/xrc/xh_unkwn.cpp
src/xrc/xh_wizrd.cpp
src/xrc/xmlres.cpp

View File

@ -527,6 +527,7 @@ if test $DEBUG_CONFIGURE = 1; then
DEFAULT_wxUSE_TOOLBAR=no
DEFAULT_wxUSE_TOOLBAR_NATIVE=no
DEFAULT_wxUSE_TOOLBAR_SIMPLE=no
DEFAULT_wxUSE_TREEBOOK=no
DEFAULT_wxUSE_TREECTRL=no
DEFAULT_wxUSE_POPUPWIN=no
DEFAULT_wxUSE_TIPWINDOW=no
@ -723,6 +724,7 @@ else
DEFAULT_wxUSE_TOOLBAR=yes
DEFAULT_wxUSE_TOOLBAR_NATIVE=yes
DEFAULT_wxUSE_TOOLBAR_SIMPLE=yes
DEFAULT_wxUSE_TREEBOOK=yes
DEFAULT_wxUSE_TREECTRL=yes
DEFAULT_wxUSE_POPUPWIN=yes
DEFAULT_wxUSE_TIPWINDOW=yes
@ -1025,6 +1027,7 @@ if test "$wxUSE_CONTROLS" = "yes"; then
DEFAULT_wxUSE_TOOLBAR_NATIVE=yes
DEFAULT_wxUSE_TOOLBAR_SIMPLE=yes
DEFAULT_wxUSE_TOOLTIPS=yes
DEFAULT_wxUSE_TREEBOOK=yes
DEFAULT_wxUSE_TREECTRL=yes
DEFAULT_wxUSE_POPUPWIN=yes
DEFAULT_wxUSE_TIPWINDOW=yes
@ -1065,6 +1068,7 @@ elif test "$wxUSE_CONTROLS" = "no"; then
DEFAULT_wxUSE_TOOLBAR_NATIVE=no
DEFAULT_wxUSE_TOOLBAR_SIMPLE=no
DEFAULT_wxUSE_TOOLTIPS=no
DEFAULT_wxUSE_TREEBOOK=no
DEFAULT_wxUSE_TREECTRL=no
DEFAULT_wxUSE_POPUPWIN=no
DEFAULT_wxUSE_TIPWINDOW=no
@ -1108,6 +1112,7 @@ WX_ARG_ENABLE(togglebtn, [ --enable-togglebtn use wxToggleButton class],
WX_ARG_ENABLE(toolbar, [ --enable-toolbar use wxToolBar class], wxUSE_TOOLBAR)
WX_ARG_ENABLE(tbarnative, [ --enable-tbarnative use native wxToolBar class], wxUSE_TOOLBAR_NATIVE)
WX_ARG_ENABLE(tbarsmpl, [ --enable-tbarsmpl use wxToolBarSimple class], wxUSE_TOOLBAR_SIMPLE)
WX_ARG_ENABLE(treebook, [ --enable-treebook use wxTreebook class], wxUSE_TREEBOOK)
WX_ARG_ENABLE(treectrl, [ --enable-treectrl use wxTreeCtrl class], wxUSE_TREECTRL)
WX_ARG_ENABLE(tipwindow, [ --enable-tipwindow use wxTipWindow class], wxUSE_TIPWINDOW)
WX_ARG_ENABLE(popupwin, [ --enable-popupwin use wxPopUpWindow class], wxUSE_POPUPWIN)
@ -6393,6 +6398,11 @@ if test "$wxUSE_TOOLTIPS" = "yes"; then
fi
fi
if test "$wxUSE_TREEBOOK" = "yes"; then
AC_DEFINE(wxUSE_TREEBOOK)
USES_CONTROLS=1
fi
if test "$wxUSE_TREECTRL" = "yes"; then
if test "$wxUSE_IMAGLIST" = "yes"; then
AC_DEFINE(wxUSE_TREECTRL)

View File

@ -11,6 +11,7 @@ All:
All (GUI):
- added wxTreeBook
- added wxDialog::SetEscapeId()
- wxItemContainerImmutable::FindString unified (affects wxRadioBox, wxListBox,
wxComboBox and wxChoice)

View File

@ -44,6 +44,7 @@ The following are a variety of classes that are derived from wxWindow.
\twocolitem{\helpref{wxNotebook}{wxnotebook}}{Notebook class}
\twocolitem{\helpref{wxListbook}{wxlistbook}}{Similar to notebook but using list control}
\twocolitem{\helpref{wxChoicebook}{wxchoicebook}}{Similar to notebook but using choice control}
\twocolitem{\helpref{wxTreebook}{wxtreebook}}{Similar to notebook but using tree control}
\twocolitem{\helpref{wxSashWindow}{wxsashwindow}}{Window with four optional sashes that can be dragged}
\twocolitem{\helpref{wxSashLayoutWindow}{wxsashlayoutwindow}}{Window that can be involved in an IDE-like layout arrangement}
\twocolitem{\helpref{wxVScrolledWindow}{wxvscrolledwindow}}{As wxScrolledWindow but supports lines of variable height}
@ -252,6 +253,7 @@ An event object contains information about a specific event. Event handlers
\twocolitem{\helpref{wxSplitterEvent}{wxsplitterevent}}{An event from \helpref{wxSplitterWindow}{wxsplitterwindow}}
\twocolitem{\helpref{wxSysColourChangedEvent}{wxsyscolourchangedevent}}{A system colour change event}
\twocolitem{\helpref{wxTimerEvent}{wxtimerevent}}{A timer expiration event}
\twocolitem{\helpref{wxTreebookEvent}{wxtreebookevent}}{A treebook control event}
\twocolitem{\helpref{wxTreeEvent}{wxtreeevent}}{A tree control event}
\twocolitem{\helpref{wxUpdateUIEvent}{wxupdateuievent}}{A user interface update event}
\twocolitem{\helpref{wxWindowCreateEvent}{wxwindowcreateevent}}{A window creation event}

View File

@ -348,6 +348,8 @@
\input toolbar.tex
\input tooltip.tex
\input tlw.tex
\input treebook.tex
\input treebookevent.tex
\input treectrl.tex
\input treeevt.tex
\input treedata.tex

269
docs/latex/wx/treebook.tex Normal file
View File

@ -0,0 +1,269 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: treebook.tex
%% Purpose: wxTreebook documentation
%% Author: Evgeniy Tarassov
%% Modified by:
%% Created: 2005-10-04
%% RCS-ID: $Id$
%% Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwindows.org>
%% License: wxWindows license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{\class{wxTreebook}}\label{wxtreebook}
This class is an extension of the Notebook class that allows a tree structured
set of pages to be shown in a control.
A classic example is a netscape preferences dialog that shows a tree
of preference sections on the left and select section page on the right.
To use the class simply create it and populate with pages using
\helpref{InsertPage}{wxtreebookinsertpage},
\helpref{AddPage}{wxtreebookaddpage},
\helpref{AddSubPage}{wxtreebookaddsubpage}.
If your tree is no more than 1 level in depth then you could
simply use \helpref{AddPage}{wxtreebookaddpage} and
\helpref{AddSubPage}{wxtreebookaddsubpage} to sequentially populate your tree
by adding at every step a page or a subpage to the end of the tree.
\wxheading{Derived from}
wxBookCtrlBase\\
\helpref{wxControl}{wxcontrol}\\
\helpref{wxWindow}{wxwindow}\\
\helpref{wxEvtHandler}{wxevthandler}\\
\helpref{wxObject}{wxobject}
\wxheading{Include files}
<wx/treebook.h>
\input treebookevt.inc
\wxheading{See also}
\helpref{wxNotebook}{wxnotebook}, \helpref{wxTreebookEvent}{wxtreebookevent}, \helpref{wxImageList}{wximagelist}, \helpref{notebook sample}{samplenotebook}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxTreebook::wxTreebook}\label{wxtreebookwxtreebook}
\func{}{wxTreebook}{\void}
Default constructor.
\func{}{wxTreebook}{
\param{wxWindow* }{parent},
\param{wxWindowID }{id},
\param{const wxPoint\& }{pos = wxDefaultPosition},
\param{const wxSize\& }{size = wxDefaultSize},
\param{long }{style = wxTBK\_DEFAULT},
\param{const wxString\& }{name = wxEmptyString}}
Creates an empty TreeBook control.
\wxheading{Parameters}
\docparam{parent}{The parent window. Must be non-NULL.}
\docparam{id}{The window identifier.}
\docparam{pos}{The window position.}
\docparam{size}{The window size.}
\docparam{style}{The window style. See \helpref{wxNotebook}{wxnotebook}.}
\docparam{name}{The name of the control (used only under Motif).}
\membersection{wxTreebook::\destruct{wxTreebook}}\label{wxtreebookdtor}
\func{}{\destruct{wxTreebook}}{\void}
Destroys the wxTreebook object.
Also deletes all the pages owned by the control (inserted previously into it).
\membersection{wxTreebook::AddPage}\label{wxtreebookaddpage}
\func{bool}{AddPage}{
\param{wxWindow* }{page},
\param{const wxString\& }{text},
\param{bool }{bSelect = false},
\param{int }{imageId = wxNOT\_FOUND}}
Adds a new page. The page is placed at the topmost level after all other pages.
NULL could be specified for page to create an empty page.
\membersection{wxTreebook::AddSubPage}\label{wxtreebookaddsubpage}
\func{bool}{AddSubPage}{\param{wxWindow* }{page}, \param{const wxString\& }{text}, \param{bool }{bSelect = false}, \param{int }{imageId = wxNOT\_FOUND}}
\func{bool}{AddSubPage}{\param{size\_t }{pagePos}, \param{wxWindow* }{page}, \param{const wxString\& }{text}, \param{bool }{bSelect = false}, \param{int }{imageId = wxNOT\_FOUND}}
Adds a new child-page to either the last or the specified top-level.
NULL could be specified for page to create an empty page.
\membersection{wxTreebook::AssignImageList}\label{wxtreebookassignimagelist}
\func{void}{AssignImageList}{\param{wxImageList* }{imageList}}
Sets the image list for the page control and takes ownership of the list.
\wxheading{See also}
\helpref{wxImageList}{wximagelist}, \helpref{SetImageList}{wxtreebooksetimagelist}
\membersection{wxTreebook::CollapseNode}\label{wxtreebookcollapsenode}
\func{bool}{CollapseNode}{\param{size\_t }{pageId}}
Shortcut for \helpref{ExpandNode}{wxtreebookexpandnode}(pageId, false).
\membersection{wxTreebook::Create}\label{wxtreebookcreate}
\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = wxTBK\_DEFAULT}, \param{const wxString\& }{name = wxEmptyString}}
Creates a treebook control. See \helpref{wxTreebook::wxTreebook}{wxtreebookwxtreebook} for the description of the parameters.
\membersection{wxTreebook::DeleteAllPages}\label{wxtreebookdeleteallpages}
\func{bool}{DeleteAllPages}{\void}
Deletes all pages inserted into the treebook. No event is generated.
\membersection{wxTreebook::DeletePage}\label{wxtreebookdeletepage}
\func{bool}{DeletePage}{\param{size\_t }{pagePos}}
Deletes the page at the specified position and all its children. Could trigger page selection change
in a case when selected page is removed. In that case its parent is selected
(or the next page if no parent).
\membersection{wxTreebook::ExpandNode}\label{wxtreebookexpandnode}
\func{bool}{ExpandNode}{\param{size\_t }{pageId}, \param{bool }{expand = true}}
Expands (collapses) the pageId node. Returns the previous state.
May generate page changing events (if selected page
is under the collapsed branch, then its parent is autoselected).
\membersection{wxTreebook::GetPageImage}\label{wxtreebookgetpageimage}
\constfunc{int}{GetPageImage}{\param{size\_t }{n}}
Returns the image index for the given page.
\membersection{wxTreebook::GetPageParent}\label{wxtreebookgetpageparent}
\constfunc{int}{GetPageParent}{\param{size\_t }{page}}
Returns the parent page of the given one or \texttt{wxNOT\_FOUND} if this is a
top-level page.
\membersection{wxTreebook::GetPageText}\label{wxtreebookgetpagetext}
\constfunc{wxString}{GetPageText}{\param{size\_t }{n}}
Returns the string for the given page.
\membersection{wxTreebook::GetSelection}\label{wxtreebookgetselection}
\constfunc{int}{GetSelection}{\void}
Returns the currently selected page, or wxNOT\_FOUND if none was selected.
Note that this method may return either the previously or newly selected page
when called from the EVT\_TREEBOOK\_PAGE\_CHANGED handler
depending on the platform and so wxTreebookEvent::GetSelection should be used instead in this case.
\membersection{wxTreebook::InsertPage}\label{wxtreebookinsertpage}
\func{bool}{InsertPage}{\param{size\_t }{pagePos}, \param{wxWindow* }{page}, \param{const wxString\& }{text}, \param{bool }{bSelect = false}, \param{int }{imageId = wxNOT\_FOUND}}
Inserts a new page just before the page indicated by pagePos.
The new page is placed before pagePos page and on the same level.
NULL could be specified for page to create an empty page.
\membersection{wxTreebook::IsNodeExpanded}\label{wxtreebookisnodeexpanded}
\constfunc{bool}{IsNodeExpanded}{\param{size\_t }{pageId}}
Gets the pagePos page state -- whether it is expanded or collapsed
\membersection{wxTreebook::SetImageList}\label{wxtreebooksetimagelist}
\func{void}{SetImageList}{\param{wxImageList* }{imageList}}
Sets the image list for the page control. It does not take ownership of the image list, you must delete it yourself.
\wxheading{See also}
\helpref{wxImageList}{wximagelist}, \helpref{AssignImageList}{wxtreebookassignimagelist}
\membersection{wxTreebook::SetPageImage}\label{wxtreebooksetpageimage}
\func{bool}{SetPageImage}{\param{size\_t }{page}, \param{int }{imageId}}
Sets the image index for the given page. ImageId is an index into the image list
which was set with \helpref{SetImageList}{wxtreebooksetimagelist}.
\membersection{wxTreebook::SetPageText}\label{wxtreebooksetpagetext}
\func{bool}{SetPageText}{\param{size\_t }{page}, \param{const wxString\& }{text}}
Sets the text for the given page.
\membersection{wxTreebook::SetSelection}\label{wxtreebooksetselection}
\func{int}{SetSelection}{\param{size\_t }{n}}
Sets the selection for the given page, returning the previous selection.
The call to this function generates the page changing events.
\wxheading{See also}
\helpref{wxTreebook::GetSelection}{wxtreebookgetselection}

View File

@ -0,0 +1,80 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: treebookevent.tex
%% Purpose: wxTreebookEvent documentation
%% Author: Evgeniy Tarassov
%% Modified by:
%% Created: 2005-10-04
%% RCS-ID: $Id$
%% Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwindows.org>
%% License: wxWindows license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{\class{wxTreebookEvent}}\label{wxtreebookevent}
This class represents the events generated by a treebook control: currently,
there are four of them. The PAGE\_CHANGING and PAGE\_CHANGED - have exactly the same
behaviour as \helpref{wxNotebookEvent}{wxnotebookevent}.
The other two NODE\_COLLAPSED and NODE\_EXPANDED are triggered when page node in the tree control
is collapsed/expanded. The page index could be retreived by calling
\helpref{wxTreebookEvent::GetSelection}{wxtreebookeventgetselection}.
\wxheading{Derived from}
wxBookCtrlBaseEvent\\
\helpref{wxNotifyEvent}{wxnotifyevent}\\
\helpref{wxCommandEvent}{wxcommandevent}\\
\helpref{wxEvent}{wxevent}\\
\helpref{wxObject}{wxobject}
\wxheading{Include files}
<treebook.h>
\input treebookevt.inc
\wxheading{See also}
\helpref{wxNotebookEvent}{wxnotebookevent}, \helpref{wxTreebook}{wxtreebook}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxTreebookEvent::wxTreebookEvent}\label{wxtreebookeventwxtreebookevent}
\func{}{wxTreebookEvent}{\param{wxEventType }{commandType = wxEVT\_NULL}, \param{int }{id = 0}, \param{int }{nSel = wxNOT\_FOUND}, \param{int }{nOldSel = wxNOT\_FOUND}}
\wxheading{See also}
\helpref{wxNotebookEvent}{wxnotebookevent}
\membersection{wxTreebookEvent::GetOldSelection}\label{wxtreebookeventgetoldselection}
\constfunc{int}{GetOldSelection}{\void}
Returns the page that was selected before the change, wxNOT\_FOUND if none was selected.
\membersection{wxTreebookEvent::GetSelection}\label{wxtreebookeventgetselection}
\constfunc{int}{GetSelection}{\void}
Returns the currently selected page, or wxNOT\_FOUND if none was selected.
\wxheading{See also}
\helpref{wxNotebookEvent::GetSelection}{wxnotebookeventgetselection}

View File

@ -0,0 +1,12 @@
\wxheading{Event handling}
To process input from a treebook control, use the following event handler macros
to direct input to member functions that take a \helpref{wxTreebookEvent}{wxtreebookevent} argument.
\twocolwidtha{10cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf EVT\_TREEBOOK\_PAGE\_CHANGED(id, func)}}{The page selection was changed. Processes a wxEVT\_COMMAND\_TREEBOOK\_PAGE\_CHANGED event.}
\twocolitem{{\bf EVT\_TREEBOOK\_PAGE\_CHANGING(id, func)}}{The page selection is about to be changed. Processes a wxEVT\_COMMAND\_TREEBOOK\_PAGE\_CHANGING event. This event can be \helpref{vetoed}{wxnotifyeventveto}.}
\twocolitem{{\bf EVT\_TREEBOOK\_NODE\_COLLAPSED(id, func)}}{The page node is going to be collapsed. Processes a wxEVT\_COMMAND\_TREEBOOK\_NODE\_COLLAPSED event.}
\twocolitem{{\bf EVT\_TREEBOOK\_NODE\_EXPANDED(id, func)}}{The page node is going to be expanded. Processes a wxEVT\_COMMAND\_TREEBOOK\_NODE\_EXPANDED event.}
\end{twocollist}

View File

@ -369,9 +369,9 @@ It replaces the old dynamic sample.
This samples shows \helpref{wxBookCtrl}{wxbookctrloverview} family of controls.
Although initially it was written to demonstrate \helpref{wxNotebook}{wxnotebook}
only, it can now be also used to see \helpref{wxListbook}{wxlistbook} and
\helpref{wxChoicebook}{wxchoicebook} in action. Test each of the controls, their
orientation, images and pages using commands through menu.
only, it can now be also used to see \helpref{wxListbook}{wxlistbook},
\helpref{wxChoicebook}{wxchoicebook} and \helpref{wxTreebook}{wxtreebook} in action.
Test each of the controls, their orientation, images and pages using commands through menu.

View File

@ -176,6 +176,13 @@ public:
}
protected:
// Should we accept NULL page pointers in Add/InsertPage()?
//
// Default is no but derived classes may override it if they can treat NULL
// pages in some sensible way (e.g. wxTreebook overrides this to allow
// having nodes without any associated page)
virtual bool AllowNullPage() const { return false; }
// remove the page and return a pointer to it
virtual wxWindow *DoRemovePage(size_t page) = 0;

View File

@ -614,6 +614,14 @@
// Recommended setting: 1
#define wxUSE_CHOICEBOOK 1
// wxTreebook control is similar to wxNotebook but uses wxTreeCtrl instead of
// the tabs
//
// Default is 1.
//
// Recommended setting: 1
#define wxUSE_TREEBOOK 1
// wxTabDialog is a generic version of wxNotebook but it is incompatible with
// the new class. It shouldn't be used in new code.
//

View File

@ -613,6 +613,14 @@
// Recommended setting: 1
#define wxUSE_CHOICEBOOK 1
// wxTreebook control is similar to wxNotebook but uses wxTreeCtrl instead of
// the tabs
//
// Default is 1.
//
// Recommended setting: 1
#define wxUSE_TREEBOOK 1
// wxTabDialog is a generic version of wxNotebook but it is incompatible with
// the new class. It shouldn't be used in new code.
//

View File

@ -613,6 +613,14 @@
// Recommended setting: 1
#define wxUSE_CHOICEBOOK 1
// wxTreebook control is similar to wxNotebook but uses wxTreeCtrl instead of
// the tabs
//
// Default is 1.
//
// Recommended setting: 1
#define wxUSE_TREEBOOK 1
// wxTabDialog is a generic version of wxNotebook but it is incompatible with
// the new class. It shouldn't be used in new code.
//

View File

@ -609,6 +609,14 @@
// Recommended setting: 1
#define wxUSE_CHOICEBOOK 1
// wxTreebook control is similar to wxNotebook but uses wxTreeCtrl instead of
// the tabs
//
// Default is 1.
//
// Recommended setting: 1
#define wxUSE_TREEBOOK 1
// wxTabDialog is a generic version of wxNotebook but it is incompatible with
// the new class. It shouldn't be used in new code.
//

298
include/wx/treebook.h Normal file
View File

@ -0,0 +1,298 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/treebook.h
// Purpose: wxTreebook: wxNotebook-like control presenting pages in a tree
// Author: Evgeniy Tarassov, Vadim Zeitlin
// Modified by:
// Created: 2005-09-15
// RCS-ID: $Id$
// Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_TREEBOOK_H_
#define _WX_TREEBOOK_H_
#include "wx/defs.h"
#if wxUSE_TREEBOOK
#include "wx/bookctrl.h"
#include "wx/treectrl.h" // for wxArrayTreeItemIds
typedef wxWindow wxTreebookPage;
class WXDLLEXPORT wxTreeEvent;
// ----------------------------------------------------------------------------
// style flags
// ----------------------------------------------------------------------------
// This is a set of synonyms of wxNB_XXX, which still could be used directly
// for styling the control. Defined for consistency with wxListbook and
// wxChoicebook only.
#define wxTBK_LEFT wxNB_LEFT
#define wxTBK_RIGHT wxNB_RIGHT
// we don't support TOP/BOTTOM orientations but still define the flags (again,
// for consistency with others)
#define wxTBK_TOP wxTBK_LEFT
#define wxTBK_BOTTOM wxTBK_RIGHT
#define wxTBK_ALIGN_MASK (wxTBK_LEFT | wxTBK_RIGHT)
#define wxTBK_DEFAULT wxTBK_LEFT
// ----------------------------------------------------------------------------
// wxTreebook
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxTreebook : public wxBookCtrlBase
{
public:
// Constructors and such
// ---------------------
// Default ctor doesn't create the control, use Create() afterwards
wxTreebook()
{
Init();
}
// This ctor creates the tree book control
wxTreebook(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTBK_DEFAULT,
const wxString& name = wxEmptyString)
{
Init();
(void)Create(parent, id, pos, size, style, name);
}
// Really creates the control
bool Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxTBK_DEFAULT,
const wxString& name = wxEmptyString);
// Page insertion operations
// -------------------------
// Notice that page pointer may be NULL in which case the next non NULL
// page (usually the first child page of a node) is shown when this page is
// selected
// Inserts a new page just before the page indicated by page.
// The new page is placed on the same level as page.
virtual bool InsertPage(size_t pos,
wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
// Inserts a new sub-page to the end of children of the page at given pos.
virtual bool AddSubPage(size_t pos,
wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
// Adds a new page at top level after all other pages.
virtual bool AddPage(wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
// Adds a new child-page to the last top-level page inserted.
// Useful when constructing 1 level tree structure.
virtual bool AddSubPage(wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
// Deletes the page and ALL its children. Could trigger page selection
// change in a case when selected page is removed. In that case its parent
// is selected (or the next page if no parent).
virtual bool DeletePage(size_t pos);
// Tree operations
// ---------------
// Gets the page node state -- node is expanded or collapsed
virtual bool IsNodeExpanded(size_t pos) const;
// Expands or collapses the page node. Returns the previous state.
// May generate page changing events (if selected page
// is under the collapsed branch, then parent is autoselected).
virtual bool ExpandNode(size_t pos, bool expand = true);
// shortcut for ExpandNode(pos, false)
bool CollapseNode(size_t pos) { return ExpandNode(pos, false); }
// get the parent page or wxNOT_FOUND if this is a top level page
int GetPageParent(size_t pos) const;
// Standard operations inherited from wxBookCtrlBase
// -------------------------------------------------
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 int SetSelection(size_t n);
virtual void SetImageList(wxImageList *imageList);
virtual void AssignImageList(wxImageList *imageList);
virtual bool DeleteAllPages();
protected:
// This subclass of wxBookCtrlBase accepts NULL page pointers (empty pages)
virtual bool AllowNullPage() const { return true; }
// get the size which the tree control should have
wxSize GetTreeSize() const;
// get the page area
wxRect GetPageRect() const;
// event handlers
void OnSize(wxSizeEvent& event);
void OnTreeSelectionChange(wxTreeEvent& event);
void OnTreeNodeExpandedCollapsed(wxTreeEvent& event);
// the tree control we use for showing the pages index tree
wxTreeCtrl *m_tree;
// array of page ids and page windows
wxArrayTreeItemIds m_treeIds;
// the currently selected page or wxNOT_FOUND if none
int m_selection;
// in the situation when m_selection page is not wxNOT_FOUND but page is
// NULL this is the first (sub)child that has a non-NULL page
int m_actualSelection;
private:
// common part of all constructors
void Init();
// The real implementations of page insertion functions
// ------------------------------------------------------
// All DoInsert/Add(Sub)Page functions add the page into :
// - the base class
// - the tree control
// - update the index/TreeItemId corespondance array
bool DoInsertPage(size_t pos,
wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
bool DoInsertSubPage(size_t pos,
wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
bool DoAddSubPage(wxWindow *page,
const wxString& text,
bool bSelect = false,
int imageId = wxNOT_FOUND);
// Implementation of a page removal. See DeletPage for comments.
wxTreebookPage *DoRemovePage(size_t pos);
// Sets selection in the tree control and updates the page being shown.
int DoSetSelection(size_t pos);
// Returns currently shown page. In a case when selected the node
// has empty (NULL) page finds first (sub)child with not-empty page.
wxTreebookPage *DoGetCurrentPage() const;
// Does the selection update. Called from page insertion functions
// to update selection if the selected page was pushed by the newly inserted
void DoUpdateSelection(bool bSelect, int page);
// Operations on the internal private members of the class
// -------------------------------------------------------
// Returns the page TreeItemId for the page.
// Or, if the page index is incorrect, a fake one (fakePage.IsOk() == false)
wxTreeItemId DoInternalGetPage(size_t pos) const;
// Linear search for a page with the id specified. If no page
// found wxNOT_FOUND is returned. The function is used when we catch an event
// from m_tree (wxTreeCtrl) component.
int DoInternalFindPageById(wxTreeItemId page) const;
// Updates page and wxTreeItemId correspondance.
void DoInternalAddPage(size_t newPos, wxWindow *page, wxTreeItemId pageId);
// Removes the page from internal structure.
void DoInternalRemovePage(size_t pos)
{ DoInternalRemovePageRange(pos, 0); }
// Removes the page and all its children designated by subCount
// from internal structures of the control.
void DoInternalRemovePageRange(size_t pos, size_t subCount);
// Returns internal number of pages which can be different from
// GetPageCount() while performing a page insertion or removal.
size_t DoInternalGetPageCount() const { return m_treeIds.Count(); }
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS_NO_COPY(wxTreebook)
};
// ----------------------------------------------------------------------------
// treebook event class and related stuff
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxTreebookEvent : public wxBookCtrlBaseEvent
{
public:
wxTreebookEvent(wxEventType commandType = wxEVT_NULL, int id = 0,
int nSel = wxNOT_FOUND, int nOldSel = wxNOT_FOUND)
: wxBookCtrlBaseEvent(commandType, id, nSel, nOldSel)
{
}
private:
DECLARE_DYNAMIC_CLASS_NO_COPY(wxTreebookEvent)
};
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED;
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING;
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED;
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED;
typedef void (wxEvtHandler::*wxTreebookEventFunction)(wxTreebookEvent&);
#define wxTreebookEventHandler(func) \
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxTreebookEventFunction, &func)
#define EVT_TREEBOOK_PAGE_CHANGED(winid, fn) \
wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, winid, wxTreebookEventHandler(fn))
#define EVT_TREEBOOK_PAGE_CHANGING(winid, fn) \
wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, winid, wxTreebookEventHandler(fn))
#define EVT_TREEBOOK_NODE_COLLAPSED(winid, fn) \
wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED, winid, wxTreebookEventHandler(fn))
#define EVT_TREEBOOK_NODE_EXPANDED(winid, fn) \
wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED, winid, wxTreebookEventHandler(fn))
#endif // wxUSE_TREEBOOK
#endif // _WX_TREEBOOK_H_

View File

@ -649,6 +649,14 @@
// Recommended setting: 1
#define wxUSE_CHOICEBOOK 1
// wxTreebook control is similar to wxNotebook but uses wxTreeCtrl instead of
// the tabs
//
// Default is 1.
//
// Recommended setting: 1
#define wxUSE_TREEBOOK 1
// wxTabDialog is a generic version of wxNotebook but it is incompatible with
// the new class. It shouldn't be used in new code.
//

View File

@ -36,6 +36,7 @@
#include "wx/xrc/xh_notbk.h"
#include "wx/xrc/xh_listbk.h"
#include "wx/xrc/xh_choicbk.h"
#include "wx/xrc/xh_treebk.h"
#include "wx/xrc/xh_text.h"
#include "wx/xrc/xh_listb.h"
#include "wx/xrc/xh_toolb.h"

View File

@ -0,0 +1,81 @@
/////////////////////////////////////////////////////////////////////////////
// Name: xh_treebk.h
// Purpose: XML resource handler for wxTreebook
// Author: Evgeniy Tarassov
// Created: 2005/09/28
// Copyright: (c) 2005 TT-Solutions <vadim@tt-solutions.com>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_XH_TREEBK_H_
#define _WX_XH_TREEBK_H_
#include "wx/xrc/xmlres.h"
#if wxUSE_TREEBOOK
#include "wx/treebook.h"
WX_DEFINE_ARRAY_INT(size_t, wxArrayTbkPageIndexes);
// ---------------------------------------------------------------------
// wxTreebookXmlHandler class
// ---------------------------------------------------------------------
// Resource xml structure have to be almost the "same" as for wxNotebook
// except the additional (size_t)depth parameter for treebookpage nodes
// which indicates the depth of the page in the tree.
// There is only one logical constraint on this parameter :
// it cannot be greater than the previous page depth plus one
class WXDLLIMPEXP_XRC wxTreebookXmlHandler : public wxXmlResourceHandler
{
DECLARE_DYNAMIC_CLASS(wxTreebookXmlHandler)
public:
wxTreebookXmlHandler();
virtual wxObject *DoCreateResource();
virtual bool CanHandle(wxXmlNode *node);
private:
bool m_isInside;
wxTreebook * m_tbk;
wxArrayTbkPageIndexes m_treeContext;
};
// Example:
// -------
// Label
// \--First
// | \--Second
// \--Third
//
//<resource>
// ...
// <object class="wxTreebook">
// <object class="treebookpage">
// <object class="wxWindow" />
// <label>My first page</label>
// <depth>0</depth>
// </object>
// <object class="treebookpage">
// <object class="wxWindow" />
// <label>First</label>
// <depth>1</depth>
// </object>
// <object class="treebookpage">
// <object class="wxWindow" />
// <label>Second</label>
// <depth>2</depth>
// </object>
// <object class="treebookpage">
// <object class="wxWindow" />
// <label>Third</label>
// <depth>1</depth>
// </object>
// </object>
// ...
//</resource>
#endif
#endif // _WX_XH_TREEBK_H_

View File

@ -33,7 +33,7 @@ IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
// Create the main window
MyFrame *frame = new MyFrame( wxT("Notebook sample") );
MyFrame *frame = new MyFrame();
// Problem with generic wxNotebook implementation whereby it doesn't size
// properly unless you set the size again
@ -153,51 +153,40 @@ void CreateInitialPages(wxBookCtrlBase *parent)
wxPanel *CreatePage(wxBookCtrlBase *parent, const wxString&pageName)
{
if
(
pageName.Contains(INSERTED_PAGE_NAME)
|| pageName.Contains(ADDED_PAGE_NAME)
)
{
if ( pageName.Contains(INSERTED_PAGE_NAME) ||
pageName.Contains(ADDED_PAGE_NAME) ||
pageName.Contains(ADDED_SUB_PAGE_NAME) ||
pageName.Contains(ADDED_PAGE_NAME_BEFORE) )
return CreateUserCreatedPage(parent);
}
if (pageName == I_WAS_INSERTED_PAGE_NAME)
{
if ( pageName == I_WAS_INSERTED_PAGE_NAME )
return CreateInsertPage(parent);
}
if (pageName == VETO_PAGE_NAME)
{
if ( pageName == VETO_PAGE_NAME )
return CreateVetoPage(parent);
}
if (pageName == RADIOBUTTONS_PAGE_NAME)
{
if ( pageName == RADIOBUTTONS_PAGE_NAME )
return CreateRadioButtonsPage(parent);
}
if (pageName == MAXIMIZED_BUTTON_PAGE_NAME)
{
if ( pageName == MAXIMIZED_BUTTON_PAGE_NAME )
return CreateBigButtonPage(parent);
}
wxFAIL;
wxFAIL_MSG( _T("unknown page name") );
return (wxPanel *) NULL;
return NULL;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style)
: wxFrame((wxWindow *) NULL, wxID_ANY, title, pos, size, style)
MyFrame::MyFrame()
: wxFrame(NULL, wxID_ANY, wxString(wxT("wxWidgets book controls sample")))
{
#if wxUSE_NOTEBOOK
m_type = ID_BOOK_NOTEBOOK;
m_type = Type_Notebook;
#elif wxUSE_CHOICEBOOK
m_type = ID_BOOK_CHOICEBOOK;
m_type = Type_Choicebook;
#elif wxUSE_LISTBOOK
m_type = ID_BOOK_LISTBOOK;
m_type = Type_Listbook;
#elif wxUSE_TREEBOOK
m_type = Type_Treebook;
#elif
#error "Don't use Notebook sample without any book enabled in wxWidgets build!"
#endif
@ -219,21 +208,30 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
#if wxUSE_CHOICEBOOK
menuType->AppendRadioItem(ID_BOOK_CHOICEBOOK, wxT("&Choicebook\tCtrl-3"));
#endif
menuType->Check(m_type, true);
#if wxUSE_TREEBOOK
menuType->AppendRadioItem(ID_BOOK_TREEBOOK, wxT("&Treebook\tCtrl-4"));
#endif
menuType->Check(ID_BOOK_NOTEBOOK + m_type, true);
wxMenu *menuOrient = new wxMenu;
menuOrient->AppendRadioItem(ID_ORIENT_DEFAULT, wxT("&Default\tCtrl-4"));
menuOrient->AppendRadioItem(ID_ORIENT_TOP, wxT("&Top\tCtrl-5"));
menuOrient->AppendRadioItem(ID_ORIENT_BOTTOM, wxT("&Bottom\tCtrl-6"));
menuOrient->AppendRadioItem(ID_ORIENT_LEFT, wxT("&Left\tCtrl-7"));
menuOrient->AppendRadioItem(ID_ORIENT_RIGHT, wxT("&Right\tCtrl-8"));
menuOrient->AppendRadioItem(ID_ORIENT_DEFAULT, wxT("&Default\tCtrl-5"));
menuOrient->AppendRadioItem(ID_ORIENT_TOP, wxT("&Top\tCtrl-6"));
menuOrient->AppendRadioItem(ID_ORIENT_BOTTOM, wxT("&Bottom\tCtrl-7"));
menuOrient->AppendRadioItem(ID_ORIENT_LEFT, wxT("&Left\tCtrl-8"));
menuOrient->AppendRadioItem(ID_ORIENT_RIGHT, wxT("&Right\tCtrl-9"));
wxMenu *menuDo = new wxMenu;
menuDo->Append(ID_ADD_PAGE, wxT("&Add page\tAlt-A"));
menuDo->Append(ID_INSERT_PAGE, wxT("&Insert page\tAlt-I"));
menuDo->Append(ID_DELETE_CUR_PAGE, wxT("&Delete current page\tAlt-D"));
menuDo->Append(ID_DELETE_LAST_PAGE, wxT("D&elete last page\tAlt-L"));
menuDo->Append(ID_NEXT_PAGE, wxT("&Next page\tAlt-N"));
wxMenu *menuOperations = new wxMenu;
menuOperations->Append(ID_ADD_PAGE, wxT("&Add page\tAlt-A"));
menuOperations->Append(ID_INSERT_PAGE, wxT("&Insert page\tAlt-I"));
menuOperations->Append(ID_DELETE_CUR_PAGE, wxT("&Delete current page\tAlt-D"));
menuOperations->Append(ID_DELETE_LAST_PAGE, wxT("D&elete last page\tAlt-L"));
menuOperations->Append(ID_NEXT_PAGE, wxT("&Next page\tAlt-N"));
#if wxUSE_TREEBOOK
menuOperations->AppendSeparator();
menuOperations->Append(ID_ADD_PAGE_BEFORE, wxT("Insert page &before\tAlt-B"));
menuOperations->Append(ID_ADD_SUB_PAGE, wxT("Add s&ub page\tAlt-U"));
#endif
wxMenu *menuFile = new wxMenu;
menuFile->Append(wxID_ANY, wxT("&Type"), menuType, wxT("Type of control"));
@ -247,54 +245,32 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, wxT("&File"));
menuBar->Append(menuDo, wxT("&Operations"));
menuBar->Append(menuOperations, wxT("&Operations"));
SetMenuBar(menuBar);
// books creation
m_panel = (wxPanel *) NULL;
#if wxUSE_NOTEBOOK
m_notebook = (wxNotebook *) NULL;
#endif
#if wxUSE_CHOICEBOOK
m_choicebook = (wxChoicebook *) NULL;
#endif
#if wxUSE_LISTBOOK
m_listbook = (wxListbook *) NULL;
#endif
m_panel = NULL;
m_bookCtrl = NULL;
// create a dummy image list with a few icons
wxSize imageSize(32, 32);
const wxSize imageSize(32, 32);
m_imageList
= new wxImageList( imageSize.GetWidth(), imageSize.GetHeight() );
m_imageList = new wxImageList(imageSize.GetWidth(), imageSize.GetHeight());
m_imageList->
Add(wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, imageSize));
m_imageList->
Add(wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, imageSize));
m_imageList->
Add(wxArtProvider::GetIcon(wxART_WARNING, wxART_OTHER, imageSize));
m_imageList->
Add(wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, imageSize));
m_imageList->Add
(
wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, imageSize)
);
m_imageList->Add
(
wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, imageSize)
);
m_imageList->Add
(
wxArtProvider::GetIcon(wxART_WARNING, wxART_OTHER, imageSize)
);
m_imageList->Add
(
wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, imageSize)
);
m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxTAB_TRAVERSAL | wxCLIP_CHILDREN | wxNO_BORDER | wxNO_FULL_REPAINT_ON_RESIZE);
m_panel = new wxPanel(this);
#if USE_LOG
m_text = new wxTextCtrl(m_panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxTE_READONLY);
m_logTargetOld = wxLog::SetActiveTarget( new wxLogTextCtrl(m_text) );
#endif // USE_LOG
@ -306,7 +282,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
m_sizerFrame->Add(m_text, 1, wxEXPAND);
#endif // USE_LOG
RecreateBooks();
RecreateBook();
m_panel->SetSizer(m_sizerFrame);
@ -322,160 +298,175 @@ MyFrame::~MyFrame()
delete wxLog::SetActiveTarget(m_logTargetOld);
#endif // USE_LOG
if (m_imageList)
{
delete m_imageList;
m_imageList = (wxImageList *) NULL;
}
delete m_imageList;
}
int MyFrame::SelectFlag(int id, int nb, int lb, int chb)
{
switch (id)
{
case ID_NOTEBOOK: return nb;
case ID_LISTBOOK: return lb;
case ID_CHOICEBOOK: return chb;
}
return 0;
}
#ifdef __SMARTPHONE__
#define MARGIN 0
// DISPATCH_ON_TYPE() macro is an ugly way to write the "same" code for
// different wxBookCtrlBase-derived classes without duplicating code and
// without using templates, it expands into "before <xxx> after" where "xxx"
// part is control class-specific
#if wxUSE_NOTEBOOK
#define CASE_NOTEBOOK(x) case Type_Notebook: x; break;
#else
#define MARGIN 4
#define CASE_NOTEBOOK(x)
#endif
#define RECREATE( wxBookType , idBook, oldBook , newBook ) \
{ \
int flags; \
\
switch ( m_orient ) \
{ \
case ID_ORIENT_TOP: \
flags = SelectFlag(idBook, wxNB_TOP, wxLB_TOP, wxCHB_TOP); \
break; \
\
case ID_ORIENT_BOTTOM: \
flags = SelectFlag(idBook, wxNB_BOTTOM, wxLB_BOTTOM, wxCHB_BOTTOM); \
break; \
\
case ID_ORIENT_LEFT: \
flags = SelectFlag(idBook, wxNB_LEFT, wxLB_LEFT, wxCHB_LEFT); \
break; \
\
case ID_ORIENT_RIGHT: \
flags = SelectFlag(idBook, wxNB_RIGHT, wxLB_RIGHT, wxCHB_RIGHT); \
break; \
\
default: \
flags = SelectFlag(idBook, wxNB_DEFAULT, wxLB_DEFAULT, wxCHB_DEFAULT); \
} \
\
if ( m_multi && ( idBook == ID_NOTEBOOK ) ) \
flags |= wxNB_MULTILINE; \
\
wxBookType *oldBook = newBook; \
\
newBook = new wxBookType(m_panel, idBook, \
wxDefaultPosition, wxDefaultSize, \
flags); \
\
if ( m_chkShowImages ) \
{ \
newBook->SetImageList(m_imageList); \
} \
\
if (oldBook) \
{ \
int sel = oldBook->GetSelection(); \
\
int count = oldBook->GetPageCount(); \
for (int n = 0; n < count; n++) \
{ \
wxString str = oldBook->GetPageText(n); \
\
wxWindow *page = CreatePage(newBook, str); \
newBook->AddPage(page, str, false, GetIconIndex(newBook) ); \
} \
\
m_sizerFrame->Detach(oldBook); \
\
delete oldBook; \
\
if (sel != wxNOT_FOUND) \
{ \
newBook->SetSelection(sel); \
} \
\
} \
else \
{ \
CreateInitialPages(newBook); \
} \
\
m_sizerFrame->Insert(0, newBook, 5, wxEXPAND | wxALL, MARGIN); \
\
m_sizerFrame->Hide(newBook); \
}
void MyFrame::RecreateBooks()
{
#if wxUSE_NOTEBOOK
RECREATE( wxNotebook , ID_NOTEBOOK , notebook , m_notebook );
#endif
#if wxUSE_LISTBOOK
RECREATE( wxListbook , ID_LISTBOOK , listbook , m_listbook );
#endif
#if wxUSE_CHOICEBOOK
RECREATE( wxChoicebook , ID_CHOICEBOOK , choicebook , m_choicebook );
#define CASE_CHOICEBOOK(x) case Type_Choicebook: x; break;
#else
#define CASE_CHOICEBOOK(x)
#endif
ShowCurrentBook();
}
wxBookCtrlBase *MyFrame::GetCurrentBook()
{
switch (m_type)
{
#if wxUSE_NOTEBOOK
case ID_BOOK_NOTEBOOK: return m_notebook;
#endif
#if wxUSE_LISTBOOK
case ID_BOOK_LISTBOOK: return m_listbook;
#define CASE_LISTBOOK(x) case Type_Listbook: x; break;
#else
#define CASE_LISTBOOK(x)
#endif
#if wxUSE_CHOICEBOOK
case ID_BOOK_CHOICEBOOK: return m_choicebook;
#endif
}
return NULL;
}
void MyFrame::ShowCurrentBook()
{
switch(m_type)
{
#if wxUSE_NOTEBOOK
case ID_BOOK_NOTEBOOK: if(m_notebook) m_sizerFrame->Show(m_notebook); break;
#endif
#if wxUSE_LISTBOOK
case ID_BOOK_LISTBOOK: if(m_listbook) m_sizerFrame->Show(m_listbook); break;
#endif
#if wxUSE_CHOICEBOOK
case ID_BOOK_CHOICEBOOK: if(m_choicebook) m_sizerFrame->Show(m_choicebook); break;
#if wxUSE_TREEBOOK
#define CASE_TREEBOOK(x) case Type_Treebook: x; break;
#else
#define CASE_TREEBOOK(x)
#endif
#define DISPATCH_ON_TYPE(before, nb, lb, cb, tb, after) \
switch ( m_type ) \
{ \
CASE_NOTEBOOK(before nb after) \
CASE_CHOICEBOOK(before cb after) \
CASE_LISTBOOK(before lb after) \
CASE_TREEBOOK(before tb after) \
\
default: \
wxFAIL_MSG( _T("unknown book control type") ); \
}
int MyFrame::TranslateBookFlag(int nb, int lb, int chb, int tbk) const
{
int flag = 0;
DISPATCH_ON_TYPE(flag =, nb, lb, chb, tbk, + 0);
return flag;
}
void MyFrame::RecreateBook()
{
#define SELECT_FLAG(flag) \
TranslateBookFlag(wxNB_##flag, wxCHB_##flag, wxLB_##flag, wxTBK_##flag)
int flags;
switch ( m_orient )
{
case ID_ORIENT_TOP:
flags = SELECT_FLAG(TOP);
break;
case ID_ORIENT_BOTTOM:
flags = SELECT_FLAG(BOTTOM);
break;
case ID_ORIENT_LEFT:
flags = SELECT_FLAG(LEFT);
break;
case ID_ORIENT_RIGHT:
flags = SELECT_FLAG(RIGHT);
break;
default:
flags = SELECT_FLAG(DEFAULT);
}
#undef SELECT_FLAG
if ( m_multi && m_type == Type_Notebook )
flags |= wxNB_MULTILINE;
flags |= wxDOUBLE_BORDER;
wxBookCtrlBase *oldBook = m_bookCtrl;
m_bookCtrl = NULL;
DISPATCH_ON_TYPE(m_bookCtrl = new,
wxNotebook,
wxChoicebook,
wxListbook,
wxTreebook,
(m_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, flags));
if ( !m_bookCtrl )
return;
m_bookCtrl->Hide();
if ( m_chkShowImages )
{
m_bookCtrl->SetImageList(m_imageList);
}
if ( oldBook )
{
#if wxUSE_TREEBOOK
// we only need the old treebook if we're recreating another treebook
wxTreebook *tbkOld = m_type == Type_Treebook
? wxDynamicCast(oldBook, wxTreebook)
: NULL;
#endif // wxUSE_TREEBOOK
const int count = oldBook->GetPageCount();
for ( int n = 0; n < count; n++ )
{
const int image = GetIconIndex(m_bookCtrl);
const wxString str = oldBook->GetPageText(n);
wxWindow *page = CreatePage(m_bookCtrl, str);
// treebook complication: need to account for possible parent page
#if wxUSE_TREEBOOK
if ( tbkOld )
{
const int parent = tbkOld->GetPageParent(n);
if ( parent != wxNOT_FOUND )
{
wxStaticCast(m_bookCtrl, wxTreebook)->
AddSubPage(parent, page, str, false, image);
// skip adding it again below
continue;
}
}
#endif // wxUSE_TREEBOOK
m_bookCtrl->AddPage(page, str, false, image);
}
const int sel = oldBook->GetSelection();
if ( sel != wxNOT_FOUND )
m_bookCtrl->SetSelection(sel);
m_sizerFrame->Detach(oldBook);
delete oldBook;
}
else // no old book
{
CreateInitialPages(m_bookCtrl);
}
m_sizerFrame->Insert(0, m_bookCtrl, wxSizerFlags(5).Expand().Border());
m_sizerFrame->Show(m_bookCtrl);
m_sizerFrame->Layout();
}
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
// File menu
EVT_MENU_RANGE(ID_BOOK_NOTEBOOK,ID_BOOK_MAX,MyFrame::OnType)
EVT_MENU_RANGE(ID_ORIENT_DEFAULT,ID_ORIENT_MAX,MyFrame::OnOrient)
EVT_MENU_RANGE(ID_BOOK_NOTEBOOK, ID_BOOK_MAX, MyFrame::OnType)
EVT_MENU_RANGE(ID_ORIENT_DEFAULT, ID_ORIENT_MAX, MyFrame::OnOrient)
EVT_MENU(ID_SHOW_IMAGES, MyFrame::OnShowImages)
EVT_MENU(ID_MULTI, MyFrame::OnMulti)
EVT_MENU(wxID_EXIT,MyFrame::OnExit)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
// Operations menu
EVT_MENU(ID_ADD_PAGE, MyFrame::OnAddPage)
@ -483,55 +474,74 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_DELETE_CUR_PAGE, MyFrame::OnDeleteCurPage)
EVT_MENU(ID_DELETE_LAST_PAGE, MyFrame::OnDeleteLastPage)
EVT_MENU(ID_NEXT_PAGE, MyFrame::OnNextPage)
EVT_MENU(ID_ADD_SUB_PAGE, MyFrame::OnAddSubPage)
EVT_MENU(ID_ADD_PAGE_BEFORE, MyFrame::OnAddPageBefore)
// Book controls
#if wxUSE_NOTEBOOK
EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, MyFrame::OnNotebook)
EVT_NOTEBOOK_PAGE_CHANGING(ID_NOTEBOOK, MyFrame::OnNotebook)
EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnNotebook)
EVT_NOTEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnNotebook)
#endif
#if wxUSE_LISTBOOK
EVT_LISTBOOK_PAGE_CHANGED(ID_LISTBOOK, MyFrame::OnListbook)
EVT_LISTBOOK_PAGE_CHANGING(ID_LISTBOOK, MyFrame::OnListbook)
EVT_LISTBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnListbook)
EVT_LISTBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnListbook)
#endif
#if wxUSE_CHOICEBOOK
EVT_CHOICEBOOK_PAGE_CHANGED(ID_CHOICEBOOK, MyFrame::OnChoicebook)
EVT_CHOICEBOOK_PAGE_CHANGING(ID_CHOICEBOOK, MyFrame::OnChoicebook)
EVT_CHOICEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnChoicebook)
EVT_CHOICEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnChoicebook)
#endif
#if wxUSE_CHOICEBOOK
EVT_TREEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnTreebook)
EVT_TREEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnTreebook)
#endif
// Update title in idle time
EVT_IDLE(MyFrame::OnIdle)
#if wxUSE_TREEBOOK
EVT_UPDATE_UI_RANGE(ID_ADD_PAGE_BEFORE, ID_ADD_SUB_PAGE,
MyFrame::OnUpdateTreeMenu)
#endif // wxUSE_TREEBOOK
END_EVENT_TABLE()
void MyFrame::OnType(wxCommandEvent& event)
{
wxBookCtrlBase *currBook = GetCurrentBook();
m_type = wx_static_cast(BookType, event.GetId() - ID_BOOK_NOTEBOOK);
m_type = event.GetId();
if ( m_bookCtrl )
m_sizerFrame->Hide(m_bookCtrl);
if (currBook)
m_sizerFrame->Hide(currBook);
ShowCurrentBook();
RecreateBook();
}
#if wxUSE_TREEBOOK
void MyFrame::OnUpdateTreeMenu(wxUpdateUIEvent& event)
{
event.Enable(m_type == Type_Treebook);
}
#endif // wxUSE_TREEBOOK
void MyFrame::OnOrient(wxCommandEvent& event)
{
m_orient = event.GetId();
RecreateBooks();
RecreateBook();
m_sizerFrame->Layout();
}
void MyFrame::OnShowImages(wxCommandEvent& event)
{
m_chkShowImages = event.IsChecked();
RecreateBooks();
RecreateBook();
m_sizerFrame->Layout();
}
void MyFrame::OnMulti(wxCommandEvent& event)
{
m_multi = event.IsChecked();
RecreateBooks();
RecreateBook();
m_sizerFrame->Layout();
wxLogMessage(_T("Multiline setting works only in wxNotebook."));
}
@ -541,25 +551,85 @@ void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
Close();
}
wxPanel *MyFrame::CreateNewPage() const
{
wxPanel *panel = new wxPanel(m_bookCtrl, wxID_ANY );
(void) new wxButton(panel, wxID_ANY, wxT("First button"), wxPoint(10, 10));
(void) new wxButton(panel, wxID_ANY, wxT("Second button"), wxPoint(50, 100));
return panel;
}
void MyFrame::OnAddPage(wxCommandEvent& WXUNUSED(event))
{
static unsigned s_pageAdded = 0;
wxBookCtrlBase *currBook = GetCurrentBook();
if ( currBook )
{
wxPanel *panel = new wxPanel( currBook, wxID_ANY );
(void) new wxButton( panel, wxID_ANY, wxT("First button"),
wxPoint(10, 10), wxDefaultSize );
(void) new wxButton( panel, wxID_ANY, wxT("Second button"),
wxPoint(50, 100), wxDefaultSize );
currBook->AddPage(panel, wxString::Format(ADDED_PAGE_NAME wxT("%u"),
++s_pageAdded), true, GetIconIndex(currBook) );
static unsigned s_pageAdded = 0;
currBook->AddPage(CreateNewPage(),
wxString::Format
(
ADDED_PAGE_NAME wxT("%u"),
++s_pageAdded
),
true,
GetIconIndex(currBook));
}
}
#if wxUSE_TREEBOOK
void MyFrame::OnAddSubPage(wxCommandEvent& WXUNUSED(event))
{
wxTreebook *currBook = wxDynamicCast(GetCurrentBook(), wxTreebook);
if ( currBook )
{
const int selPos = currBook->GetSelection();
if ( selPos == wxNOT_FOUND )
{
wxLogError(_T("Select the parent page first!"));
return;
}
static unsigned s_subPageAdded = 0;
currBook->AddSubPage(selPos,
CreateNewPage(),
wxString::Format
(
ADDED_SUB_PAGE_NAME wxT("%u"),
++s_subPageAdded
),
true,
GetIconIndex(currBook));
}
}
void MyFrame::OnAddPageBefore(wxCommandEvent& WXUNUSED(event))
{
wxBookCtrlBase *currBook = GetCurrentBook();
if ( currBook )
{
const int selPos = currBook->GetSelection();
if ( selPos == wxNOT_FOUND )
{
wxLogError(_T("Select the parent page first!"));
return;
}
static unsigned s_subPageAdded = 0;
currBook->InsertPage(selPos,
CreateNewPage(),
wxString::Format
(
ADDED_PAGE_NAME_BEFORE wxT("%u"),
++s_subPageAdded
),
true,
GetIconIndex(currBook));
}
}
#endif // wxUSE_TREEBOOK
void MyFrame::OnInsertPage(wxCommandEvent& WXUNUSED(event))
{
static unsigned s_pageIns = 0;
@ -648,65 +718,103 @@ void MyFrame::OnIdle( wxIdleEvent& WXUNUSED(event) )
}
}
#if USE_LOG
#define BOOKEVENT_LOG m_text->SetInsertionPointEnd();
#else
#define BOOKEVENT_LOG
#endif
void MyFrame::OnBookCtrl(wxBookCtrlBaseEvent& event)
{
static const struct EventInfo
{
wxEventType typeChanged,
typeChanging;
const wxChar *name;
} events[] =
{
#if wxUSE_NOTEBOOK
{
wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
_T("wxNotebook")
},
#endif // wxUSE_NOTEBOOK
#if wxUSE_CHOICEBOOK
{
wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED,
wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING,
_T("wxChoicebook")
},
#endif // wxUSE_CHOICEBOOK
#if wxUSE_LISTBOOK
{
wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED,
wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING,
_T("wxListbook")
},
#endif // wxUSE_LISTBOOK
#if wxUSE_TREEBOOK
{
wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED,
wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING,
_T("wxTreebook")
},
#endif // wxUSE_TREEBOOK
};
#define BOOKEVENT(OnBook,wxBookEvent,bookStr,wxEVT_PAGE_CHANGED,wxEVT_PAGE_CHANGING,s_num) \
void MyFrame::OnBook(wxBookEvent& event) \
{ \
wxString str = wxT("Unknown "); \
str << wxT(bookStr); \
str << wxT(" event"); \
\
wxEventType eventType = event.GetEventType(); \
\
if (eventType == wxEVT_PAGE_CHANGED) \
{ \
str = wxT("Changed"); \
} \
else if (eventType == wxEVT_PAGE_CHANGING) \
{ \
int idx = event.GetOldSelection(); \
wxBookCtrlBase *book = (wxBookCtrlBase *)event.GetEventObject(); \
if ( idx != wxNOT_FOUND && book && book->GetPageText(idx) == VETO_PAGE_NAME ) \
{ \
if \
( \
wxMessageBox( \
wxT("Are you sure you want to leave this page?\n") \
wxT("(This demonstrates veto-ing)"), \
wxT("Notebook sample"), \
wxICON_QUESTION | wxYES_NO, this) != wxYES ) \
{ \
event.Veto(); \
} \
\
} \
\
str = wxT("Changing"); \
} \
\
static int s_num = 0; \
\
wxString logMsg; \
logMsg.Printf(wxT("%s event #%d: %s (%d) Sel %d, OldSel %d"), \
wxT(bookStr),s_num++, str.c_str(), eventType, \
event.GetSelection(), event.GetOldSelection()); \
\
wxLogMessage(logMsg.c_str()); \
\
BOOKEVENT_LOG \
wxString nameEvent,
nameControl,
veto;
const wxEventType eventType = event.GetEventType();
for ( size_t n = 0; n < WXSIZEOF(events); n++ )
{
const EventInfo& ei = events[n];
if ( eventType == ei.typeChanged )
{
nameEvent = wxT("Changed");
}
else if ( eventType == ei.typeChanging )
{
const int idx = event.GetOldSelection();
const wxBookCtrlBase * const
book = wxStaticCast(event.GetEventObject(), wxBookCtrlBase);
if ( idx != wxNOT_FOUND &&
book && book->GetPageText(idx) == VETO_PAGE_NAME )
{
if ( wxMessageBox
(
wxT("Are you sure you want to leave this page?\n")
wxT("(This demonstrates veto-ing)"),
wxT("Notebook sample"),
wxICON_QUESTION | wxYES_NO,
this
) != wxYES )
{
event.Veto();
veto = _T(" (vetoed)");
}
}
nameEvent = wxT("Changing");
}
else // skip end of the loop
{
continue;
}
nameControl = ei.name;
break;
}
static int s_num = 0;
wxLogMessage(wxT("Event #%d: %s: %s (%d) new sel %d, old %d%s"),
++s_num,
nameControl.c_str(),
nameEvent.c_str(),
eventType,
event.GetSelection(),
event.GetOldSelection(),
veto.c_str());
#if USE_LOG
m_text->SetInsertionPointEnd();
#endif
}
#if wxUSE_NOTEBOOK
BOOKEVENT(OnNotebook,wxNotebookEvent,"wxNotebook",wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,s_numNotebookEvents)
#endif
#if wxUSE_CHOICEBOOK
BOOKEVENT(OnChoicebook,wxChoicebookEvent,"wxChoicebook",wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED,wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING,s_numChoicebookEvents)
#endif
#if wxUSE_LISTBOOK
BOOKEVENT(OnListbook,wxListbookEvent,"wxListbook",wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED,wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING,s_numListbookEvents)
#endif

View File

@ -11,6 +11,7 @@
#include "wx/choicebk.h"
#include "wx/listbook.h"
#include "wx/treebook.h"
#include "wx/notebook.h"
#if wxUSE_LOG && !defined( __SMARTPHONE__ )
@ -28,12 +29,11 @@ public:
DECLARE_APP(MyApp)
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE);
MyFrame();
virtual ~MyFrame();
void OnType(wxCommandEvent& event);
@ -48,29 +48,47 @@ public:
void OnDeleteLastPage(wxCommandEvent& event);
void OnNextPage(wxCommandEvent& event);
void OnAddSubPage(wxCommandEvent& event);
void OnAddPageBefore(wxCommandEvent& event);
void OnBookCtrl(wxBookCtrlBaseEvent& event);
#if wxUSE_NOTEBOOK
void OnNotebook(wxNotebookEvent& event);
void OnNotebook(wxNotebookEvent& event) { OnBookCtrl(event); }
#endif
#if wxUSE_CHOICEBOOK
void OnChoicebook(wxChoicebookEvent& event);
void OnChoicebook(wxChoicebookEvent& event) { OnBookCtrl(event); }
#endif
#if wxUSE_LISTBOOK
void OnListbook(wxListbookEvent& event);
void OnListbook(wxListbookEvent& event) { OnBookCtrl(event); }
#endif
#if wxUSE_TREEBOOK
void OnTreebook(wxTreebookEvent& event) { OnBookCtrl(event); }
#endif
void OnIdle(wxIdleEvent& event);
wxBookCtrlBase *GetCurrentBook();
#if wxUSE_TREEBOOK
void OnUpdateTreeMenu(wxUpdateUIEvent& event);
#endif // wxUSE_TREEBOOK
wxBookCtrlBase *GetCurrentBook() const { return m_bookCtrl; }
private:
wxLog *m_logTargetOld;
int SelectFlag(int id, int nb, int lb, int chb);
void ShowCurrentBook();
void RecreateBooks();
void RecreateBook();
wxPanel *CreateNewPage() const;
int TranslateBookFlag(int nb, int lb, int chb, int tbk) const;
// Sample setup
int m_type;
enum BookType
{
Type_Notebook,
Type_Choicebook,
Type_Listbook,
Type_Treebook,
Type_Max
} m_type;
int m_orient;
bool m_chkShowImages;
bool m_multi;
@ -78,16 +96,7 @@ private:
// Controls
wxPanel *m_panel; // Panel containing notebook and other controls
#if wxUSE_NOTEBOOK
wxNotebook *m_notebook;
#endif
#if wxUSE_CHOICEBOOK
wxChoicebook *m_choicebook;
#endif
#if wxUSE_LISTBOOK
wxListbook *m_listbook;
#endif
wxBookCtrlBase *m_bookCtrl;
#if USE_LOG
// Log window
@ -103,10 +112,13 @@ private:
enum ID_COMMANDS
{
// these should be in the same order as Type_XXX elements above
ID_BOOK_NOTEBOOK = wxID_HIGHEST,
ID_BOOK_LISTBOOK,
ID_BOOK_CHOICEBOOK,
ID_BOOK_TREEBOOK,
ID_BOOK_MAX,
ID_ORIENT_DEFAULT,
ID_ORIENT_TOP,
ID_ORIENT_BOTTOM,
@ -120,9 +132,8 @@ enum ID_COMMANDS
ID_DELETE_CUR_PAGE,
ID_DELETE_LAST_PAGE,
ID_NEXT_PAGE,
ID_NOTEBOOK,
ID_LISTBOOK,
ID_CHOICEBOOK
ID_ADD_PAGE_BEFORE,
ID_ADD_SUB_PAGE
};
/*
@ -139,3 +150,7 @@ to decide what type of page it is.
// Pages that can be added by the user
#define INSERTED_PAGE_NAME wxT("Inserted ")
#define ADDED_PAGE_NAME wxT("Added ")
#define ADDED_PAGE_NAME_BEFORE wxT(" Inserted before ")
#define ADDED_SUB_PAGE_NAME wxT(" Inserted sub-page ")

View File

@ -19,6 +19,43 @@
<object class="wxNotebook" name="controls_notebook">
<usenotebooksizer>1</usenotebooksizer>
<size>550,200</size>
<object class="notebookpage">
<label>wxTreebook</label>
<object class="wxTreebook" name="controls_treebook">
<size>350,280</size>
<style>wxSUNKEN_BORDER</style>
<object class="treebookpage">
<label>Page 1</label>
<depth>0</depth>
<object class="wxButton" name="controls_treebook_button1">
<size>200,180</size>
<label>Button N1</label>
</object>
</object>
<object class="treebookpage">
<label>Empty Page 2</label>
<depth>1</depth>
</object>
<object class="treebookpage">
<label>Page 3</label>
<depth>2</depth>
<object class="wxButton" name="controls_treebook_button3">
<size>200,180</size>
<label>Button N3</label>
</object>
</object>
<object class="treebookpage">
<label>Page 4</label>
<depth>1</depth>
<object class="wxButton" name="controls_treebook_button4">
<size>200,180</size>
<label>Button N4</label>
</object>
</object>
</object>
</object>
<object class="notebookpage">
<label>wxBitmapButton</label>
<object class="wxPanel" name="bitmapbutton">

View File

@ -329,6 +329,8 @@
#define wxUSE_CHOICEBOOK 0
#define wxUSE_TREEBOOK 0
#define wxUSE_TAB_DIALOG 0
#define wxUSE_GRID 0

View File

@ -344,6 +344,8 @@
#define wxUSE_CHOICEBOOK 1
#define wxUSE_TREEBOOK 1
#define wxUSE_TAB_DIALOG 1
#define wxUSE_GRID 1

View File

@ -114,14 +114,17 @@ wxSize wxBookCtrlBase::DoGetBestSize() const
const size_t nCount = m_pages.size();
for ( size_t nPage = 0; nPage < nCount; nPage++ )
{
wxWindow *pPage = m_pages[nPage];
wxSize childBestSize(pPage->GetBestSize());
const wxWindow * const pPage = m_pages[nPage];
if( pPage )
{
wxSize childBestSize(pPage->GetBestSize());
if ( childBestSize.x > bestSize.x )
bestSize.x = childBestSize.x;
if ( childBestSize.x > bestSize.x )
bestSize.x = childBestSize.x;
if ( childBestSize.y > bestSize.y )
bestSize.y = childBestSize.y;
if ( childBestSize.y > bestSize.y )
bestSize.y = childBestSize.y;
}
}
// convert display area to window area, adding the size necessary for the
@ -142,7 +145,7 @@ wxBookCtrlBase::InsertPage(size_t nPage,
bool WXUNUSED(bSelect),
int WXUNUSED(imageId))
{
wxCHECK_MSG( page, false, _T("NULL page in wxBookCtrlBase::InsertPage()") );
wxCHECK_MSG( page || AllowNullPage(), false, _T("NULL page in wxBookCtrlBase::InsertPage()") );
wxCHECK_MSG( nPage <= m_pages.size(), false,
_T("invalid page index in wxBookCtrlBase::InsertPage()") );
@ -155,9 +158,10 @@ wxBookCtrlBase::InsertPage(size_t nPage,
bool wxBookCtrlBase::DeletePage(size_t nPage)
{
wxWindow *page = DoRemovePage(nPage);
if ( !page )
if ( !(page || AllowNullPage()) )
return false;
// delete NULL is harmless
delete page;
return true;

807
src/generic/treebkg.cpp Normal file
View File

@ -0,0 +1,807 @@
///////////////////////////////////////////////////////////////////////////////
// Name: src/generic/treebkg.cpp
// Purpose: generic implementation of wxTreebook
// Author: Evgeniy Tarassov, Vadim Zeitlin
// Modified by:
// Created: 2005-09-15
// RCS-ID: $Id$
// Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_TREEBOOK
#include "wx/treebook.h"
#include "wx/imaglist.h"
#include "wx/settings.h"
// ----------------------------------------------------------------------------
// various wxWidgets macros
// ----------------------------------------------------------------------------
// check that the page index is valid
#define IS_VALID_PAGE(nPage) ((nPage) < DoInternalGetPageCount())
// ----------------------------------------------------------------------------
// event table
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxTreebook, wxControl)
IMPLEMENT_DYNAMIC_CLASS(wxTreebookEvent, wxNotifyEvent)
const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING = wxNewEventType();
const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED = wxNewEventType();
const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED = wxNewEventType();
const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED = wxNewEventType();
const int wxID_TREEBOOKTREEVIEW = wxNewId();
BEGIN_EVENT_TABLE(wxTreebook, wxBookCtrlBase)
EVT_SIZE(wxTreebook::OnSize)
EVT_TREE_SEL_CHANGED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeSelectionChange)
EVT_TREE_ITEM_EXPANDED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
EVT_TREE_ITEM_COLLAPSED(wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
END_EVENT_TABLE()
// ============================================================================
// wxTreebook implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxTreebook creation
// ----------------------------------------------------------------------------
void wxTreebook::Init()
{
m_tree = NULL;
m_selection =
m_actualSelection = wxNOT_FOUND;
}
bool
wxTreebook::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
{
// Check the style flag to have either wxTBK_RIGHT or wxTBK_LEFT
if ( style & wxTBK_RIGHT )
{
wxASSERT_MSG( !(style & wxTBK_LEFT),
_T("RIGHT and LEFT can't be used together") );
}
else
{
style |= wxTBK_LEFT;
}
// no border for this control, it doesn't look nice together with the tree
style &= ~wxBORDER_MASK;
style |= wxBORDER_NONE;
if ( !wxControl::Create(parent, id, pos, size,
style, wxDefaultValidator, name) )
return false;
m_tree = new wxTreeCtrl
(
this,
wxID_TREEBOOKTREEVIEW,
wxDefaultPosition,
wxDefaultSize,
wxBORDER_SIMPLE |
wxTR_HAS_BUTTONS |
wxTR_HIDE_ROOT |
wxTR_LINES_AT_ROOT |
wxTR_SINGLE
);
m_tree->AddRoot(wxEmptyString); // label doesn't matter, it's hidden
#ifdef __WXMSW__
// see listbook.h for origins of that
// On XP with themes enabled the GetViewRect used in GetListSize to
// determine the space needed for the list view will incorrectly return
// (0,0,0,0) the first time. So send a pending event so OnSize will be
// called again after the window is ready to go. Technically we don't
// need to do this on non-XP windows, but if things are already sized
// correctly then nothing changes and so there is no harm.
wxSizeEvent evt;
GetEventHandler()->AddPendingEvent(evt);
#endif
return true;
}
// insert a new page just before the pagePos
bool wxTreebook::InsertPage(size_t pagePos,
wxWindow *page,
const wxString& text,
bool bSelect,
int imageId)
{
return DoInsertPage(pagePos, page, text, bSelect, imageId);
}
bool wxTreebook::AddSubPage(size_t pagePos,
wxWindow *page,
const wxString& text,
bool bSelect,
int imageId)
{
return DoInsertSubPage(pagePos, page, text, bSelect, imageId);
}
bool wxTreebook::AddPage(wxWindow *page, const wxString& text, bool bSelect,
int imageId)
{
return DoInsertPage(m_treeIds.GetCount(), page, text, bSelect, imageId);
}
// insertion time is linear to the number of top-pages
bool wxTreebook::AddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
{
return DoAddSubPage(page, text, bSelect, imageId);
}
bool wxTreebook::DoInsertPage(size_t pagePos,
wxWindow *page,
const wxString& text,
bool bSelect,
int imageId)
{
wxCHECK_MSG( pagePos <= DoInternalGetPageCount(), false,
wxT("Invalid treebook page position") );
if ( !wxBookCtrlBase::InsertPage(pagePos, page, text, bSelect, imageId) )
return false;
wxTreeItemId newId;
if ( pagePos == DoInternalGetPageCount() )
{
// append the page to the end
wxTreeItemId rootId = m_tree->GetRootItem();
newId = m_tree->AppendItem(rootId, text, imageId);
}
else // insert the new page before the given one
{
wxTreeItemId nodeId = m_treeIds[pagePos];
wxTreeItemId previousId = m_tree->GetPrevSibling(nodeId);
wxTreeItemId parentId = m_tree->GetItemParent(nodeId);
if ( previousId.IsOk() )
{
// insert before the sibling - previousId
newId = m_tree->InsertItem(parentId, previousId, text, imageId);
}
else // no prev siblings -- insert as a first child
{
wxASSERT_MSG( parentId.IsOk(), wxT( "Tree has no root node?" ) );
newId = m_tree->PrependItem(parentId, text, imageId);
}
}
if ( !newId.IsOk() )
{
//something wrong -> cleaning and returning with false
(void)wxBookCtrlBase::DoRemovePage(pagePos);
wxFAIL_MSG( wxT("Failed to insert treebook page") );
return false;
}
DoInternalAddPage(pagePos, page, newId);
DoUpdateSelection(bSelect, pagePos);
return true;
}
bool wxTreebook::DoAddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
{
wxTreeItemId rootId = m_tree->GetRootItem();
wxTreeItemId lastNodeId = m_tree->GetLastChild(rootId);
wxCHECK_MSG( lastNodeId.IsOk(), false,
_T("Can't insert sub page when there are no pages") );
// now calculate its position (should we save/update it too?)
size_t newPos = m_tree->GetCount() -
(m_tree->GetChildrenCount(lastNodeId, true) + 1);
return DoInsertSubPage(newPos, page, text, bSelect, imageId);
}
bool wxTreebook::DoInsertSubPage(size_t pagePos,
wxTreebookPage *page,
const wxString& text,
bool bSelect,
int imageId)
{
wxTreeItemId parentId = DoInternalGetPage(pagePos);
wxCHECK_MSG( parentId.IsOk(), false, wxT("invalid tree item") );
size_t newPos = pagePos + m_tree->GetChildrenCount(parentId, true) + 1;
wxASSERT_MSG( newPos <= DoInternalGetPageCount(),
wxT("Internal error in tree insert point calculation") );
if ( !wxBookCtrlBase::InsertPage(newPos, page, text, bSelect, imageId) )
return false;
wxTreeItemId newId = m_tree->AppendItem(parentId, text, imageId);
if ( !newId.IsOk() )
{
(void)wxBookCtrlBase::DoRemovePage(newPos);
wxFAIL_MSG( wxT("Failed to insert treebook page") );
return false;
}
DoInternalAddPage(newPos, page, newId);
DoUpdateSelection(bSelect, newPos);
return true;
}
bool wxTreebook::DeletePage(size_t pagePos)
{
wxCHECK_MSG( IS_VALID_PAGE(pagePos), false, wxT("Invalid tree index") );
wxTreebookPage *oldPage = DoRemovePage(pagePos);
if ( !oldPage )
return false;
delete oldPage;
return true;
}
wxTreebookPage *wxTreebook::DoRemovePage(size_t pagePos)
{
wxTreeItemId pageId = DoInternalGetPage(pagePos);
wxCHECK_MSG( pageId.IsOk(), NULL, wxT("Invalid tree index") );
wxTreebookPage * oldPage = GetPage(pagePos);
size_t subCount = m_tree->GetChildrenCount(pageId, true);
wxASSERT_MSG ( IS_VALID_PAGE(pagePos + subCount),
wxT("Internal error in wxTreebook::DoRemovePage") );
// here we are going to delete ALL the pages in the range
// [pagePos, pagePos + subCount] -- the page and its children
// deleting all the pages from the base class
for ( size_t i = 0; i <= subCount; ++i )
{
wxTreebookPage *page = wxBookCtrlBase::DoRemovePage(pagePos);
// don't delete the page itself though -- it will be deleted in
// DeletePage() when we return
if ( i )
{
delete page;
}
}
DoInternalRemovePageRange(pagePos, subCount);
m_tree->DeleteChildren( pageId );
m_tree->Delete( pageId );
return oldPage;
}
bool wxTreebook::DeleteAllPages()
{
wxBookCtrlBase::DeleteAllPages();
m_treeIds.Clear();
m_selection =
m_actualSelection = wxNOT_FOUND;
m_tree->DeleteChildren(m_tree->GetRootItem());
return true;
}
void wxTreebook::DoInternalAddPage(size_t newPos,
wxTreebookPage *page,
wxTreeItemId pageId)
{
wxASSERT_MSG( newPos <= m_treeIds.GetCount(), wxT("Ivalid index passed to wxTreebook::DoInternalAddPage") );
// hide newly inserted page initially (it will be shown when selected)
if ( page )
page->Hide();
if ( newPos == m_treeIds.GetCount() )
{
// append
m_treeIds.Add(pageId);
}
else // insert
{
m_treeIds.Insert(pageId, newPos);
if ( m_selection != wxNOT_FOUND && newPos <= (size_t)m_selection )
{
// selection has been moved one unit toward the end
++m_selection;
if ( m_actualSelection != wxNOT_FOUND )
++m_actualSelection;
}
else if ( m_actualSelection != wxNOT_FOUND &&
newPos <= (size_t)m_actualSelection )
{
DoSetSelection(m_selection);
}
}
}
void wxTreebook::DoInternalRemovePageRange(size_t pagePos, size_t subCount)
{
// Attention: this function is only for a situation when we delete a node
// with all its children so pagePos is the node's index and subCount is the
// node children count
wxASSERT_MSG( pagePos + subCount < m_treeIds.GetCount(),
wxT("Ivalid page index") );
wxTreeItemId pageId = m_treeIds[pagePos];
m_treeIds.RemoveAt(pagePos, subCount + 1);
if ( m_selection != wxNOT_FOUND )
{
if ( (size_t)m_selection > pagePos + subCount)
{
// selection is far after the deleted page, so just update the index and move on
m_selection -= 1 + subCount;
if ( m_actualSelection != wxNOT_FOUND)
{
m_actualSelection -= subCount + 1;
}
}
else if ( (size_t)m_selection >= pagePos )
{
// as selected page is going to be deleted, try to select the next
// sibling if exists, if not then the parent
wxTreeItemId nodeId = m_tree->GetNextSibling(pageId);
m_selection = wxNOT_FOUND;
m_actualSelection = wxNOT_FOUND;
if ( nodeId.IsOk() )
{
// selecting next siblings
m_tree->SelectItem(nodeId);
}
else // no next sibling, select the parent
{
wxTreeItemId parentId = m_tree->GetItemParent(pageId);
if ( parentId.IsOk() && parentId != m_tree->GetRootItem() )
{
m_tree->SelectItem(parentId);
}
else // parent is root
{
// we can't select it as it's hidden
DoUpdateSelection(false, wxNOT_FOUND);
}
}
}
else if ( m_actualSelection != wxNOT_FOUND &&
(size_t)m_actualSelection >= pagePos )
{
// nothing to do -- selection is before the deleted node, but
// actually shown page (the first (sub)child with page != NULL) is
// already deleted
m_actualSelection = m_selection;
DoSetSelection(m_selection);
}
//else: nothing to do -- selection is before the deleted node
}
else
{
DoUpdateSelection(false, wxNOT_FOUND);
}
}
void wxTreebook::DoUpdateSelection(bool bSelect, int newPos)
{
int newSelPos;
if ( bSelect )
{
newSelPos = newPos;
}
else if ( m_selection == wxNOT_FOUND && DoInternalGetPageCount() > 0 )
{
newSelPos = 0;
}
else
{
newSelPos = wxNOT_FOUND;
}
if ( newSelPos != wxNOT_FOUND )
{
SetSelection((size_t)newSelPos);
}
}
wxTreeItemId wxTreebook::DoInternalGetPage(size_t pagePos) const
{
if ( pagePos >= m_treeIds.GetCount() )
{
// invalid position but ok here, in this internal function, don't assert
// (the caller will do it)
return wxTreeItemId();
}
return m_treeIds[pagePos];
}
int wxTreebook::DoInternalFindPageById(wxTreeItemId pageId) const
{
const size_t count = m_treeIds.GetCount();
for ( size_t i = 0; i < count; ++i )
{
if ( m_treeIds[i] == pageId )
return i;
}
return wxNOT_FOUND;
}
bool wxTreebook::IsNodeExpanded(size_t pagePos) const
{
wxTreeItemId pageId = DoInternalGetPage(pagePos);
wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
return m_tree->IsExpanded(pageId);
}
bool wxTreebook::ExpandNode(size_t pagePos, bool expand)
{
wxTreeItemId pageId = DoInternalGetPage(pagePos);
wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
if ( expand )
{
m_tree->Expand( pageId );
}
else // collapse
{
m_tree->Collapse( pageId );
// rely on the events generated by wxTreeCtrl to update selection
}
return true;
}
int wxTreebook::GetPageParent(size_t pagePos) const
{
wxTreeItemId nodeId = DoInternalGetPage( pagePos );
wxCHECK_MSG( nodeId.IsOk(), wxNOT_FOUND, wxT("Invalid page index spacified!") );
const wxTreeItemId parent = m_tree->GetItemParent( nodeId );
return parent.IsOk() ? DoInternalFindPageById(parent) : wxNOT_FOUND;
}
bool wxTreebook::SetPageText(size_t n, const wxString& strText)
{
wxTreeItemId pageId = DoInternalGetPage(n);
wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
m_tree->SetItemText(pageId, strText);
return true;
}
wxString wxTreebook::GetPageText(size_t n) const
{
wxTreeItemId pageId = DoInternalGetPage(n);
wxCHECK_MSG( pageId.IsOk(), wxString(), wxT("invalid tree item") );
return m_tree->GetItemText(pageId);
}
int wxTreebook::GetPageImage(size_t n) const
{
wxTreeItemId pageId = DoInternalGetPage(n);
wxCHECK_MSG( pageId.IsOk(), wxNOT_FOUND, wxT("invalid tree item") );
return m_tree->GetItemImage(pageId);
}
bool wxTreebook::SetPageImage(size_t n, int imageId)
{
wxTreeItemId pageId = DoInternalGetPage(n);
wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
m_tree->SetItemImage(pageId, imageId);
return true;
}
wxSize wxTreebook::CalcSizeFromPage(const wxSize& sizePage) const
{
const wxSize sizeTree = GetTreeSize();
wxSize size = sizePage;
size.x += sizeTree.x;
return size;
}
int wxTreebook::GetSelection() const
{
return m_selection;
}
int wxTreebook::SetSelection(size_t pagePos)
{
if ( (size_t)m_selection != pagePos )
return DoSetSelection(pagePos);
return m_selection;
}
int wxTreebook::DoSetSelection(size_t pagePos)
{
wxCHECK_MSG( IS_VALID_PAGE(pagePos), wxNOT_FOUND,
wxT("invalid page index in wxListbook::SetSelection()") );
wxASSERT_MSG( GetPageCount() == DoInternalGetPageCount(),
wxT("wxTreebook logic error: m_treeIds and m_pages not in sync!"));
const int oldSel = m_selection;
wxTreebookEvent event(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, m_windowId);
event.SetEventObject(this);
event.SetSelection(pagePos);
event.SetOldSelection(m_selection);
// don't send the event if the old and new pages are the same; do send it
// otherwise and be prepared for it to be vetoed
if ( (int)pagePos == m_selection ||
!GetEventHandler()->ProcessEvent(event) ||
event.IsAllowed() )
{
// hide the previously shown page
wxTreebookPage * const oldPage = DoGetCurrentPage();
if ( oldPage )
oldPage->Hide();
// then show the new one
m_selection = pagePos;
wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
if ( !page )
{
// find the next page suitable to be shown: the first (grand)child
// of this one with a non-NULL associated page
wxTreeItemId childId = m_treeIds[pagePos];
m_actualSelection = pagePos;
while ( !page && childId.IsOk() )
{
wxTreeItemIdValue cookie;
childId = m_tree->GetFirstChild( childId, cookie );
if ( childId.IsOk() )
{
page = wxBookCtrlBase::GetPage(++m_actualSelection);
}
}
wxASSERT_MSG( page, wxT("no page to show found!") );
}
if ( page )
{
page->SetSize(GetPageRect());
page->Show();
}
m_tree->SelectItem(DoInternalGetPage(pagePos));
// notify about the (now completed) page change
event.SetEventType(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED);
(void)GetEventHandler()->ProcessEvent(event);
}
else // page change vetoed
{
// tree selection might have already had changed
m_tree->SelectItem(DoInternalGetPage(oldSel));
}
return oldSel;
}
void wxTreebook::SetImageList(wxImageList *imageList)
{
wxBookCtrlBase::SetImageList(imageList);
m_tree->SetImageList(imageList);
}
void wxTreebook::AssignImageList(wxImageList *imageList)
{
wxBookCtrlBase::AssignImageList(imageList);
m_tree->SetImageList(imageList);
}
// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------
void wxTreebook::OnTreeSelectionChange(wxTreeEvent& event)
{
wxTreeItemId newId = event.GetItem();
if ( (m_selection == wxNOT_FOUND &&
(!newId.IsOk() || newId == m_tree->GetRootItem())) ||
(m_selection != wxNOT_FOUND && newId == m_treeIds[m_selection]) )
{
// this event can only come when we modify the tree selection ourselves
// so we should simply ignore it
return;
}
int newPos = DoInternalFindPageById(newId);
if ( newPos != wxNOT_FOUND )
SetSelection( newPos );
}
void wxTreebook::OnTreeNodeExpandedCollapsed(wxTreeEvent & event)
{
wxTreeItemId nodeId = event.GetItem();
if ( !nodeId.IsOk() || nodeId == m_tree->GetRootItem() )
return;
int pagePos = DoInternalFindPageById(nodeId);
wxCHECK_RET( pagePos != wxNOT_FOUND, wxT("Internal problem in wxTreebook!..") );
wxTreebookEvent ev(m_tree->IsExpanded(nodeId)
? wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED
: wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED,
m_windowId);
ev.SetSelection(pagePos);
ev.SetOldSelection(pagePos);
ev.SetEventObject(this);
GetEventHandler()->ProcessEvent(ev);
}
// ----------------------------------------------------------------------------
// wxTreebook geometry management
// ----------------------------------------------------------------------------
wxSize wxTreebook::GetTreeSize() const
{
const wxSize sizeClient = GetClientSize(),
sizeBorder = m_tree->GetSize() - m_tree->GetClientSize(),
sizeTree = m_tree->GetBestSize() + sizeBorder;
wxSize size;
size.x = sizeTree.x;
size.y = sizeClient.y;
return size;
}
wxRect wxTreebook::GetPageRect() const
{
const wxSize sizeTree = m_tree->GetSize();
wxPoint pt;
wxRect rectPage(pt, GetClientSize());
switch ( GetWindowStyle() & wxTBK_ALIGN_MASK )
{
default:
wxFAIL_MSG( _T("unexpected wxTreebook alignment") );
// fall through
case wxTBK_LEFT:
rectPage.x = sizeTree.x; // + MARGIN;
// fall through
case wxTBK_RIGHT:
rectPage.width -= sizeTree.x; // + MARGIN;
break;
}
return rectPage;
}
void wxTreebook::OnSize(wxSizeEvent& event)
{
event.Skip();
if ( !m_tree )
{
// we're not fully created yet
return;
}
// resize the list control and the page area to fit inside our new size
const wxSize sizeClient = GetClientSize(),
sizeBorder = m_tree->GetSize() - m_tree->GetClientSize(),
sizeTree = GetTreeSize();
m_tree->SetClientSize( sizeTree.x - sizeBorder.x, sizeTree.y - sizeBorder.y );
const wxSize sizeNew = m_tree->GetSize();
wxPoint posTree;
switch ( GetWindowStyle() & wxTBK_ALIGN_MASK )
{
default:
wxFAIL_MSG( _T("unexpected wxTreebook alignment") );
// fall through
case wxTBK_LEFT:
// posTree is already ok
break;
case wxTBK_RIGHT:
posTree.x = sizeClient.x - sizeNew.x;
break;
}
if ( m_tree->GetPosition() != posTree )
m_tree->Move(posTree);
// resize the currently shown page
wxTreebookPage *page = DoGetCurrentPage();
if ( page )
{
wxRect rectPage = GetPageRect();
page->SetSize(rectPage);
}
}
wxTreebookPage * wxTreebook::DoGetCurrentPage() const
{
if ( m_selection == wxNOT_FOUND )
return NULL;
wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
if ( !page && m_actualSelection != wxNOT_FOUND )
{
page = wxBookCtrlBase::GetPage(m_actualSelection);
}
return page;
}
#endif // wxUSE_TREEBOOK

134
src/xrc/xh_treebk.cpp Normal file
View File

@ -0,0 +1,134 @@
/////////////////////////////////////////////////////////////////////////////
// Name: xh_treebk.cpp
// Purpose: XRC resource handler for wxTreebook
// Author: Evgeniy Tarassov
// Created: 2005/09/28
// RCS-ID: $Id$
// Copyright: (c) 2005 TT-Solutions <vadim@tt-solutions.com>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_XRC && wxUSE_TREEBOOK
#include "wx/xrc/xh_treebk.h"
#include "wx/treebook.h"
#include "wx/imaglist.h"
#include "wx/log.h"
IMPLEMENT_DYNAMIC_CLASS(wxTreebookXmlHandler, wxXmlResourceHandler)
wxTreebookXmlHandler::wxTreebookXmlHandler()
: wxXmlResourceHandler(), m_isInside(false), m_tbk(NULL), m_treeContext()
{
XRC_ADD_STYLE(wxTBK_DEFAULT);
XRC_ADD_STYLE(wxTBK_LEFT);
XRC_ADD_STYLE(wxTBK_RIGHT);
AddWindowStyles();
}
bool wxTreebookXmlHandler::CanHandle(wxXmlNode *node)
{
return ((!m_isInside && IsOfClass(node, wxT("wxTreebook"))) ||
(m_isInside && IsOfClass(node, wxT("treebookpage"))));
}
wxObject *wxTreebookXmlHandler::DoCreateResource()
{
if (m_class == wxT("wxTreebook"))
{
XRC_MAKE_INSTANCE(tbk, wxTreebook)
tbk->Create(m_parentAsWindow,
GetID(),
GetPosition(), GetSize(),
GetStyle(wxT("style")),
GetName());
wxTreebook * old_par = m_tbk;
m_tbk = tbk;
bool old_ins = m_isInside;
m_isInside = true;
wxArrayTbkPageIndexes old_treeContext = m_treeContext;
m_treeContext.Clear();
CreateChildren(m_tbk, true/*only this handler*/);
m_treeContext = old_treeContext;
m_isInside = old_ins;
m_tbk = old_par;
return tbk;
}
// else ( m_class == wxT("treebookpage") )
wxXmlNode *n = GetParamNode(wxT("object"));
wxWindow *wnd = NULL;
if ( !n )
n = GetParamNode(wxT("object_ref"));
if (n)
{
bool old_ins = m_isInside;
m_isInside = false;
wxObject *item = CreateResFromNode(n, m_tbk, NULL);
m_isInside = old_ins;
wnd = wxDynamicCast(item, wxWindow);
if (wnd == NULL && item != NULL)
wxLogError(wxT("Error in resource: control within treebook's <page> tag is not a window."));
}
size_t depth = GetLong( wxT("depth") );
if( depth <= m_treeContext.Count() )
{
// first prepare the icon
int imgIndex = wxNOT_FOUND;
if ( HasParam(wxT("bitmap")) )
{
wxBitmap bmp = GetBitmap(wxT("bitmap"), wxART_OTHER);
wxImageList *imgList = m_tbk->GetImageList();
if ( imgList == NULL )
{
imgList = new wxImageList( bmp.GetWidth(), bmp.GetHeight() );
m_tbk->AssignImageList( imgList );
}
imgIndex = imgList->Add(bmp);
}
// then add the page to the corresponding parent
if( depth < m_treeContext.Count() )
m_treeContext.RemoveAt(depth, m_treeContext.Count() - depth );
if( depth == 0)
{
m_tbk->AddPage(wnd,
GetText(wxT("label")), GetBool(wxT("selected")), imgIndex);
}
else
{
m_tbk->AddSubPage(m_treeContext.Item(depth - 1), wnd,
GetText(wxT("label")), GetBool(wxT("selected")), imgIndex);
}
m_treeContext.Add( m_tbk->GetPageCount() - 1);
}
else
wxLogError(wxT("Error in resource. wxTreebookPage has an invalid depth."));
return wnd;
}
#endif // wxUSE_XRC && wxUSE_TREEBOOK

View File

@ -85,6 +85,9 @@ void wxXmlResource::InitAllHandlers()
#endif
#if wxUSE_CHOICEBOOK
AddHandler(new wxChoicebookXmlHandler);
#endif
#if wxUSE_TREEBOOK
AddHandler(new wxTreebookXmlHandler);
#endif
AddHandler(new wxTextCtrlXmlHandler);
#if wxUSE_LISTBOX