1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/treebook.h
3 // Purpose:     wxTreebook: wxNotebook-like control presenting pages in a tree
4 // Author:      Evgeniy Tarassov, Vadim Zeitlin
5 // Modified by:
6 // Created:     2005-09-15
7 // RCS-ID:      $Id: treebook.h 49804 2007-11-10 01:09:42Z VZ $
8 // Copyright:   (c) 2005 Vadim Zeitlin <vadim@wxwidgets.org>
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_TREEBOOK_H_
13 #define _WX_TREEBOOK_H_
14 
15 #include "wx/defs.h"
16 
17 #if wxUSE_TREEBOOK
18 
19 #include "wx/bookctrl.h"
20 #include "wx/treectrl.h"        // for wxArrayTreeItemIds
21 #include "wx/containr.h"
22 
23 typedef wxWindow wxTreebookPage;
24 
25 class WXDLLIMPEXP_FWD_CORE wxTreeEvent;
26 
27 // ----------------------------------------------------------------------------
28 // wxTreebook
29 // ----------------------------------------------------------------------------
30 
31 class WXDLLEXPORT wxTreebook : public wxBookCtrlBase
32 {
33 public:
34     // Constructors and such
35     // ---------------------
36 
37     // Default ctor doesn't create the control, use Create() afterwards
wxTreebook()38     wxTreebook()
39     {
40         Init();
41     }
42 
43     // This ctor creates the tree book control
44     wxTreebook(wxWindow *parent,
45                wxWindowID id,
46                const wxPoint& pos = wxDefaultPosition,
47                const wxSize& size = wxDefaultSize,
48                long style = wxBK_DEFAULT,
49                const wxString& name = wxEmptyString)
50     {
51         Init();
52 
53         (void)Create(parent, id, pos, size, style, name);
54     }
55 
56     // Really creates the control
57     bool Create(wxWindow *parent,
58                 wxWindowID id,
59                 const wxPoint& pos = wxDefaultPosition,
60                 const wxSize& size = wxDefaultSize,
61                 long style = wxBK_DEFAULT,
62                 const wxString& name = wxEmptyString);
63 
64 
65     // Page insertion operations
66     // -------------------------
67 
68     // Notice that page pointer may be NULL in which case the next non NULL
69     // page (usually the first child page of a node) is shown when this page is
70     // selected
71 
72     // Inserts a new page just before the page indicated by page.
73     // The new page is placed on the same level as page.
74     virtual bool InsertPage(size_t pos,
75                             wxWindow *page,
76                             const wxString& text,
77                             bool bSelect = false,
78                             int imageId = wxNOT_FOUND);
79 
80     // Inserts a new sub-page to the end of children of the page at given pos.
81     virtual bool InsertSubPage(size_t pos,
82                                wxWindow *page,
83                                const wxString& text,
84                                bool bSelect = false,
85                                int imageId = wxNOT_FOUND);
86 
87     // Adds a new page at top level after all other pages.
88     virtual bool AddPage(wxWindow *page,
89                          const wxString& text,
90                          bool bSelect = false,
91                          int imageId = wxNOT_FOUND);
92 
93     // Adds a new child-page to the last top-level page inserted.
94     // Useful when constructing 1 level tree structure.
95     virtual bool AddSubPage(wxWindow *page,
96                             const wxString& text,
97                             bool bSelect = false,
98                             int imageId = wxNOT_FOUND);
99 
100     // Deletes the page and ALL its children. Could trigger page selection
101     // change in a case when selected page is removed. In that case its parent
102     // is selected (or the next page if no parent).
103     virtual bool DeletePage(size_t pos);
104 
105 
106     // Tree operations
107     // ---------------
108 
109     // Gets the page node state -- node is expanded or collapsed
110     virtual bool IsNodeExpanded(size_t pos) const;
111 
112     // Expands or collapses the page node. Returns the previous state.
113     // May generate page changing events (if selected page
114     // is under the collapsed branch, then parent is autoselected).
115     virtual bool ExpandNode(size_t pos, bool expand = true);
116 
117     // shortcut for ExpandNode(pos, false)
CollapseNode(size_t pos)118     bool CollapseNode(size_t pos) { return ExpandNode(pos, false); }
119 
120     // get the parent page or wxNOT_FOUND if this is a top level page
121     int GetPageParent(size_t pos) const;
122 
123     // the tree control we use for showing the pages index tree
GetTreeCtrl()124     wxTreeCtrl* GetTreeCtrl() const { return (wxTreeCtrl*)m_bookctrl; }
125 
126 
127     // Standard operations inherited from wxBookCtrlBase
128     // -------------------------------------------------
129 
130     virtual int GetSelection() const;
131     virtual bool SetPageText(size_t n, const wxString& strText);
132     virtual wxString GetPageText(size_t n) const;
133     virtual int GetPageImage(size_t n) const;
134     virtual bool SetPageImage(size_t n, int imageId);
135     virtual wxSize CalcSizeFromPage(const wxSize& sizePage) const;
SetSelection(size_t n)136     virtual int SetSelection(size_t n) { return DoSetSelection(n, SetSelection_SendEvent); }
ChangeSelection(size_t n)137     virtual int ChangeSelection(size_t n) { return DoSetSelection(n); }
138     virtual int HitTest(const wxPoint& pt, long *flags = NULL) const;
139     virtual void SetImageList(wxImageList *imageList);
140     virtual void AssignImageList(wxImageList *imageList);
141     virtual bool DeleteAllPages();
142 
143 protected:
144     // Implementation of a page removal. See DeletPage for comments.
145     wxTreebookPage *DoRemovePage(size_t pos);
146 
147     // This subclass of wxBookCtrlBase accepts NULL page pointers (empty pages)
AllowNullPage()148     virtual bool AllowNullPage() const { return true; }
149 
150     // event handlers
151     void OnTreeSelectionChange(wxTreeEvent& event);
152     void OnTreeNodeExpandedCollapsed(wxTreeEvent& event);
153 
154     // array of page ids and page windows
155     wxArrayTreeItemIds m_treeIds;
156 
157     // the currently selected page or wxNOT_FOUND if none
158     int m_selection;
159 
160     // in the situation when m_selection page is not wxNOT_FOUND but page is
161     // NULL this is the first (sub)child that has a non-NULL page
162     int m_actualSelection;
163 
164 private:
165     // common part of all constructors
166     void Init();
167 
168     // The real implementations of page insertion functions
169     // ------------------------------------------------------
170     // All DoInsert/Add(Sub)Page functions add the page into :
171     // - the base class
172     // - the tree control
173     // - update the index/TreeItemId corespondance array
174     bool DoInsertPage(size_t pos,
175                       wxWindow *page,
176                       const wxString& text,
177                       bool bSelect = false,
178                       int imageId = wxNOT_FOUND);
179     bool DoInsertSubPage(size_t pos,
180                          wxWindow *page,
181                          const wxString& text,
182                          bool bSelect = false,
183                          int imageId = wxNOT_FOUND);
184     bool DoAddSubPage(wxWindow *page,
185                          const wxString& text,
186                          bool bSelect = false,
187                          int imageId = wxNOT_FOUND);
188 
189     // Sets selection in the tree control and updates the page being shown.
190     int DoSetSelection(size_t pos, int flags = 0);
191 
192     // Returns currently shown page. In a case when selected the node
193     // has empty (NULL) page finds first (sub)child with not-empty page.
194     wxTreebookPage *DoGetCurrentPage() const;
195 
196     // Does the selection update. Called from page insertion functions
197     // to update selection if the selected page was pushed by the newly inserted
198     void DoUpdateSelection(bool bSelect, int page);
199 
200 
201     // Operations on the internal private members of the class
202     // -------------------------------------------------------
203     // Returns the page TreeItemId for the page.
204     // Or, if the page index is incorrect, a fake one (fakePage.IsOk() == false)
205     wxTreeItemId DoInternalGetPage(size_t pos) const;
206 
207     // Linear search for a page with the id specified. If no page
208     // found wxNOT_FOUND is returned. The function is used when we catch an event
209     // from m_tree (wxTreeCtrl) component.
210     int DoInternalFindPageById(wxTreeItemId page) const;
211 
212     // Updates page and wxTreeItemId correspondance.
213     void DoInternalAddPage(size_t newPos, wxWindow *page, wxTreeItemId pageId);
214 
215     // Removes the page from internal structure.
DoInternalRemovePage(size_t pos)216     void DoInternalRemovePage(size_t pos)
217         { DoInternalRemovePageRange(pos, 0); }
218 
219     // Removes the page and all its children designated by subCount
220     // from internal structures of the control.
221     void DoInternalRemovePageRange(size_t pos, size_t subCount);
222 
223     // Returns internal number of pages which can be different from
224     // GetPageCount() while performing a page insertion or removal.
DoInternalGetPageCount()225     size_t DoInternalGetPageCount() const { return m_treeIds.Count(); }
226 
227 
228     DECLARE_EVENT_TABLE()
229     DECLARE_DYNAMIC_CLASS_NO_COPY(wxTreebook)
230     WX_DECLARE_CONTROL_CONTAINER();
231 };
232 
233 
234 // ----------------------------------------------------------------------------
235 // treebook event class and related stuff
236 // ----------------------------------------------------------------------------
237 
238 class WXDLLEXPORT wxTreebookEvent : public wxBookCtrlBaseEvent
239 {
240 public:
241     wxTreebookEvent(wxEventType commandType = wxEVT_NULL, int id = 0,
242                     int nSel = wxNOT_FOUND, int nOldSel = wxNOT_FOUND)
wxBookCtrlBaseEvent(commandType,id,nSel,nOldSel)243         : wxBookCtrlBaseEvent(commandType, id, nSel, nOldSel)
244     {
245     }
246 
wxTreebookEvent(const wxTreebookEvent & event)247     wxTreebookEvent(const wxTreebookEvent& event)
248         : wxBookCtrlBaseEvent(event)
249     {
250     }
251 
Clone()252     virtual wxEvent *Clone() const { return new wxTreebookEvent(*this); }
253 
254 private:
255     DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxTreebookEvent)
256 };
257 
258 extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED;
259 extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING;
260 extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED;
261 extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED;
262 
263 typedef void (wxEvtHandler::*wxTreebookEventFunction)(wxTreebookEvent&);
264 
265 #define wxTreebookEventHandler(func) \
266     (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxTreebookEventFunction, &func)
267 
268 #define EVT_TREEBOOK_PAGE_CHANGED(winid, fn) \
269     wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, winid, wxTreebookEventHandler(fn))
270 
271 #define EVT_TREEBOOK_PAGE_CHANGING(winid, fn) \
272     wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, winid, wxTreebookEventHandler(fn))
273 
274 #define EVT_TREEBOOK_NODE_COLLAPSED(winid, fn) \
275     wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED, winid, wxTreebookEventHandler(fn))
276 
277 #define EVT_TREEBOOK_NODE_EXPANDED(winid, fn) \
278     wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED, winid, wxTreebookEventHandler(fn))
279 
280 
281 #endif // wxUSE_TREEBOOK
282 
283 #endif // _WX_TREEBOOK_H_
284