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>
wx/tooltip.h
wx/toplevel.h
wx/treebase.h
+ wx/treebook.h
wx/treectrl.h
wx/valgen.h
wx/vidmode.h
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
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
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
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
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
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)
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)
All (GUI):
+- added wxTreeBook
- added wxDialog::SetEscapeId()
- wxItemContainerImmutable::FindString unified (affects wxRadioBox, wxListBox,
wxComboBox and wxChoice)
\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}
\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}
\input toolbar.tex
\input tooltip.tex
\input tlw.tex
+\input treebook.tex
+\input treebookevent.tex
\input treectrl.tex
\input treeevt.tex
\input treedata.tex
--- /dev/null
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 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}
+
--- /dev/null
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% 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}
+
--- /dev/null
+\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}
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.
}
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;
// 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.
//
// 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.
//
// 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.
//
// 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.
//
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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_
// 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.
//
#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"
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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_
+
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
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
#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"));
-
- 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"));
+ 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 *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"));
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);
-
- m_imageList
- = new wxImageList( imageSize.GetWidth(), imageSize.GetHeight() );
-
- m_imageList->Add
- (
- wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, imageSize)
- );
+ const wxSize imageSize(32, 32);
- m_imageList->Add
- (
- wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, imageSize)
- );
+ 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_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
m_sizerFrame->Add(m_text, 1, wxEXPAND);
#endif // USE_LOG
- RecreateBooks();
+ RecreateBook();
m_panel->SetSizer(m_sizerFrame);
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 );
+#if wxUSE_CHOICEBOOK
+ #define CASE_CHOICEBOOK(x) case Type_Choicebook: x; break;
+#else
+ #define CASE_CHOICEBOOK(x)
#endif
+
#if wxUSE_LISTBOOK
- RECREATE( wxListbook , ID_LISTBOOK , listbook , m_listbook );
+ #define CASE_LISTBOOK(x) case Type_Listbook: x; break;
+#else
+ #define CASE_LISTBOOK(x)
#endif
-#if wxUSE_CHOICEBOOK
- RECREATE( wxChoicebook , ID_CHOICEBOOK , choicebook , m_choicebook );
+
+#if wxUSE_TREEBOOK
+ #define CASE_TREEBOOK(x) case Type_Treebook: x; break;
+#else
+ #define CASE_TREEBOOK(x)
#endif
- ShowCurrentBook();
+#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;
}
-wxBookCtrlBase *MyFrame::GetCurrentBook()
+void MyFrame::RecreateBook()
{
- switch (m_type)
+#define SELECT_FLAG(flag) \
+ TranslateBookFlag(wxNB_##flag, wxCHB_##flag, wxLB_##flag, wxTBK_##flag)
+
+ int flags;
+ switch ( m_orient )
{
-#if wxUSE_NOTEBOOK
- case ID_BOOK_NOTEBOOK: return m_notebook;
-#endif
-#if wxUSE_LISTBOOK
- case ID_BOOK_LISTBOOK: return m_listbook;
-#endif
-#if wxUSE_CHOICEBOOK
- case ID_BOOK_CHOICEBOOK: return m_choicebook;
-#endif
+ 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);
}
- return NULL;
-}
-void MyFrame::ShowCurrentBook()
-{
- switch(m_type)
+#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 )
{
-#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;
-#endif
+ 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)
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);
+
+ if ( m_bookCtrl )
+ m_sizerFrame->Hide(m_bookCtrl);
- m_type = event.GetId();
+ RecreateBook();
+}
- if (currBook)
- m_sizerFrame->Hide(currBook);
+#if wxUSE_TREEBOOK
- ShowCurrentBook();
+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."));
}
Close();
}
-void MyFrame::OnAddPage(wxCommandEvent& WXUNUSED(event))
+wxPanel *MyFrame::CreateNewPage() const
{
- static unsigned s_pageAdded = 0;
+ 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))
+{
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))
{
}
}
-#if USE_LOG
- #define BOOKEVENT_LOG m_text->SetInsertionPointEnd();
-#else
- #define BOOKEVENT_LOG
-#endif
-
-#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 \
-}
-
+void MyFrame::OnBookCtrl(wxBookCtrlBaseEvent& event)
+{
+ static const struct EventInfo
+ {
+ wxEventType typeChanged,
+ typeChanging;
+ const wxChar *name;
+ } events[] =
+ {
#if wxUSE_NOTEBOOK
-BOOKEVENT(OnNotebook,wxNotebookEvent,"wxNotebook",wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,s_numNotebookEvents)
-#endif
+ {
+ wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+ wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
+ _T("wxNotebook")
+ },
+#endif // wxUSE_NOTEBOOK
#if wxUSE_CHOICEBOOK
-BOOKEVENT(OnChoicebook,wxChoicebookEvent,"wxChoicebook",wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED,wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING,s_numChoicebookEvents)
-#endif
+ {
+ wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGED,
+ wxEVT_COMMAND_CHOICEBOOK_PAGE_CHANGING,
+ _T("wxChoicebook")
+ },
+#endif // wxUSE_CHOICEBOOK
#if wxUSE_LISTBOOK
-BOOKEVENT(OnListbook,wxListbookEvent,"wxListbook",wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED,wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING,s_numListbookEvents)
+ {
+ 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
+ };
+
+
+ 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
+}
+
#include "wx/choicebk.h"
#include "wx/listbook.h"
+#include "wx/treebook.h"
#include "wx/notebook.h"
#if wxUSE_LOG && !defined( __SMARTPHONE__ )
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);
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;
// 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
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,
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
};
/*
// 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 ")
+
+
<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">
#define wxUSE_CHOICEBOOK 0
+#define wxUSE_TREEBOOK 0
+
#define wxUSE_TAB_DIALOG 0
#define wxUSE_GRID 0
#define wxUSE_CHOICEBOOK 1
+#define wxUSE_TREEBOOK 1
+
#define wxUSE_TAB_DIALOG 1
#define wxUSE_GRID 1
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
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()") );
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;
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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
#endif
#if wxUSE_CHOICEBOOK
AddHandler(new wxChoicebookXmlHandler);
+#endif
+#if wxUSE_TREEBOOK
+ AddHandler(new wxTreebookXmlHandler);
#endif
AddHandler(new wxTextCtrlXmlHandler);
#if wxUSE_LISTBOX