1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxTreeListCtrl class declaration.
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_TREELIST_H_
12 #define _WX_TREELIST_H_
16 #if wxUSE_TREELISTCTRL
18 #include "wx/compositewin.h"
19 #include "wx/containr.h"
20 #include "wx/headercol.h"
21 #include "wx/itemid.h"
22 #include "wx/vector.h"
23 #include "wx/window.h"
24 #include "wx/withimages.h"
26 class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl
;
27 class WXDLLIMPEXP_FWD_ADV wxDataViewEvent
;
29 extern WXDLLIMPEXP_DATA_ADV(const char) wxTreeListCtrlNameStr
[];
32 class wxTreeListModel
;
33 class wxTreeListModelNode
;
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // wxTreeListCtrl styles.
41 // Notice that using wxTL_USER_3STATE implies wxTL_3STATE and wxTL_3STATE in
42 // turn implies wxTL_CHECKBOX.
45 wxTL_SINGLE
= 0x0000, // This is the default anyhow.
46 wxTL_MULTIPLE
= 0x0001, // Allow multiple selection.
47 wxTL_CHECKBOX
= 0x0002, // Show checkboxes in the first column.
48 wxTL_3STATE
= 0x0004, // Allow 3rd state in checkboxes.
49 wxTL_USER_3STATE
= 0x0008, // Allow user to set 3rd state.
50 wxTL_NO_HEADER
= 0x0010, // Column titles not visible.
52 wxTL_DEFAULT_STYLE
= wxTL_SINGLE
,
53 wxTL_STYLE_MASK
= wxTL_SINGLE
|
60 // ----------------------------------------------------------------------------
61 // wxTreeListItem: unique identifier of an item in wxTreeListCtrl.
62 // ----------------------------------------------------------------------------
64 // Make wxTreeListItem a forward-declarable class even though it's simple
65 // enough to possibly be declared as a simple typedef.
66 class wxTreeListItem
: public wxItemId
<wxTreeListModelNode
*>
69 wxTreeListItem(wxTreeListModelNode
* item
= NULL
)
70 : wxItemId
<wxTreeListModelNode
*>(item
)
75 // Container of multiple items.
76 typedef wxVector
<wxTreeListItem
> wxTreeListItems
;
78 // Some special "items" that can be used with InsertItem():
79 extern WXDLLIMPEXP_DATA_ADV(const wxTreeListItem
) wxTLI_FIRST
;
80 extern WXDLLIMPEXP_DATA_ADV(const wxTreeListItem
) wxTLI_LAST
;
82 // ----------------------------------------------------------------------------
83 // wxTreeListItemComparator: defines order of wxTreeListCtrl items.
84 // ----------------------------------------------------------------------------
86 class wxTreeListItemComparator
89 wxTreeListItemComparator() { }
91 // The comparison function should return negative, null or positive value
92 // depending on whether the first item is less than, equal to or greater
93 // than the second one. The items should be compared using their values for
96 Compare(wxTreeListCtrl
* treelist
,
99 wxTreeListItem second
) = 0;
101 // Although this class is not used polymorphically by wxWidgets itself,
102 // provide virtual dtor in case it's used like this in the user code.
103 virtual ~wxTreeListItemComparator() { }
106 wxDECLARE_NO_COPY_CLASS(wxTreeListItemComparator
);
109 // ----------------------------------------------------------------------------
110 // wxTreeListCtrl: a control combining wxTree- and wxListCtrl features.
111 // ----------------------------------------------------------------------------
113 // This control also provides easy to use high level interface. Although the
114 // implementation uses wxDataViewCtrl internally, this class is intentionally
115 // simpler than wxDataViewCtrl and doesn't provide all of its functionality.
117 // If you need extra features you can always use GetDataView() accessor to work
118 // with wxDataViewCtrl directly but doing this makes your unportable to possible
119 // future non-wxDataViewCtrl-based implementations of this class.
121 class WXDLLIMPEXP_ADV wxTreeListCtrl
122 : public wxCompositeWindow
< wxNavigationEnabled
<wxWindow
> >,
126 // Constructors and such
127 // ---------------------
129 wxTreeListCtrl() { Init(); }
130 wxTreeListCtrl(wxWindow
* parent
,
132 const wxPoint
& pos
= wxDefaultPosition
,
133 const wxSize
& size
= wxDefaultSize
,
134 long style
= wxTL_DEFAULT_STYLE
,
135 const wxString
& name
= wxTreeListCtrlNameStr
)
139 Create(parent
, id
, pos
, size
, style
, name
);
142 bool Create(wxWindow
* parent
,
144 const wxPoint
& pos
= wxDefaultPosition
,
145 const wxSize
& size
= wxDefaultSize
,
146 long style
= wxTL_DEFAULT_STYLE
,
147 const wxString
& name
= wxTreeListCtrlNameStr
);
150 virtual ~wxTreeListCtrl();
155 // Add a column with the given title and attributes, returns the index of
156 // the new column or -1 on failure.
157 int AppendColumn(const wxString
& title
,
158 int width
= wxCOL_WIDTH_AUTOSIZE
,
159 wxAlignment align
= wxALIGN_LEFT
,
160 int flags
= wxCOL_RESIZABLE
)
162 return DoInsertColumn(title
, -1, width
, align
, flags
);
165 // Return the total number of columns.
166 unsigned GetColumnCount() const;
168 // Delete the column with the given index, returns false if index is
169 // invalid or deleting the column failed for some other reason.
170 bool DeleteColumn(unsigned col
);
172 // Delete all columns.
175 // Set column width to either the given value in pixels or to the value
176 // large enough to fit all of the items if width == wxCOL_WIDTH_AUTOSIZE.
177 void SetColumnWidth(unsigned col
, int width
);
179 // Get the current width of the given column in pixels.
180 int GetColumnWidth(unsigned col
) const;
182 // Get the width appropriate for showing the given text. This is typically
183 // used as second argument for AppendColumn() or with SetColumnWidth().
184 int WidthFor(const wxString
& text
) const;
190 // Adding items. The parent and text of the first column of the new item
191 // must always be specified, the rest is optional.
193 // Each item can have two images: one used for closed state and another for
194 // opened one. Only the first one is ever used for the items that don't
195 // have children. And both are not set by default.
197 // It is also possible to associate arbitrary client data pointer with the
198 // new item. It will be deleted by the control when the item is deleted
199 // (either by an explicit DeleteItem() call or because the entire control
202 wxTreeListItem
AppendItem(wxTreeListItem parent
,
203 const wxString
& text
,
204 int imageClosed
= NO_IMAGE
,
205 int imageOpened
= NO_IMAGE
,
206 wxClientData
* data
= NULL
)
208 return DoInsertItem(parent
, wxTLI_LAST
, text
,
209 imageClosed
, imageOpened
, data
);
212 wxTreeListItem
InsertItem(wxTreeListItem parent
,
213 wxTreeListItem previous
,
214 const wxString
& text
,
215 int imageClosed
= NO_IMAGE
,
216 int imageOpened
= NO_IMAGE
,
217 wxClientData
* data
= NULL
)
219 return DoInsertItem(parent
, previous
, text
,
220 imageClosed
, imageOpened
, data
);
223 wxTreeListItem
PrependItem(wxTreeListItem parent
,
224 const wxString
& text
,
225 int imageClosed
= NO_IMAGE
,
226 int imageOpened
= NO_IMAGE
,
227 wxClientData
* data
= NULL
)
229 return DoInsertItem(parent
, wxTLI_FIRST
, text
,
230 imageClosed
, imageOpened
, data
);
234 void DeleteItem(wxTreeListItem item
);
235 void DeleteAllItems();
241 // Return the (never shown) root item.
242 wxTreeListItem
GetRootItem() const;
244 // The parent item may be invalid for the root-level items.
245 wxTreeListItem
GetItemParent(wxTreeListItem item
) const;
247 // Iterate over the given item children: start by calling GetFirstChild()
248 // and then call GetNextSibling() for as long as it returns valid item.
249 wxTreeListItem
GetFirstChild(wxTreeListItem item
) const;
250 wxTreeListItem
GetNextSibling(wxTreeListItem item
) const;
252 // Return the first child of the root item, which is also the first item of
253 // the tree in depth-first traversal order.
254 wxTreeListItem
GetFirstItem() const { return GetFirstChild(GetRootItem()); }
256 // Get item after the given one in the depth-first tree-traversal order.
257 // Calling this function starting with the result of GetFirstItem() allows
258 // iterating over all items in the tree.
259 wxTreeListItem
GetNextItem(wxTreeListItem item
) const;
265 const wxString
& GetItemText(wxTreeListItem item
, unsigned col
= 0) const;
267 // The convenience overload below sets the text for the first column.
268 void SetItemText(wxTreeListItem item
, unsigned col
, const wxString
& text
);
269 void SetItemText(wxTreeListItem item
, const wxString
& text
)
271 SetItemText(item
, 0, text
);
274 // By default the opened image is the same as the normal, closed one (if
275 // it's used at all).
276 void SetItemImage(wxTreeListItem item
, int closed
, int opened
= NO_IMAGE
);
278 // Retrieve or set the data associated with the item.
279 wxClientData
* GetItemData(wxTreeListItem item
) const;
280 void SetItemData(wxTreeListItem item
, wxClientData
* data
);
283 // Expanding and collapsing
284 // ------------------------
286 void Expand(wxTreeListItem item
);
287 void Collapse(wxTreeListItem item
);
288 bool IsExpanded(wxTreeListItem item
) const;
291 // Selection handling
292 // ------------------
294 // This function can be used with single selection controls, use
295 // GetSelections() with the multi-selection ones.
296 wxTreeListItem
GetSelection() const;
298 // This one can be used with either single or multi-selection controls.
299 unsigned GetSelections(wxTreeListItems
& selections
) const;
301 // In single selection mode Select() deselects any other selected items, in
302 // multi-selection case it adds to the selection.
303 void Select(wxTreeListItem item
);
305 // Can be used in multiple selection mode only, single selected item in the
306 // single selection mode can't be unselected.
307 void Unselect(wxTreeListItem item
);
309 // Return true if the item is selected, can be used in both single and
310 // multiple selection modes.
311 bool IsSelected(wxTreeListItem item
) const;
313 // Select or unselect all items, only valid in multiple selection mode.
321 // Methods in this section can only be used with the controls created with
322 // wxTL_CHECKBOX style.
324 // Simple set, unset or query the checked state.
325 void CheckItem(wxTreeListItem item
, wxCheckBoxState state
= wxCHK_CHECKED
);
326 void UncheckItem(wxTreeListItem item
) { CheckItem(item
, wxCHK_UNCHECKED
); }
328 // The same but do it recursively for this item itself and its children.
329 void CheckItemRecursively(wxTreeListItem item
,
330 wxCheckBoxState state
= wxCHK_CHECKED
);
332 // Update the parent of this item recursively: if this item and all its
333 // siblings are checked, the parent will become checked as well. If this
334 // item and all its siblings are unchecked, the parent will be unchecked.
335 // And if the siblings of this item are not all in the same state, the
336 // parent will be switched to indeterminate state. And then the same logic
337 // will be applied to the parents parent and so on recursively.
339 // This is typically called when the state of the given item has changed
340 // from EVT_TREELIST_ITEM_CHECKED() handler in the controls which have
341 // wxTL_3STATE flag. Notice that without this flag this function can't work
342 // as it would be unable to set the state of a parent with both checked and
343 // unchecked items so it's only allowed to call it when this flag is set.
344 void UpdateItemParentStateRecursively(wxTreeListItem item
);
346 // Return the current state.
347 wxCheckBoxState
GetCheckedState(wxTreeListItem item
) const;
349 // Return true if all item children (if any) are in the given state.
350 bool AreAllChildrenInState(wxTreeListItem item
,
351 wxCheckBoxState state
) const;
358 // Sort by the given column, either in ascending (default) or descending
361 // By default, simple alphabetical sorting is done by this column contents
362 // but SetItemComparator() may be called to perform comparison in some
364 void SetSortColumn(unsigned col
, bool ascendingOrder
= true);
366 // If the control contents is sorted, return true and fill the output
367 // parameters with the column which is currently used for sorting and
368 // whether we sort using ascending or descending order. Otherwise, i.e. if
369 // the control contents is unsorted, simply return false.
370 bool GetSortColumn(unsigned* col
, bool* ascendingOrder
= NULL
);
372 // Set the object to use for comparing the items. It will be called when
373 // the control is being sorted because the user clicked on a sortable
376 // The provided pointer is stored by the control so the object it points to
377 // must have a life-time equal or greater to that of the control itself. In
378 // addition, the pointer can be NULL to stop using custom comparator and
379 // revert to the default alphabetical comparison.
380 void SetItemComparator(wxTreeListItemComparator
* comparator
);
383 // View window functions.
384 // ----------------------
386 // This control itself is entirely covered by the "view window" which is
387 // currently a wxDataViewCtrl but if you want to avoid relying on this to
388 // allow your code to work with later versions which might not be
389 // wxDataViewCtrl-based, use the first function only and only use the
390 // second one if you really need to call wxDataViewCtrl methods on it.
391 wxWindow
* GetView() const;
392 wxDataViewCtrl
* GetDataView() const { return m_view
; }
395 // Common part of all ctors.
398 // Pure virtual method inherited from wxCompositeWindow.
399 virtual wxWindowList
GetCompositeWindowParts() const;
401 // Implementation of AppendColumn().
402 int DoInsertColumn(const wxString
& title
,
403 int pos
, // May be -1 meaning "append".
408 // Common part of {Append,Insert,Prepend}Item().
409 wxTreeListItem
DoInsertItem(wxTreeListItem parent
,
410 wxTreeListItem previous
,
411 const wxString
& text
,
416 // Send wxTreeListEvent corresponding to the given wxDataViewEvent for an
417 // item (as opposed for column-oriented events).
419 // Also updates the original event "skipped" and "vetoed" flags.
420 void SendItemEvent(wxEventType evt
, wxDataViewEvent
& event
);
422 // Send wxTreeListEvent corresponding to the given column wxDataViewEvent.
423 void SendColumnEvent(wxEventType evt
, wxDataViewEvent
& event
);
426 // Called by wxTreeListModel when an item is toggled by the user.
427 void OnItemToggled(wxTreeListItem item
, wxCheckBoxState stateOld
);
430 void OnSelectionChanged(wxDataViewEvent
& event
);
431 void OnItemExpanding(wxDataViewEvent
& event
);
432 void OnItemExpanded(wxDataViewEvent
& event
);
433 void OnItemActivated(wxDataViewEvent
& event
);
434 void OnItemContextMenu(wxDataViewEvent
& event
);
435 void OnColumnSorted(wxDataViewEvent
& event
);
436 void OnSize(wxSizeEvent
& event
);
438 wxDECLARE_EVENT_TABLE();
441 wxDataViewCtrl
* m_view
;
442 wxTreeListModel
* m_model
;
444 wxTreeListItemComparator
* m_comparator
;
447 // It calls our inherited protected wxWithImages::GetImage() method.
448 friend class wxTreeListModel
;
450 wxDECLARE_NO_COPY_CLASS(wxTreeListCtrl
);
453 // ----------------------------------------------------------------------------
454 // wxTreeListEvent: event generated by wxTreeListCtrl.
455 // ----------------------------------------------------------------------------
457 class WXDLLIMPEXP_ADV wxTreeListEvent
: public wxNotifyEvent
460 // Default ctor is provided for wxRTTI needs only but should never be used.
461 wxTreeListEvent() { Init(); }
463 // The item affected by the event. Valid for all events except
464 // column-specific ones such as COLUMN_SORTED.
465 wxTreeListItem
GetItem() const { return m_item
; }
467 // The previous state of the item checkbox for ITEM_CHECKED events only.
468 wxCheckBoxState
GetOldCheckedState() const { return m_oldCheckedState
; }
470 // The index of the column affected by the event. Currently only used by
471 // COLUMN_SORTED event.
472 unsigned GetColumn() const { return m_column
; }
474 virtual wxEvent
* Clone() const { return new wxTreeListEvent(*this); }
477 // Common part of all ctors.
480 m_column
= static_cast<unsigned>(-1);
482 m_oldCheckedState
= wxCHK_UNDETERMINED
;
485 // Ctor is private, only wxTreeListCtrl can create events of this type.
486 wxTreeListEvent(wxEventType evtType
,
487 wxTreeListCtrl
* treelist
,
489 : wxNotifyEvent(evtType
, treelist
->GetId()),
492 SetEventObject(treelist
);
497 // Set the checkbox state before this event for ITEM_CHECKED events.
498 void SetOldCheckedState(wxCheckBoxState state
)
500 m_oldCheckedState
= state
;
503 // Set the column affected by this event for COLUMN_SORTED events.
504 void SetColumn(unsigned column
)
510 const wxTreeListItem m_item
;
512 wxCheckBoxState m_oldCheckedState
;
516 friend class wxTreeListCtrl
;
518 wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxTreeListEvent
);
521 // Event types and event table macros.
523 typedef void (wxEvtHandler::*wxTreeListEventFunction
)(wxTreeListEvent
&);
525 #define wxTreeListEventHandler(func) \
526 wxEVENT_HANDLER_CAST(wxTreeListEventFunction, func)
528 #define wxEVT_TREELIST_GENERIC(name, id, fn) \
529 wx__DECLARE_EVT1(wxEVT_COMMAND_TREELIST_##name, id, wxTreeListEventHandler(fn))
531 #define wxDECLARE_TREELIST_EVENT(name) \
532 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, \
533 wxEVT_COMMAND_TREELIST_##name, \
536 wxDECLARE_TREELIST_EVENT(SELECTION_CHANGED
);
537 #define EVT_TREELIST_SELECTION_CHANGED(id, fn) \
538 wxEVT_TREELIST_GENERIC(SELECTION_CHANGED, id, fn)
540 wxDECLARE_TREELIST_EVENT(ITEM_EXPANDING
);
541 #define EVT_TREELIST_ITEM_EXPANDING(id, fn) \
542 wxEVT_TREELIST_GENERIC(ITEM_EXPANDING, id, fn)
544 wxDECLARE_TREELIST_EVENT(ITEM_EXPANDED
);
545 #define EVT_TREELIST_ITEM_EXPANDED(id, fn) \
546 wxEVT_TREELIST_GENERIC(ITEM_EXPANDED, id, fn)
548 wxDECLARE_TREELIST_EVENT(ITEM_CHECKED
);
549 #define EVT_TREELIST_ITEM_CHECKED(id, fn) \
550 wxEVT_TREELIST_GENERIC(ITEM_CHECKED, id, fn)
552 wxDECLARE_TREELIST_EVENT(ITEM_ACTIVATED
);
553 #define EVT_TREELIST_ITEM_ACTIVATED(id, fn) \
554 wxEVT_TREELIST_GENERIC(ITEM_ACTIVATED, id, fn)
556 wxDECLARE_TREELIST_EVENT(ITEM_CONTEXT_MENU
);
557 #define EVT_TREELIST_ITEM_CONTEXT_MENU(id, fn) \
558 wxEVT_TREELIST_GENERIC(ITEM_CONTEXT_MENU, id, fn)
560 wxDECLARE_TREELIST_EVENT(COLUMN_SORTED
);
561 #define EVT_TREELIST_COLUMN_SORTED(id, fn) \
562 wxEVT_TREELIST_GENERIC(COLUMN_SORTED, id, fn)
564 #undef wxDECLARE_TREELIST_EVENT
566 #endif // wxUSE_TREELISTCTRL
568 #endif // _WX_TREELIST_H_