treelist.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/treelist.h
  3. // Purpose: wxTreeListCtrl class declaration.
  4. // Author: Vadim Zeitlin
  5. // Created: 2011-08-17
  6. // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
  7. // Licence: wxWindows licence
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_TREELIST_H_
  10. #define _WX_TREELIST_H_
  11. #include "wx/defs.h"
  12. #if wxUSE_TREELISTCTRL
  13. #include "wx/compositewin.h"
  14. #include "wx/containr.h"
  15. #include "wx/headercol.h"
  16. #include "wx/itemid.h"
  17. #include "wx/vector.h"
  18. #include "wx/window.h"
  19. #include "wx/withimages.h"
  20. class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
  21. class WXDLLIMPEXP_FWD_ADV wxDataViewEvent;
  22. extern WXDLLIMPEXP_DATA_ADV(const char) wxTreeListCtrlNameStr[];
  23. class wxTreeListCtrl;
  24. class wxTreeListModel;
  25. class wxTreeListModelNode;
  26. // ----------------------------------------------------------------------------
  27. // Constants.
  28. // ----------------------------------------------------------------------------
  29. // wxTreeListCtrl styles.
  30. //
  31. // Notice that using wxTL_USER_3STATE implies wxTL_3STATE and wxTL_3STATE in
  32. // turn implies wxTL_CHECKBOX.
  33. enum
  34. {
  35. wxTL_SINGLE = 0x0000, // This is the default anyhow.
  36. wxTL_MULTIPLE = 0x0001, // Allow multiple selection.
  37. wxTL_CHECKBOX = 0x0002, // Show checkboxes in the first column.
  38. wxTL_3STATE = 0x0004, // Allow 3rd state in checkboxes.
  39. wxTL_USER_3STATE = 0x0008, // Allow user to set 3rd state.
  40. wxTL_NO_HEADER = 0x0010, // Column titles not visible.
  41. wxTL_DEFAULT_STYLE = wxTL_SINGLE,
  42. wxTL_STYLE_MASK = wxTL_SINGLE |
  43. wxTL_MULTIPLE |
  44. wxTL_CHECKBOX |
  45. wxTL_3STATE |
  46. wxTL_USER_3STATE
  47. };
  48. // ----------------------------------------------------------------------------
  49. // wxTreeListItem: unique identifier of an item in wxTreeListCtrl.
  50. // ----------------------------------------------------------------------------
  51. // Make wxTreeListItem a forward-declarable class even though it's simple
  52. // enough to possibly be declared as a simple typedef.
  53. class wxTreeListItem : public wxItemId<wxTreeListModelNode*>
  54. {
  55. public:
  56. wxTreeListItem(wxTreeListModelNode* item = NULL)
  57. : wxItemId<wxTreeListModelNode*>(item)
  58. {
  59. }
  60. };
  61. // Container of multiple items.
  62. typedef wxVector<wxTreeListItem> wxTreeListItems;
  63. // Some special "items" that can be used with InsertItem():
  64. extern WXDLLIMPEXP_DATA_ADV(const wxTreeListItem) wxTLI_FIRST;
  65. extern WXDLLIMPEXP_DATA_ADV(const wxTreeListItem) wxTLI_LAST;
  66. // ----------------------------------------------------------------------------
  67. // wxTreeListItemComparator: defines order of wxTreeListCtrl items.
  68. // ----------------------------------------------------------------------------
  69. class wxTreeListItemComparator
  70. {
  71. public:
  72. wxTreeListItemComparator() { }
  73. // The comparison function should return negative, null or positive value
  74. // depending on whether the first item is less than, equal to or greater
  75. // than the second one. The items should be compared using their values for
  76. // the given column.
  77. virtual int
  78. Compare(wxTreeListCtrl* treelist,
  79. unsigned column,
  80. wxTreeListItem first,
  81. wxTreeListItem second) = 0;
  82. // Although this class is not used polymorphically by wxWidgets itself,
  83. // provide virtual dtor in case it's used like this in the user code.
  84. virtual ~wxTreeListItemComparator() { }
  85. private:
  86. wxDECLARE_NO_COPY_CLASS(wxTreeListItemComparator);
  87. };
  88. // ----------------------------------------------------------------------------
  89. // wxTreeListCtrl: a control combining wxTree- and wxListCtrl features.
  90. // ----------------------------------------------------------------------------
  91. // This control also provides easy to use high level interface. Although the
  92. // implementation uses wxDataViewCtrl internally, this class is intentionally
  93. // simpler than wxDataViewCtrl and doesn't provide all of its functionality.
  94. //
  95. // If you need extra features you can always use GetDataView() accessor to work
  96. // with wxDataViewCtrl directly but doing this makes your unportable to possible
  97. // future non-wxDataViewCtrl-based implementations of this class.
  98. class WXDLLIMPEXP_ADV wxTreeListCtrl
  99. : public wxCompositeWindow< wxNavigationEnabled<wxWindow> >,
  100. public wxWithImages
  101. {
  102. public:
  103. // Constructors and such
  104. // ---------------------
  105. wxTreeListCtrl() { Init(); }
  106. wxTreeListCtrl(wxWindow* parent,
  107. wxWindowID id,
  108. const wxPoint& pos = wxDefaultPosition,
  109. const wxSize& size = wxDefaultSize,
  110. long style = wxTL_DEFAULT_STYLE,
  111. const wxString& name = wxTreeListCtrlNameStr)
  112. {
  113. Init();
  114. Create(parent, id, pos, size, style, name);
  115. }
  116. bool Create(wxWindow* parent,
  117. wxWindowID id,
  118. const wxPoint& pos = wxDefaultPosition,
  119. const wxSize& size = wxDefaultSize,
  120. long style = wxTL_DEFAULT_STYLE,
  121. const wxString& name = wxTreeListCtrlNameStr);
  122. virtual ~wxTreeListCtrl();
  123. // Columns methods
  124. // ---------------
  125. // Add a column with the given title and attributes, returns the index of
  126. // the new column or -1 on failure.
  127. int AppendColumn(const wxString& title,
  128. int width = wxCOL_WIDTH_AUTOSIZE,
  129. wxAlignment align = wxALIGN_LEFT,
  130. int flags = wxCOL_RESIZABLE)
  131. {
  132. return DoInsertColumn(title, -1, width, align, flags);
  133. }
  134. // Return the total number of columns.
  135. unsigned GetColumnCount() const;
  136. // Delete the column with the given index, returns false if index is
  137. // invalid or deleting the column failed for some other reason.
  138. bool DeleteColumn(unsigned col);
  139. // Delete all columns.
  140. void ClearColumns();
  141. // Set column width to either the given value in pixels or to the value
  142. // large enough to fit all of the items if width == wxCOL_WIDTH_AUTOSIZE.
  143. void SetColumnWidth(unsigned col, int width);
  144. // Get the current width of the given column in pixels.
  145. int GetColumnWidth(unsigned col) const;
  146. // Get the width appropriate for showing the given text. This is typically
  147. // used as second argument for AppendColumn() or with SetColumnWidth().
  148. int WidthFor(const wxString& text) const;
  149. // Item methods
  150. // ------------
  151. // Adding items. The parent and text of the first column of the new item
  152. // must always be specified, the rest is optional.
  153. //
  154. // Each item can have two images: one used for closed state and another for
  155. // opened one. Only the first one is ever used for the items that don't
  156. // have children. And both are not set by default.
  157. //
  158. // It is also possible to associate arbitrary client data pointer with the
  159. // new item. It will be deleted by the control when the item is deleted
  160. // (either by an explicit DeleteItem() call or because the entire control
  161. // is destroyed).
  162. wxTreeListItem AppendItem(wxTreeListItem parent,
  163. const wxString& text,
  164. int imageClosed = NO_IMAGE,
  165. int imageOpened = NO_IMAGE,
  166. wxClientData* data = NULL)
  167. {
  168. return DoInsertItem(parent, wxTLI_LAST, text,
  169. imageClosed, imageOpened, data);
  170. }
  171. wxTreeListItem InsertItem(wxTreeListItem parent,
  172. wxTreeListItem previous,
  173. const wxString& text,
  174. int imageClosed = NO_IMAGE,
  175. int imageOpened = NO_IMAGE,
  176. wxClientData* data = NULL)
  177. {
  178. return DoInsertItem(parent, previous, text,
  179. imageClosed, imageOpened, data);
  180. }
  181. wxTreeListItem PrependItem(wxTreeListItem parent,
  182. const wxString& text,
  183. int imageClosed = NO_IMAGE,
  184. int imageOpened = NO_IMAGE,
  185. wxClientData* data = NULL)
  186. {
  187. return DoInsertItem(parent, wxTLI_FIRST, text,
  188. imageClosed, imageOpened, data);
  189. }
  190. // Deleting items.
  191. void DeleteItem(wxTreeListItem item);
  192. void DeleteAllItems();
  193. // Tree navigation
  194. // ---------------
  195. // Return the (never shown) root item.
  196. wxTreeListItem GetRootItem() const;
  197. // The parent item may be invalid for the root-level items.
  198. wxTreeListItem GetItemParent(wxTreeListItem item) const;
  199. // Iterate over the given item children: start by calling GetFirstChild()
  200. // and then call GetNextSibling() for as long as it returns valid item.
  201. wxTreeListItem GetFirstChild(wxTreeListItem item) const;
  202. wxTreeListItem GetNextSibling(wxTreeListItem item) const;
  203. // Return the first child of the root item, which is also the first item of
  204. // the tree in depth-first traversal order.
  205. wxTreeListItem GetFirstItem() const { return GetFirstChild(GetRootItem()); }
  206. // Get item after the given one in the depth-first tree-traversal order.
  207. // Calling this function starting with the result of GetFirstItem() allows
  208. // iterating over all items in the tree.
  209. wxTreeListItem GetNextItem(wxTreeListItem item) const;
  210. // Items attributes
  211. // ----------------
  212. const wxString& GetItemText(wxTreeListItem item, unsigned col = 0) const;
  213. // The convenience overload below sets the text for the first column.
  214. void SetItemText(wxTreeListItem item, unsigned col, const wxString& text);
  215. void SetItemText(wxTreeListItem item, const wxString& text)
  216. {
  217. SetItemText(item, 0, text);
  218. }
  219. // By default the opened image is the same as the normal, closed one (if
  220. // it's used at all).
  221. void SetItemImage(wxTreeListItem item, int closed, int opened = NO_IMAGE);
  222. // Retrieve or set the data associated with the item.
  223. wxClientData* GetItemData(wxTreeListItem item) const;
  224. void SetItemData(wxTreeListItem item, wxClientData* data);
  225. // Expanding and collapsing
  226. // ------------------------
  227. void Expand(wxTreeListItem item);
  228. void Collapse(wxTreeListItem item);
  229. bool IsExpanded(wxTreeListItem item) const;
  230. // Selection handling
  231. // ------------------
  232. // This function can be used with single selection controls, use
  233. // GetSelections() with the multi-selection ones.
  234. wxTreeListItem GetSelection() const;
  235. // This one can be used with either single or multi-selection controls.
  236. unsigned GetSelections(wxTreeListItems& selections) const;
  237. // In single selection mode Select() deselects any other selected items, in
  238. // multi-selection case it adds to the selection.
  239. void Select(wxTreeListItem item);
  240. // Can be used in multiple selection mode only, single selected item in the
  241. // single selection mode can't be unselected.
  242. void Unselect(wxTreeListItem item);
  243. // Return true if the item is selected, can be used in both single and
  244. // multiple selection modes.
  245. bool IsSelected(wxTreeListItem item) const;
  246. // Select or unselect all items, only valid in multiple selection mode.
  247. void SelectAll();
  248. void UnselectAll();
  249. // Checkbox handling
  250. // -----------------
  251. // Methods in this section can only be used with the controls created with
  252. // wxTL_CHECKBOX style.
  253. // Simple set, unset or query the checked state.
  254. void CheckItem(wxTreeListItem item, wxCheckBoxState state = wxCHK_CHECKED);
  255. void UncheckItem(wxTreeListItem item) { CheckItem(item, wxCHK_UNCHECKED); }
  256. // The same but do it recursively for this item itself and its children.
  257. void CheckItemRecursively(wxTreeListItem item,
  258. wxCheckBoxState state = wxCHK_CHECKED);
  259. // Update the parent of this item recursively: if this item and all its
  260. // siblings are checked, the parent will become checked as well. If this
  261. // item and all its siblings are unchecked, the parent will be unchecked.
  262. // And if the siblings of this item are not all in the same state, the
  263. // parent will be switched to indeterminate state. And then the same logic
  264. // will be applied to the parents parent and so on recursively.
  265. //
  266. // This is typically called when the state of the given item has changed
  267. // from EVT_TREELIST_ITEM_CHECKED() handler in the controls which have
  268. // wxTL_3STATE flag. Notice that without this flag this function can't work
  269. // as it would be unable to set the state of a parent with both checked and
  270. // unchecked items so it's only allowed to call it when this flag is set.
  271. void UpdateItemParentStateRecursively(wxTreeListItem item);
  272. // Return the current state.
  273. wxCheckBoxState GetCheckedState(wxTreeListItem item) const;
  274. // Return true if all item children (if any) are in the given state.
  275. bool AreAllChildrenInState(wxTreeListItem item,
  276. wxCheckBoxState state) const;
  277. // Sorting.
  278. // --------
  279. // Sort by the given column, either in ascending (default) or descending
  280. // sort order.
  281. //
  282. // By default, simple alphabetical sorting is done by this column contents
  283. // but SetItemComparator() may be called to perform comparison in some
  284. // other way.
  285. void SetSortColumn(unsigned col, bool ascendingOrder = true);
  286. // If the control contents is sorted, return true and fill the output
  287. // parameters with the column which is currently used for sorting and
  288. // whether we sort using ascending or descending order. Otherwise, i.e. if
  289. // the control contents is unsorted, simply return false.
  290. bool GetSortColumn(unsigned* col, bool* ascendingOrder = NULL);
  291. // Set the object to use for comparing the items. It will be called when
  292. // the control is being sorted because the user clicked on a sortable
  293. // column.
  294. //
  295. // The provided pointer is stored by the control so the object it points to
  296. // must have a life-time equal or greater to that of the control itself. In
  297. // addition, the pointer can be NULL to stop using custom comparator and
  298. // revert to the default alphabetical comparison.
  299. void SetItemComparator(wxTreeListItemComparator* comparator);
  300. // View window functions.
  301. // ----------------------
  302. // This control itself is entirely covered by the "view window" which is
  303. // currently a wxDataViewCtrl but if you want to avoid relying on this to
  304. // allow your code to work with later versions which might not be
  305. // wxDataViewCtrl-based, use the first function only and only use the
  306. // second one if you really need to call wxDataViewCtrl methods on it.
  307. wxWindow* GetView() const;
  308. wxDataViewCtrl* GetDataView() const { return m_view; }
  309. private:
  310. // Common part of all ctors.
  311. void Init();
  312. // Pure virtual method inherited from wxCompositeWindow.
  313. virtual wxWindowList GetCompositeWindowParts() const;
  314. // Implementation of AppendColumn().
  315. int DoInsertColumn(const wxString& title,
  316. int pos, // May be -1 meaning "append".
  317. int width,
  318. wxAlignment align,
  319. int flags);
  320. // Common part of {Append,Insert,Prepend}Item().
  321. wxTreeListItem DoInsertItem(wxTreeListItem parent,
  322. wxTreeListItem previous,
  323. const wxString& text,
  324. int imageClosed,
  325. int imageOpened,
  326. wxClientData* data);
  327. // Send wxTreeListEvent corresponding to the given wxDataViewEvent for an
  328. // item (as opposed for column-oriented events).
  329. //
  330. // Also updates the original event "skipped" and "vetoed" flags.
  331. void SendItemEvent(wxEventType evt, wxDataViewEvent& event);
  332. // Send wxTreeListEvent corresponding to the given column wxDataViewEvent.
  333. void SendColumnEvent(wxEventType evt, wxDataViewEvent& event);
  334. // Called by wxTreeListModel when an item is toggled by the user.
  335. void OnItemToggled(wxTreeListItem item, wxCheckBoxState stateOld);
  336. // Event handlers.
  337. void OnSelectionChanged(wxDataViewEvent& event);
  338. void OnItemExpanding(wxDataViewEvent& event);
  339. void OnItemExpanded(wxDataViewEvent& event);
  340. void OnItemActivated(wxDataViewEvent& event);
  341. void OnItemContextMenu(wxDataViewEvent& event);
  342. void OnColumnSorted(wxDataViewEvent& event);
  343. void OnSize(wxSizeEvent& event);
  344. wxDECLARE_EVENT_TABLE();
  345. wxDataViewCtrl* m_view;
  346. wxTreeListModel* m_model;
  347. wxTreeListItemComparator* m_comparator;
  348. // It calls our inherited protected wxWithImages::GetImage() method.
  349. friend class wxTreeListModel;
  350. wxDECLARE_NO_COPY_CLASS(wxTreeListCtrl);
  351. };
  352. // ----------------------------------------------------------------------------
  353. // wxTreeListEvent: event generated by wxTreeListCtrl.
  354. // ----------------------------------------------------------------------------
  355. class WXDLLIMPEXP_ADV wxTreeListEvent : public wxNotifyEvent
  356. {
  357. public:
  358. // Default ctor is provided for wxRTTI needs only but should never be used.
  359. wxTreeListEvent() { Init(); }
  360. // The item affected by the event. Valid for all events except
  361. // column-specific ones such as COLUMN_SORTED.
  362. wxTreeListItem GetItem() const { return m_item; }
  363. // The previous state of the item checkbox for ITEM_CHECKED events only.
  364. wxCheckBoxState GetOldCheckedState() const { return m_oldCheckedState; }
  365. // The index of the column affected by the event. Currently only used by
  366. // COLUMN_SORTED event.
  367. unsigned GetColumn() const { return m_column; }
  368. virtual wxEvent* Clone() const { return new wxTreeListEvent(*this); }
  369. private:
  370. // Common part of all ctors.
  371. void Init()
  372. {
  373. m_column = static_cast<unsigned>(-1);
  374. m_oldCheckedState = wxCHK_UNDETERMINED;
  375. }
  376. // Ctor is private, only wxTreeListCtrl can create events of this type.
  377. wxTreeListEvent(wxEventType evtType,
  378. wxTreeListCtrl* treelist,
  379. wxTreeListItem item)
  380. : wxNotifyEvent(evtType, treelist->GetId()),
  381. m_item(item)
  382. {
  383. SetEventObject(treelist);
  384. Init();
  385. }
  386. // Set the checkbox state before this event for ITEM_CHECKED events.
  387. void SetOldCheckedState(wxCheckBoxState state)
  388. {
  389. m_oldCheckedState = state;
  390. }
  391. // Set the column affected by this event for COLUMN_SORTED events.
  392. void SetColumn(unsigned column)
  393. {
  394. m_column = column;
  395. }
  396. const wxTreeListItem m_item;
  397. wxCheckBoxState m_oldCheckedState;
  398. unsigned m_column;
  399. friend class wxTreeListCtrl;
  400. wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxTreeListEvent);
  401. };
  402. // Event types and event table macros.
  403. typedef void (wxEvtHandler::*wxTreeListEventFunction)(wxTreeListEvent&);
  404. #define wxTreeListEventHandler(func) \
  405. wxEVENT_HANDLER_CAST(wxTreeListEventFunction, func)
  406. #define wxEVT_TREELIST_GENERIC(name, id, fn) \
  407. wx__DECLARE_EVT1(wxEVT_TREELIST_##name, id, wxTreeListEventHandler(fn))
  408. #define wxDECLARE_TREELIST_EVENT(name) \
  409. wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, \
  410. wxEVT_TREELIST_##name, \
  411. wxTreeListEvent)
  412. wxDECLARE_TREELIST_EVENT(SELECTION_CHANGED);
  413. #define EVT_TREELIST_SELECTION_CHANGED(id, fn) \
  414. wxEVT_TREELIST_GENERIC(SELECTION_CHANGED, id, fn)
  415. wxDECLARE_TREELIST_EVENT(ITEM_EXPANDING);
  416. #define EVT_TREELIST_ITEM_EXPANDING(id, fn) \
  417. wxEVT_TREELIST_GENERIC(ITEM_EXPANDING, id, fn)
  418. wxDECLARE_TREELIST_EVENT(ITEM_EXPANDED);
  419. #define EVT_TREELIST_ITEM_EXPANDED(id, fn) \
  420. wxEVT_TREELIST_GENERIC(ITEM_EXPANDED, id, fn)
  421. wxDECLARE_TREELIST_EVENT(ITEM_CHECKED);
  422. #define EVT_TREELIST_ITEM_CHECKED(id, fn) \
  423. wxEVT_TREELIST_GENERIC(ITEM_CHECKED, id, fn)
  424. wxDECLARE_TREELIST_EVENT(ITEM_ACTIVATED);
  425. #define EVT_TREELIST_ITEM_ACTIVATED(id, fn) \
  426. wxEVT_TREELIST_GENERIC(ITEM_ACTIVATED, id, fn)
  427. wxDECLARE_TREELIST_EVENT(ITEM_CONTEXT_MENU);
  428. #define EVT_TREELIST_ITEM_CONTEXT_MENU(id, fn) \
  429. wxEVT_TREELIST_GENERIC(ITEM_CONTEXT_MENU, id, fn)
  430. wxDECLARE_TREELIST_EVENT(COLUMN_SORTED);
  431. #define EVT_TREELIST_COLUMN_SORTED(id, fn) \
  432. wxEVT_TREELIST_GENERIC(COLUMN_SORTED, id, fn)
  433. #undef wxDECLARE_TREELIST_EVENT
  434. // old wxEVT_COMMAND_* constants
  435. #define wxEVT_COMMAND_TREELIST_SELECTION_CHANGED wxEVT_TREELIST_SELECTION_CHANGED
  436. #define wxEVT_COMMAND_TREELIST_ITEM_EXPANDING wxEVT_TREELIST_ITEM_EXPANDING
  437. #define wxEVT_COMMAND_TREELIST_ITEM_EXPANDED wxEVT_TREELIST_ITEM_EXPANDED
  438. #define wxEVT_COMMAND_TREELIST_ITEM_CHECKED wxEVT_TREELIST_ITEM_CHECKED
  439. #define wxEVT_COMMAND_TREELIST_ITEM_ACTIVATED wxEVT_TREELIST_ITEM_ACTIVATED
  440. #define wxEVT_COMMAND_TREELIST_ITEM_CONTEXT_MENU wxEVT_TREELIST_ITEM_CONTEXT_MENU
  441. #define wxEVT_COMMAND_TREELIST_COLUMN_SORTED wxEVT_TREELIST_COLUMN_SORTED
  442. #endif // wxUSE_TREELISTCTRL
  443. #endif // _WX_TREELIST_H_