]> git.saurik.com Git - wxWidgets.git/blame - include/wx/treelist.h
Reset sorting column in generic wxDataViewCtrl properly.
[wxWidgets.git] / include / wx / treelist.h
CommitLineData
524cb040
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: wx/treelist.h
3// Purpose: wxTreeListCtrl class declaration.
4// Author: Vadim Zeitlin
5// Created: 2011-08-17
c71b5269 6// RCS-ID: $Id$
524cb040
VZ
7// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11#ifndef _WX_TREELIST_H_
12#define _WX_TREELIST_H_
13
14#include "wx/defs.h"
15
16#if wxUSE_TREELISTCTRL
17
1a661779 18#include "wx/compositewin.h"
513d0595 19#include "wx/containr.h"
524cb040
VZ
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"
25
26class WXDLLIMPEXP_FWD_ADV wxDataViewCtrl;
27class WXDLLIMPEXP_FWD_ADV wxDataViewEvent;
28
6de6ca4c 29extern WXDLLIMPEXP_DATA_ADV(const char) wxTreeListCtrlNameStr[];
524cb040 30
da2e758f 31class wxTreeListCtrl;
524cb040
VZ
32class wxTreeListModel;
33class wxTreeListModelNode;
34
35// ----------------------------------------------------------------------------
36// Constants.
37// ----------------------------------------------------------------------------
38
39// wxTreeListCtrl styles.
40//
41// Notice that using wxTL_USER_3STATE implies wxTL_3STATE and wxTL_3STATE in
42// turn implies wxTL_CHECKBOX.
43enum
44{
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.
c71b5269 50 wxTL_NO_HEADER = 0x0010, // Column titles not visible.
524cb040
VZ
51
52 wxTL_DEFAULT_STYLE = wxTL_SINGLE,
53 wxTL_STYLE_MASK = wxTL_SINGLE |
d50fc4dc
VZ
54 wxTL_MULTIPLE |
55 wxTL_CHECKBOX |
56 wxTL_3STATE |
57 wxTL_USER_3STATE
524cb040
VZ
58};
59
60// ----------------------------------------------------------------------------
61// wxTreeListItem: unique identifier of an item in wxTreeListCtrl.
62// ----------------------------------------------------------------------------
63
64// Make wxTreeListItem a forward-declarable class even though it's simple
65// enough to possibly be declared as a simple typedef.
66class wxTreeListItem : public wxItemId<wxTreeListModelNode*>
67{
68public:
69 wxTreeListItem(wxTreeListModelNode* item = NULL)
70 : wxItemId<wxTreeListModelNode*>(item)
71 {
72 }
73};
74
75// Container of multiple items.
76typedef wxVector<wxTreeListItem> wxTreeListItems;
77
78// Some special "items" that can be used with InsertItem():
79extern WXDLLIMPEXP_DATA_ADV(const wxTreeListItem) wxTLI_FIRST;
80extern WXDLLIMPEXP_DATA_ADV(const wxTreeListItem) wxTLI_LAST;
81
da2e758f
VZ
82// ----------------------------------------------------------------------------
83// wxTreeListItemComparator: defines order of wxTreeListCtrl items.
84// ----------------------------------------------------------------------------
85
86class wxTreeListItemComparator
87{
88public:
89 wxTreeListItemComparator() { }
90
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
94 // the given column.
95 virtual int
96 Compare(wxTreeListCtrl* treelist,
97 unsigned column,
98 wxTreeListItem first,
99 wxTreeListItem second) = 0;
100
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() { }
104
105private:
106 wxDECLARE_NO_COPY_CLASS(wxTreeListItemComparator);
107};
108
524cb040
VZ
109// ----------------------------------------------------------------------------
110// wxTreeListCtrl: a control combining wxTree- and wxListCtrl features.
111// ----------------------------------------------------------------------------
112
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.
116//
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.
120
1a661779
VZ
121class WXDLLIMPEXP_ADV wxTreeListCtrl
122 : public wxCompositeWindow< wxNavigationEnabled<wxWindow> >,
123 public wxWithImages
524cb040
VZ
124{
125public:
126 // Constructors and such
127 // ---------------------
128
129 wxTreeListCtrl() { Init(); }
130 wxTreeListCtrl(wxWindow* parent,
131 wxWindowID id,
132 const wxPoint& pos = wxDefaultPosition,
133 const wxSize& size = wxDefaultSize,
134 long style = wxTL_DEFAULT_STYLE,
135 const wxString& name = wxTreeListCtrlNameStr)
136 {
137 Init();
138
139 Create(parent, id, pos, size, style, name);
140 }
141
142 bool Create(wxWindow* parent,
143 wxWindowID id,
144 const wxPoint& pos = wxDefaultPosition,
145 const wxSize& size = wxDefaultSize,
146 long style = wxTL_DEFAULT_STYLE,
147 const wxString& name = wxTreeListCtrlNameStr);
148
149
150 virtual ~wxTreeListCtrl();
151
152 // Columns methods
153 // ---------------
154
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)
161 {
162 return DoInsertColumn(title, -1, width, align, flags);
163 }
164
165 // Return the total number of columns.
166 unsigned GetColumnCount() const;
167
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);
171
172 // Delete all columns.
173 void ClearColumns();
174
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);
178
179 // Get the current width of the given column in pixels.
180 int GetColumnWidth(unsigned col) const;
181
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;
185
186
187 // Item methods
188 // ------------
189
190 // Adding items. The parent and text of the first column of the new item
191 // must always be specified, the rest is optional.
192 //
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.
196 //
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
200 // is destroyed).
201
202 wxTreeListItem AppendItem(wxTreeListItem parent,
203 const wxString& text,
204 int imageClosed = NO_IMAGE,
205 int imageOpened = NO_IMAGE,
206 wxClientData* data = NULL)
207 {
208 return DoInsertItem(parent, wxTLI_LAST, text,
209 imageClosed, imageOpened, data);
210 }
211
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)
218 {
219 return DoInsertItem(parent, previous, text,
220 imageClosed, imageOpened, data);
221 }
222
223 wxTreeListItem PrependItem(wxTreeListItem parent,
224 const wxString& text,
225 int imageClosed = NO_IMAGE,
226 int imageOpened = NO_IMAGE,
227 wxClientData* data = NULL)
228 {
229 return DoInsertItem(parent, wxTLI_FIRST, text,
230 imageClosed, imageOpened, data);
231 }
232
233 // Deleting items.
234 void DeleteItem(wxTreeListItem item);
235 void DeleteAllItems();
236
237
238 // Tree navigation
239 // ---------------
240
241 // Return the (never shown) root item.
242 wxTreeListItem GetRootItem() const;
243
244 // The parent item may be invalid for the root-level items.
245 wxTreeListItem GetItemParent(wxTreeListItem item) const;
246
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;
251
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()); }
255
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;
260
261
262 // Items attributes
263 // ----------------
264
265 const wxString& GetItemText(wxTreeListItem item, unsigned col = 0) const;
266
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)
270 {
271 SetItemText(item, 0, text);
272 }
273
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);
277
278 // Retrieve or set the data associated with the item.
279 wxClientData* GetItemData(wxTreeListItem item) const;
280 void SetItemData(wxTreeListItem item, wxClientData* data);
281
282
283 // Expanding and collapsing
284 // ------------------------
285
286 void Expand(wxTreeListItem item);
287 void Collapse(wxTreeListItem item);
288 bool IsExpanded(wxTreeListItem item) const;
289
290
291 // Selection handling
292 // ------------------
293
294 // This function can be used with single selection controls, use
295 // GetSelections() with the multi-selection ones.
296 wxTreeListItem GetSelection() const;
297
298 // This one can be used with either single or multi-selection controls.
299 unsigned GetSelections(wxTreeListItems& selections) const;
300
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);
304
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);
308
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;
312
313 // Select or unselect all items, only valid in multiple selection mode.
314 void SelectAll();
315 void UnselectAll();
316
317
318 // Checkbox handling
319 // -----------------
320
321 // Methods in this section can only be used with the controls created with
322 // wxTL_CHECKBOX style.
323
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); }
327
328 // The same but do it recursively for this item itself and its children.
329 void CheckItemRecursively(wxTreeListItem item,
330 wxCheckBoxState state = wxCHK_CHECKED);
331
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.
338 //
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);
345
346 // Return the current state.
347 wxCheckBoxState GetCheckedState(wxTreeListItem item) const;
348
349 // Return true if all item children (if any) are in the given state.
350 bool AreAllChildrenInState(wxTreeListItem item,
351 wxCheckBoxState state) const;
352
353
8148ae02 354
da2e758f
VZ
355 // Sorting.
356 // --------
357
358 // Sort by the given column, either in ascending (default) or descending
359 // sort order.
360 //
361 // By default, simple alphabetical sorting is done by this column contents
362 // but SetItemComparator() may be called to perform comparison in some
363 // other way.
364 void SetSortColumn(unsigned col, bool ascendingOrder = true);
365
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);
371
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
374 // column.
375 //
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);
381
382
8148ae02
VZ
383 // View window functions.
384 // ----------------------
385
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; }
393
524cb040
VZ
394private:
395 // Common part of all ctors.
396 void Init();
397
1a661779
VZ
398 // Pure virtual method inherited from wxCompositeWindow.
399 virtual wxWindowList GetCompositeWindowParts() const;
400
524cb040
VZ
401 // Implementation of AppendColumn().
402 int DoInsertColumn(const wxString& title,
403 int pos, // May be -1 meaning "append".
404 int width,
405 wxAlignment align,
406 int flags);
407
408 // Common part of {Append,Insert,Prepend}Item().
409 wxTreeListItem DoInsertItem(wxTreeListItem parent,
410 wxTreeListItem previous,
411 const wxString& text,
412 int imageClosed,
413 int imageOpened,
414 wxClientData* data);
415
da2e758f
VZ
416 // Send wxTreeListEvent corresponding to the given wxDataViewEvent for an
417 // item (as opposed for column-oriented events).
524cb040
VZ
418 //
419 // Also updates the original event "skipped" and "vetoed" flags.
da2e758f
VZ
420 void SendItemEvent(wxEventType evt, wxDataViewEvent& event);
421
422 // Send wxTreeListEvent corresponding to the given column wxDataViewEvent.
423 void SendColumnEvent(wxEventType evt, wxDataViewEvent& event);
524cb040
VZ
424
425
426 // Called by wxTreeListModel when an item is toggled by the user.
427 void OnItemToggled(wxTreeListItem item, wxCheckBoxState stateOld);
428
429 // Event handlers.
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);
da2e758f 435 void OnColumnSorted(wxDataViewEvent& event);
524cb040
VZ
436 void OnSize(wxSizeEvent& event);
437
438 wxDECLARE_EVENT_TABLE();
439
440
441 wxDataViewCtrl* m_view;
442 wxTreeListModel* m_model;
443
da2e758f
VZ
444 wxTreeListItemComparator* m_comparator;
445
524cb040
VZ
446
447 // It calls our inherited protected wxWithImages::GetImage() method.
448 friend class wxTreeListModel;
449
450 wxDECLARE_NO_COPY_CLASS(wxTreeListCtrl);
451};
452
453// ----------------------------------------------------------------------------
454// wxTreeListEvent: event generated by wxTreeListCtrl.
455// ----------------------------------------------------------------------------
456
e1b8b76f 457class WXDLLIMPEXP_ADV wxTreeListEvent : public wxNotifyEvent
524cb040
VZ
458{
459public:
f81ccc11
VZ
460 // Default ctor is provided for wxRTTI needs only but should never be used.
461 wxTreeListEvent() { Init(); }
462
da2e758f
VZ
463 // The item affected by the event. Valid for all events except
464 // column-specific ones such as COLUMN_SORTED.
524cb040
VZ
465 wxTreeListItem GetItem() const { return m_item; }
466
467 // The previous state of the item checkbox for ITEM_CHECKED events only.
468 wxCheckBoxState GetOldCheckedState() const { return m_oldCheckedState; }
469
da2e758f
VZ
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; }
524cb040
VZ
473
474 virtual wxEvent* Clone() const { return new wxTreeListEvent(*this); }
475
476private:
f81ccc11
VZ
477 // Common part of all ctors.
478 void Init()
479 {
480 m_column = static_cast<unsigned>(-1);
481
482 m_oldCheckedState = wxCHK_UNDETERMINED;
483 }
484
524cb040
VZ
485 // Ctor is private, only wxTreeListCtrl can create events of this type.
486 wxTreeListEvent(wxEventType evtType,
487 wxTreeListCtrl* treelist,
488 wxTreeListItem item)
489 : wxNotifyEvent(evtType, treelist->GetId()),
490 m_item(item)
491 {
492 SetEventObject(treelist);
da2e758f 493
f81ccc11 494 Init();
524cb040
VZ
495 }
496
497 // Set the checkbox state before this event for ITEM_CHECKED events.
498 void SetOldCheckedState(wxCheckBoxState state)
499 {
500 m_oldCheckedState = state;
501 }
502
da2e758f
VZ
503 // Set the column affected by this event for COLUMN_SORTED events.
504 void SetColumn(unsigned column)
505 {
506 m_column = column;
507 }
508
524cb040
VZ
509
510 const wxTreeListItem m_item;
511
512 wxCheckBoxState m_oldCheckedState;
513
da2e758f
VZ
514 unsigned m_column;
515
524cb040
VZ
516 friend class wxTreeListCtrl;
517
e1b8b76f 518 wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxTreeListEvent);
524cb040
VZ
519};
520
521// Event types and event table macros.
522
523typedef void (wxEvtHandler::*wxTreeListEventFunction)(wxTreeListEvent&);
524
525#define wxTreeListEventHandler(func) \
526 wxEVENT_HANDLER_CAST(wxTreeListEventFunction, func)
527
528#define wxEVT_TREELIST_GENERIC(name, id, fn) \
529 wx__DECLARE_EVT1(wxEVT_COMMAND_TREELIST_##name, id, wxTreeListEventHandler(fn))
530
531#define wxDECLARE_TREELIST_EVENT(name) \
532 wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_ADV, \
533 wxEVT_COMMAND_TREELIST_##name, \
534 wxTreeListEvent)
535
536wxDECLARE_TREELIST_EVENT(SELECTION_CHANGED);
537#define EVT_TREELIST_SELECTION_CHANGED(id, fn) \
538 wxEVT_TREELIST_GENERIC(SELECTION_CHANGED, id, fn)
539
540wxDECLARE_TREELIST_EVENT(ITEM_EXPANDING);
541#define EVT_TREELIST_ITEM_EXPANDING(id, fn) \
542 wxEVT_TREELIST_GENERIC(ITEM_EXPANDING, id, fn)
543
544wxDECLARE_TREELIST_EVENT(ITEM_EXPANDED);
545#define EVT_TREELIST_ITEM_EXPANDED(id, fn) \
546 wxEVT_TREELIST_GENERIC(ITEM_EXPANDED, id, fn)
547
548wxDECLARE_TREELIST_EVENT(ITEM_CHECKED);
549#define EVT_TREELIST_ITEM_CHECKED(id, fn) \
550 wxEVT_TREELIST_GENERIC(ITEM_CHECKED, id, fn)
551
552wxDECLARE_TREELIST_EVENT(ITEM_ACTIVATED);
553#define EVT_TREELIST_ITEM_ACTIVATED(id, fn) \
554 wxEVT_TREELIST_GENERIC(ITEM_ACTIVATED, id, fn)
555
556wxDECLARE_TREELIST_EVENT(ITEM_CONTEXT_MENU);
557#define EVT_TREELIST_ITEM_CONTEXT_MENU(id, fn) \
558 wxEVT_TREELIST_GENERIC(ITEM_CONTEXT_MENU, id, fn)
559
da2e758f
VZ
560wxDECLARE_TREELIST_EVENT(COLUMN_SORTED);
561#define EVT_TREELIST_COLUMN_SORTED(id, fn) \
562 wxEVT_TREELIST_GENERIC(COLUMN_SORTED, id, fn)
563
524cb040
VZ
564#undef wxDECLARE_TREELIST_EVENT
565
566#endif // wxUSE_TREELISTCTRL
567
568#endif // _WX_TREELIST_H_