1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/msw/treectrl.h
3 // Purpose:     wxTreeCtrl class
4 // Author:      Julian Smart
5 // Modified by: Vadim Zeitlin to be less MSW-specific on 10/10/98
6 // Created:     01/02/97
7 // RCS-ID:      $Id: treectrl.h,v 1.1 2006/12/02 15:58:47 scara Exp $
8 // Copyright:   (c) Julian Smart and Markus Holzem
9 // Licence:     wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_TREECTRL_H_
13 #define _WX_TREECTRL_H_
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 #ifdef __GNUG__
20     #pragma interface "treectrl.h"
21 #endif
22 
23 #if wxUSE_TREECTRL
24 
25 #include "wx/textctrl.h"
26 #include "wx/dynarray.h"
27 #include "wx/treebase.h"
28 
29 #ifdef __GNUWIN32__
30     // Cygwin windows.h defines these identifiers
31     #undef GetFirstChild
32     #undef GetNextSibling
33 #endif // Cygwin
34 
35 // the type for "untyped" data
36 typedef long wxDataType;
37 
38 // fwd decl
39 class  WXDLLEXPORT wxImageList;
40 class  WXDLLEXPORT wxDragImage;
41 struct WXDLLEXPORT wxTreeViewItem;
42 
43 // a callback function used for sorting tree items, it should return -1 if the
44 // first item precedes the second, +1 if the second precedes the first or 0 if
45 // they're equivalent
46 class wxTreeItemData;
47 
48 // NB: all the following flags are for compatbility only and will be removed in the
49 //     next versions
50 
51 // flags for deprecated `Expand(int action)'
52 enum
53 {
54     wxTREE_EXPAND_EXPAND,
55     wxTREE_EXPAND_COLLAPSE,
56     wxTREE_EXPAND_COLLAPSE_RESET,
57     wxTREE_EXPAND_TOGGLE
58 };
59 
60 // flags for deprecated InsertItem() variant
61 #define wxTREE_INSERT_FIRST 0xFFFF0001
62 #define wxTREE_INSERT_LAST  0xFFFF0002
63 
64 // ----------------------------------------------------------------------------
65 // wxTreeCtrl
66 // ----------------------------------------------------------------------------
67 class WXDLLEXPORT wxTreeCtrl : public wxControl
68 {
69 public:
70     // creation
71     // --------
wxTreeCtrl()72     wxTreeCtrl() { Init(); }
73 
74     wxTreeCtrl(wxWindow *parent, wxWindowID id = -1,
75                const wxPoint& pos = wxDefaultPosition,
76                const wxSize& size = wxDefaultSize,
77                long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
78                const wxValidator& validator = wxDefaultValidator,
79                const wxString& name = wxTreeCtrlNameStr)
80     {
81         Create(parent, id, pos, size, style, validator, name);
82     }
83 
84     virtual ~wxTreeCtrl();
85 
86     bool Create(wxWindow *parent, wxWindowID id = -1,
87                 const wxPoint& pos = wxDefaultPosition,
88                 const wxSize& size = wxDefaultSize,
89                 long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT,
90                 const wxValidator& validator = wxDefaultValidator,
91                 const wxString& name = wxTreeCtrlNameStr);
92 
93     // accessors
94     // ---------
95 
96         // get the total number of items in the control
97     size_t GetCount() const;
98 
99         // indent is the number of pixels the children are indented relative to
100         // the parents position. SetIndent() also redraws the control
101         // immediately.
102     unsigned int GetIndent() const;
103     void SetIndent(unsigned int indent);
104 
105     // spacing is the number of pixels between the start and the Text
106         // not implemented under wxMSW
GetSpacing()107     unsigned int GetSpacing() const { return 18; } // return wxGTK default
SetSpacing(unsigned int WXUNUSED (spacing))108     void SetSpacing(unsigned int WXUNUSED(spacing)) { }
109 
110         // image list: these functions allow to associate an image list with
111         // the control and retrieve it. Note that the control does _not_ delete
112         // the associated image list when it's deleted in order to allow image
113         // lists to be shared between different controls.
114         //
115         // The normal image list is for the icons which correspond to the
116         // normal tree item state (whether it is selected or not).
117         // Additionally, the application might choose to show a state icon
118         // which corresponds to an app-defined item state (for example,
119         // checked/unchecked) which are taken from the state image list.
120     wxImageList *GetImageList() const;
121     wxImageList *GetStateImageList() const;
122 
123     void SetImageList(wxImageList *imageList);
124     void SetStateImageList(wxImageList *imageList);
125     void AssignImageList(wxImageList *imageList);
126     void AssignStateImageList(wxImageList *imageList);
127 
128     // Functions to work with tree ctrl items. Unfortunately, they can _not_ be
129     // member functions of wxTreeItem because they must know the tree the item
130     // belongs to for Windows implementation and storing the pointer to
131     // wxTreeCtrl in each wxTreeItem is just too much waste.
132 
133     // accessors
134     // ---------
135 
136         // retrieve items label
137     wxString GetItemText(const wxTreeItemId& item) const;
138         // get one of the images associated with the item (normal by default)
139     int GetItemImage(const wxTreeItemId& item,
140                      wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
141         // get the data associated with the item
142     wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
143 
144         // get the item's text colour
145     wxColour GetItemTextColour(const wxTreeItemId& item) const;
146 
147         // get the item's background colour
148     wxColour GetItemBackgroundColour(const wxTreeItemId& item) const;
149 
150         // get the item's font
151     wxFont GetItemFont(const wxTreeItemId& item) const;
152 
153     // modifiers
154     // ---------
155 
156         // set items label
157     void SetItemText(const wxTreeItemId& item, const wxString& text);
158         // get one of the images associated with the item (normal by default)
159     void SetItemImage(const wxTreeItemId& item, int image,
160                       wxTreeItemIcon which = wxTreeItemIcon_Normal);
161         // associate some data with the item
162     void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
163 
164         // force appearance of [+] button near the item. This is useful to
165         // allow the user to expand the items which don't have any children now
166         // - but instead add them only when needed, thus minimizing memory
167         // usage and loading time.
168     void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE);
169 
170         // the item will be shown in bold
171     void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
172 
173         // the item will be shown with a drop highlight
174     void SetItemDropHighlight(const wxTreeItemId& item, bool highlight = TRUE);
175 
176         // set the items text colour
177     void SetItemTextColour(const wxTreeItemId& item, const wxColour& col);
178 
179         // set the items background colour
180     void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col);
181 
182         // set the items font (should be of the same height for all items)
183     void SetItemFont(const wxTreeItemId& item, const wxFont& font);
184 
185     // item status inquiries
186     // ---------------------
187 
188         // is the item visible (it might be outside the view or not expanded)?
189     bool IsVisible(const wxTreeItemId& item) const;
190         // does the item has any children?
191     bool ItemHasChildren(const wxTreeItemId& item) const;
192         // is the item expanded (only makes sense if HasChildren())?
193     bool IsExpanded(const wxTreeItemId& item) const;
194         // is this item currently selected (the same as has focus)?
195     bool IsSelected(const wxTreeItemId& item) const;
196         // is item text in bold font?
197     bool IsBold(const wxTreeItemId& item) const;
198 
199     // number of children
200     // ------------------
201 
202         // if 'recursively' is FALSE, only immediate children count, otherwise
203         // the returned number is the number of all items in this branch
204     size_t GetChildrenCount(const wxTreeItemId& item,
205                             bool recursively = TRUE) const;
206 
207     // navigation
208     // ----------
209 
210     // wxTreeItemId.IsOk() will return FALSE if there is no such item
211 
212         // get the root tree item
213     wxTreeItemId GetRootItem() const;
214 
215         // get the item currently selected (may return NULL if no selection)
216     wxTreeItemId GetSelection() const;
217 
218         // get the items currently selected, return the number of such item
219         //
220         // NB: this operation is expensive and can take a long time for a
221         //     control with a lot of items (~ O(number of items)).
222     size_t GetSelections(wxArrayTreeItemIds& selections) const;
223 
224         // get the parent of this item (may return NULL if root)
225     wxTreeItemId GetItemParent(const wxTreeItemId& item) const;
226 
227 #if WXWIN_COMPATIBILITY_2_2
228         // deprecated:  Use GetItemParent instead.
GetParent(const wxTreeItemId & item)229     wxTreeItemId GetParent(const wxTreeItemId& item) const
230     	{ return GetItemParent( item ); }
231 
232     	// Expose the base class method hidden by the one above.
GetParent()233     wxWindow *GetParent() const { return wxControl::GetParent(); }
234 #endif  // WXWIN_COMPATIBILITY_2_2
235 
236         // for this enumeration function you must pass in a "cookie" parameter
237         // which is opaque for the application but is necessary for the library
238         // to make these functions reentrant (i.e. allow more than one
239         // enumeration on one and the same object simultaneously). Of course,
240         // the "cookie" passed to GetFirstChild() and GetNextChild() should be
241         // the same!
242 
243         // get the first child of this item
244     wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& _cookie) const;
245         // get the next child
246     wxTreeItemId GetNextChild(const wxTreeItemId& item, long& _cookie) const;
247         // get the last child of this item - this method doesn't use cookies
248     wxTreeItemId GetLastChild(const wxTreeItemId& item) const;
249 
250         // get the next sibling of this item
251     wxTreeItemId GetNextSibling(const wxTreeItemId& item) const;
252         // get the previous sibling
253     wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const;
254 
255         // get first visible item
256     wxTreeItemId GetFirstVisibleItem() const;
257         // get the next visible item: item must be visible itself!
258         // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem()
259     wxTreeItemId GetNextVisible(const wxTreeItemId& item) const;
260         // get the previous visible item: item must be visible itself!
261     wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const;
262 
263     // operations
264     // ----------
265 
266         // add the root node to the tree
267     wxTreeItemId AddRoot(const wxString& text,
268                          int image = -1, int selectedImage = -1,
269                          wxTreeItemData *data = NULL);
270 
271         // insert a new item in as the first child of the parent
272     wxTreeItemId PrependItem(const wxTreeItemId& parent,
273                              const wxString& text,
274                              int image = -1, int selectedImage = -1,
275                              wxTreeItemData *data = NULL);
276 
277         // insert a new item after a given one
278     wxTreeItemId InsertItem(const wxTreeItemId& parent,
279                             const wxTreeItemId& idPrevious,
280                             const wxString& text,
281                             int image = -1, int selectedImage = -1,
282                             wxTreeItemData *data = NULL);
283 
284         // insert a new item before the one with the given index
285     wxTreeItemId InsertItem(const wxTreeItemId& parent,
286                             size_t index,
287                             const wxString& text,
288                             int image = -1, int selectedImage = -1,
289                             wxTreeItemData *data = NULL);
290 
291         // insert a new item in as the last child of the parent
292     wxTreeItemId AppendItem(const wxTreeItemId& parent,
293                             const wxString& text,
294                             int image = -1, int selectedImage = -1,
295                             wxTreeItemData *data = NULL);
296 
297         // delete this item and associated data if any
298     void Delete(const wxTreeItemId& item);
299         // delete all children (but don't delete the item itself)
300         // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
301     void DeleteChildren(const wxTreeItemId& item);
302         // delete all items from the tree
303         // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
304     void DeleteAllItems();
305 
306         // expand this item
307     void Expand(const wxTreeItemId& item);
308         // collapse the item without removing its children
309     void Collapse(const wxTreeItemId& item);
310         // collapse the item and remove all children
311     void CollapseAndReset(const wxTreeItemId& item);
312         // toggles the current state
313     void Toggle(const wxTreeItemId& item);
314 
315         // remove the selection from currently selected item (if any)
316     void Unselect();
317         // unselect all items (only makes sense for multiple selection control)
318     void UnselectAll();
319         // select this item
320     void SelectItem(const wxTreeItemId& item);
321         // make sure this item is visible (expanding the parent item and/or
322         // scrolling to this item if necessary)
323     void EnsureVisible(const wxTreeItemId& item);
324         // scroll to this item (but don't expand its parent)
325     void ScrollTo(const wxTreeItemId& item);
326 
327         // start editing the item label: this (temporarily) replaces the item
328         // with a one line edit control. The item will be selected if it hadn't
329         // been before. textCtrlClass parameter allows you to create an edit
330         // control of arbitrary user-defined class deriving from wxTextCtrl.
331     wxTextCtrl* EditLabel(const wxTreeItemId& item,
332                           wxClassInfo* textCtrlClass = CLASSINFO(wxTextCtrl));
333         // returns the same pointer as StartEdit() if the item is being edited,
334         // NULL otherwise (it's assumed that no more than one item may be
335         // edited simultaneously)
336     wxTextCtrl* GetEditControl() const;
337         // end editing and accept or discard the changes to item label
338     void EndEditLabel(const wxTreeItemId& item, bool discardChanges = FALSE);
339 
340     // sorting
341         // this function is called to compare 2 items and should return -1, 0
342         // or +1 if the first item is less than, equal to or greater than the
343         // second one. The base class version performs alphabetic comparaison
344         // of item labels (GetText)
345     virtual int OnCompareItems(const wxTreeItemId& item1,
346                                const wxTreeItemId& item2);
347         // sort the children of this item using OnCompareItems
348         //
349         // NB: this function is not reentrant and not MT-safe (FIXME)!
350     void SortChildren(const wxTreeItemId& item);
351 
352     // helpers
353     // -------
354 
355         // determine to which item (if any) belongs the given point (the
356         // coordinates specified are relative to the client area of tree ctrl)
357         // and fill the flags parameter with a bitmask of wxTREE_HITTEST_xxx
358         // constants.
359         //
360         // The first function is more portable (because easier to implement
361         // on other platforms), but the second one returns some extra info.
HitTest(const wxPoint & point)362     wxTreeItemId HitTest(const wxPoint& point)
363         { int dummy; return HitTest(point, dummy); }
364     wxTreeItemId HitTest(const wxPoint& point, int& flags);
365 
366         // get the bounding rectangle of the item (or of its label only)
367     bool GetBoundingRect(const wxTreeItemId& item,
368                          wxRect& rect,
369                          bool textOnly = FALSE) const;
370 
371     // deprecated
372     // ----------
373 
374     // these methods are deprecated and will be removed in future versions of
375     // wxWindows, they're here for compatibility only, don't use them in new
376     // code (the comments indicate why these methods are now useless and how to
377     // replace them)
378 
379         // use Expand, Collapse, CollapseAndReset or Toggle
380     void ExpandItem(const wxTreeItemId& item, int action);
381 
382         // use AddRoot, PrependItem or AppendItem
383     wxTreeItemId InsertItem(const wxTreeItemId& parent,
384                             const wxString& text,
385                             int image = -1, int selImage = -1,
386                             long insertAfter = wxTREE_INSERT_LAST);
387 
388         // use Set/GetImageList and Set/GetStateImageList
GetImageList(int)389     wxImageList *GetImageList(int) const
390         { return GetImageList(); }
SetImageList(wxImageList * imageList,int)391     void SetImageList(wxImageList *imageList, int)
392         { SetImageList(imageList); }
393 
394     // use Set/GetItemImage directly
395         // get the selected item image
GetItemSelectedImage(const wxTreeItemId & item)396     int GetItemSelectedImage(const wxTreeItemId& item) const
397         { return GetItemImage(item, wxTreeItemIcon_Selected); }
398         // set the selected item image
SetItemSelectedImage(const wxTreeItemId & item,int image)399     void SetItemSelectedImage(const wxTreeItemId& item, int image)
400         { SetItemImage(item, image, wxTreeItemIcon_Selected); }
401 
402     // implementation
403     // --------------
404 
405     virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
406     virtual bool MSWCommand(WXUINT param, WXWORD id);
407     virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
408 
409     // override some base class virtuals
410     virtual bool SetBackgroundColour(const wxColour &colour);
411     virtual bool SetForegroundColour(const wxColour &colour);
412 
413     // get/set the check state for the item (only for wxTR_MULTIPLE)
414     bool IsItemChecked(const wxTreeItemId& item) const;
415     void SetItemCheck(const wxTreeItemId& item, bool check = TRUE);
416 
417 protected:
418     // SetImageList helper
419     void SetAnyImageList(wxImageList *imageList, int which);
420 
421     // refresh a single item
422     void RefreshItem(const wxTreeItemId& item);
423 
424     wxTextCtrl  *m_textCtrl;        // used while editing the item label
425     wxImageList *m_imageListNormal, // images for tree elements
426                 *m_imageListState;  // special images for app defined states
427     bool         m_ownsImageListNormal, m_ownsImageListState;
428 
429 private:
430     // the common part of all ctors
431     void Init();
432 
433     // helper functions
434     inline bool DoGetItem(wxTreeViewItem *tvItem) const;
435     inline void DoSetItem(wxTreeViewItem *tvItem);
436 
437     inline void DoExpand(const wxTreeItemId& item, int flag);
438 
439     wxTreeItemId DoInsertItem(const wxTreeItemId& parent,
440                               wxTreeItemId hInsertAfter,
441                               const wxString& text,
442                               int image, int selectedImage,
443                               wxTreeItemData *data);
444 
445     int DoGetItemImageFromData(const wxTreeItemId& item,
446                                wxTreeItemIcon which) const;
447     void DoSetItemImageFromData(const wxTreeItemId& item,
448                                 int image,
449                                 wxTreeItemIcon which) const;
450     void DoSetItemImages(const wxTreeItemId& item, int image, int imageSel);
451 
452     void DeleteTextCtrl();
453 
454     // support for additional item images which we implement using
455     // wxTreeItemIndirectData technique - see the comments in msw/treectrl.cpp
456     void SetIndirectItemData(const wxTreeItemId& item,
457                              class wxTreeItemIndirectData *data);
458     bool HasIndirectData(const wxTreeItemId& item) const;
IsDataIndirect(wxTreeItemData * data)459     bool IsDataIndirect(wxTreeItemData *data) const
460         { return data && data->GetId().m_pItem == 0; }
461 
462     // the hash storing the items attributes (indexed by items ids)
463     wxHashTable m_attrs;
464 
465     // TRUE if the hash above is not empty
466     bool m_hasAnyAttr;
467 
468     // used for dragging
469     wxDragImage *m_dragImage;
470 
471     // Virtual root item, if wxTR_HIDE_ROOT is set.
472     void* m_pVirtualRoot;
473 
474     // the starting item for selection with Shift
475     WXHTREEITEM m_htSelStart;
476 
477     friend class wxTreeItemIndirectData;
478     friend class wxTreeSortHelper;
479 
480     DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
481 };
482 
483 #endif // wxUSE_TREECTRL
484 
485 #endif
486     // _WX_TREECTRL_H_
487