1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/generic/treectlg.h
3 // Purpose:     wxTreeCtrl class
4 // Author:      Robert Roebling
5 // Modified by:
6 // Created:     01/02/97
7 // RCS-ID:      $Id: treectlg.h,v 1.1 2006/12/02 15:58:29 scara Exp $
8 // Copyright:   (c) 1997,1998 Robert Roebling
9 // Licence:     wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _GENERIC_TREECTRL_H_
13 #define _GENERIC_TREECTRL_H_
14 
15 #if defined(__GNUG__) && !defined(__APPLE__)
16     #pragma interface "treectlg.h"
17 #endif
18 
19 #if wxUSE_TREECTRL
20 
21 #include "wx/scrolwin.h"
22 #include "wx/pen.h"
23 #include "wx/imaglist.h"
24 
25 // -----------------------------------------------------------------------------
26 // forward declaration
27 // -----------------------------------------------------------------------------
28 
29 class WXDLLEXPORT wxGenericTreeItem;
30 
31 class WXDLLEXPORT wxTreeItemData;
32 
33 class WXDLLEXPORT wxTreeRenameTimer;
34 class WXDLLEXPORT wxTreeFindTimer;
35 class WXDLLEXPORT wxTreeTextCtrl;
36 class WXDLLEXPORT wxTextCtrl;
37 
38 // -----------------------------------------------------------------------------
39 // wxGenericTreeCtrl - the tree control
40 // -----------------------------------------------------------------------------
41 
42 class WXDLLEXPORT wxGenericTreeCtrl : public wxScrolledWindow
43 {
44 public:
45     // creation
46     // --------
wxGenericTreeCtrl()47     wxGenericTreeCtrl() { Init(); }
48 
49     wxGenericTreeCtrl(wxWindow *parent, wxWindowID id = -1,
50                const wxPoint& pos = wxDefaultPosition,
51                const wxSize& size = wxDefaultSize,
52                long style = wxTR_DEFAULT_STYLE,
53                const wxValidator &validator = wxDefaultValidator,
54                const wxString& name = wxTreeCtrlNameStr)
55     {
56         Init();
57         Create(parent, id, pos, size, style, validator, name);
58     }
59 
60     virtual ~wxGenericTreeCtrl();
61 
62     bool Create(wxWindow *parent, wxWindowID id = -1,
63                 const wxPoint& pos = wxDefaultPosition,
64                 const wxSize& size = wxDefaultSize,
65                 long style = wxTR_DEFAULT_STYLE,
66                 const wxValidator &validator = wxDefaultValidator,
67                 const wxString& name = wxTreeCtrlNameStr);
68 
69     // accessors
70     // ---------
71 
72         // get the total number of items in the control
73     size_t GetCount() const;
74 
75         // indent is the number of pixels the children are indented relative to
76         // the parents position. SetIndent() also redraws the control
77         // immediately.
GetIndent()78     unsigned int GetIndent() const { return m_indent; }
79     void SetIndent(unsigned int indent);
80 
81         // spacing is the number of pixels between the start and the Text
GetSpacing()82     unsigned int GetSpacing() const { return m_spacing; }
83     void SetSpacing(unsigned int spacing);
84 
85         // image list: these functions allow to associate an image list with
86         // the control and retrieve it. Note that when assigned with
87         // SetImageList, the control does _not_ delete
88         // the associated image list when it's deleted in order to allow image
89         // lists to be shared between different controls. If you use
90         // AssignImageList, the control _does_ delete the image list.
91         //
92         // The normal image list is for the icons which correspond to the
93         // normal tree item state (whether it is selected or not).
94         // Additionally, the application might choose to show a state icon
95         // which corresponds to an app-defined item state (for example,
96         // checked/unchecked) which are taken from the state image list.
97     wxImageList *GetImageList() const;
98     wxImageList *GetStateImageList() const;
99     wxImageList *GetButtonsImageList() const;
100 
101     void SetImageList(wxImageList *imageList);
102     void SetStateImageList(wxImageList *imageList);
103     void SetButtonsImageList(wxImageList *imageList);
104     void AssignImageList(wxImageList *imageList);
105     void AssignStateImageList(wxImageList *imageList);
106     void AssignButtonsImageList(wxImageList *imageList);
107 
108     // Functions to work with tree ctrl items.
109 
110     // accessors
111     // ---------
112 
113         // retrieve item's label
114     wxString GetItemText(const wxTreeItemId& item) const;
115         // get one of the images associated with the item (normal by default)
116     int GetItemImage(const wxTreeItemId& item,
117                      wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
118         // get the data associated with the item
119     wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
120 
121         // get the item's text colour
122     wxColour GetItemTextColour(const wxTreeItemId& item) const;
123 
124         // get the item's background colour
125     wxColour GetItemBackgroundColour(const wxTreeItemId& item) const;
126 
127         // get the item's font
128     wxFont GetItemFont(const wxTreeItemId& item) const;
129 
130     // modifiers
131     // ---------
132 
133         // set item's label
134     void SetItemText(const wxTreeItemId& item, const wxString& text);
135         // get one of the images associated with the item (normal by default)
136     void SetItemImage(const wxTreeItemId& item, int image,
137                       wxTreeItemIcon which = wxTreeItemIcon_Normal);
138         // associate some data with the item
139     void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
140 
141         // force appearance of [+] button near the item. This is useful to
142         // allow the user to expand the items which don't have any children now
143         // - but instead add them only when needed, thus minimizing memory
144         // usage and loading time.
145     void SetItemHasChildren(const wxTreeItemId& item, bool has = TRUE);
146 
147         // the item will be shown in bold
148     void SetItemBold(const wxTreeItemId& item, bool bold = TRUE);
149 
150         // set the item's text colour
151     void SetItemTextColour(const wxTreeItemId& item, const wxColour& col);
152 
153         // set the item's background colour
154     void SetItemBackgroundColour(const wxTreeItemId& item, const wxColour& col);
155 
156         // set the item's font (should be of the same height for all items)
157     void SetItemFont(const wxTreeItemId& item, const wxFont& font);
158 
159         // set the window font
160     virtual bool SetFont( const wxFont &font );
161 
162        // set the styles.  No need to specify a GetWindowStyle here since
163        // the base wxWindow member function will do it for us
164     void SetWindowStyle(const long styles);
165 
166     // item status inquiries
167     // ---------------------
168 
169         // is the item visible (it might be outside the view or not expanded)?
170     bool IsVisible(const wxTreeItemId& item) const;
171         // does the item has any children?
HasChildren(const wxTreeItemId & item)172     bool HasChildren(const wxTreeItemId& item) const
173       { return ItemHasChildren(item); }
174     bool ItemHasChildren(const wxTreeItemId& item) const;
175         // is the item expanded (only makes sense if HasChildren())?
176     bool IsExpanded(const wxTreeItemId& item) const;
177         // is this item currently selected (the same as has focus)?
178     bool IsSelected(const wxTreeItemId& item) const;
179         // is item text in bold font?
180     bool IsBold(const wxTreeItemId& item) const;
181         // does the layout include space for a button?
182 
183     // number of children
184     // ------------------
185 
186         // if 'recursively' is FALSE, only immediate children count, otherwise
187         // the returned number is the number of all items in this branch
188     size_t GetChildrenCount(const wxTreeItemId& item, bool recursively = TRUE);
189 
190     // navigation
191     // ----------
192 
193     // wxTreeItemId.IsOk() will return FALSE if there is no such item
194 
195         // get the root tree item
GetRootItem()196     wxTreeItemId GetRootItem() const { return m_anchor; }
197 
198         // get the item currently selected (may return NULL if no selection)
GetSelection()199     wxTreeItemId GetSelection() const { return m_current; }
200 
201         // get the items currently selected, return the number of such item
202     size_t GetSelections(wxArrayTreeItemIds&) const;
203 
204         // get the parent of this item (may return NULL if root)
205     wxTreeItemId GetItemParent(const wxTreeItemId& item) const;
206 
207 #if WXWIN_COMPATIBILITY_2_2
208         // deprecated:  Use GetItemParent instead.
GetParent(const wxTreeItemId & item)209     wxTreeItemId GetParent(const wxTreeItemId& item) const
210     	{ return GetItemParent( item ); }
211 
212     	// Expose the base class method hidden by the one above.
GetParent()213     wxWindow *GetParent() const { return wxScrolledWindow::GetParent(); }
214 #endif  // WXWIN_COMPATIBILITY_2_2
215 
216         // for this enumeration function you must pass in a "cookie" parameter
217         // which is opaque for the application but is necessary for the library
218         // to make these functions reentrant (i.e. allow more than one
219         // enumeration on one and the same object simultaneously). Of course,
220         // the "cookie" passed to GetFirstChild() and GetNextChild() should be
221         // the same!
222 
223         // get the first child of this item
224     wxTreeItemId GetFirstChild(const wxTreeItemId& item, long& cookie) const;
225         // get the next child
226     wxTreeItemId GetNextChild(const wxTreeItemId& item, long& cookie) const;
227         // get the last child of this item - this method doesn't use cookies
228     wxTreeItemId GetLastChild(const wxTreeItemId& item) const;
229 
230         // get the next sibling of this item
231     wxTreeItemId GetNextSibling(const wxTreeItemId& item) const;
232         // get the previous sibling
233     wxTreeItemId GetPrevSibling(const wxTreeItemId& item) const;
234 
235         // get first visible item
236     wxTreeItemId GetFirstVisibleItem() const;
237         // get the next visible item: item must be visible itself!
238         // see IsVisible() and wxTreeCtrl::GetFirstVisibleItem()
239     wxTreeItemId GetNextVisible(const wxTreeItemId& item) const;
240         // get the previous visible item: item must be visible itself!
241     wxTreeItemId GetPrevVisible(const wxTreeItemId& item) const;
242 
243         // Only for internal use right now, but should probably be public
244     wxTreeItemId GetNext(const wxTreeItemId& item) const;
245 
246     // operations
247     // ----------
248 
249         // add the root node to the tree
250     wxTreeItemId AddRoot(const wxString& text,
251                          int image = -1, int selectedImage = -1,
252                          wxTreeItemData *data = NULL);
253 
254         // insert a new item in as the first child of the parent
255     wxTreeItemId PrependItem(const wxTreeItemId& parent,
256                              const wxString& text,
257                              int image = -1, int selectedImage = -1,
258                              wxTreeItemData *data = NULL);
259 
260         // insert a new item after a given one
261     wxTreeItemId InsertItem(const wxTreeItemId& parent,
262                             const wxTreeItemId& idPrevious,
263                             const wxString& text,
264                             int image = -1, int selectedImage = -1,
265                             wxTreeItemData *data = NULL);
266 
267         // insert a new item before the one with the given index
268     wxTreeItemId InsertItem(const wxTreeItemId& parent,
269                             size_t index,
270                             const wxString& text,
271                             int image = -1, int selectedImage = -1,
272                             wxTreeItemData *data = NULL);
273 
274         // insert a new item in as the last child of the parent
275     wxTreeItemId AppendItem(const wxTreeItemId& parent,
276                             const wxString& text,
277                             int image = -1, int selectedImage = -1,
278                             wxTreeItemData *data = NULL);
279 
280         // delete this item and associated data if any
281     void Delete(const wxTreeItemId& item);
282         // delete all children (but don't delete the item itself)
283         // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
284     void DeleteChildren(const wxTreeItemId& item);
285         // delete all items from the tree
286         // NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
287     void DeleteAllItems();
288 
289         // expand this item
290     void Expand(const wxTreeItemId& item);
291         // expand this item and all subitems recursively
292     void ExpandAll(const wxTreeItemId& item);
293         // collapse the item without removing its children
294     void Collapse(const wxTreeItemId& item);
295         // collapse the item and remove all children
296     void CollapseAndReset(const wxTreeItemId& item);
297         // toggles the current state
298     void Toggle(const wxTreeItemId& item);
299 
300         // remove the selection from currently selected item (if any)
301     void Unselect();
302     void UnselectAll();
303         // select this item
304     void SelectItem(const wxTreeItemId& item, bool unselect_others=TRUE, bool extended_select=FALSE);
305         // make sure this item is visible (expanding the parent item and/or
306         // scrolling to this item if necessary)
307     void EnsureVisible(const wxTreeItemId& item);
308         // scroll to this item (but don't expand its parent)
309     void ScrollTo(const wxTreeItemId& item);
310     void AdjustMyScrollbars();
311 
312         // The first function is more portable (because easier to implement
313         // on other platforms), but the second one returns some extra info.
HitTest(const wxPoint & point)314     wxTreeItemId HitTest(const wxPoint& point)
315         { int dummy; return HitTest(point, dummy); }
316     wxTreeItemId HitTest(const wxPoint& point, int& flags);
317 
318         // get the bounding rectangle of the item (or of its label only)
319     bool GetBoundingRect(const wxTreeItemId& item,
320                          wxRect& rect,
321                          bool textOnly = FALSE) const;
322 
323         // Start editing the item label: this (temporarily) replaces the item
324         // with a one line edit control. The item will be selected if it hadn't
325         // been before.
EditLabel(const wxTreeItemId & item)326     void EditLabel( const wxTreeItemId& item ) { Edit( item ); }
327     void Edit( const wxTreeItemId& item );
328         // returns a pointer to the text edit control if the item is being
329         // edited, NULL otherwise (it's assumed that no more than one item may
330         // be edited simultaneously)
331     wxTextCtrl* GetEditControl() const;
332 
333     // sorting
334         // this function is called to compare 2 items and should return -1, 0
335         // or +1 if the first item is less than, equal to or greater than the
336         // second one. The base class version performs alphabetic comparaison
337         // of item labels (GetText)
338     virtual int OnCompareItems(const wxTreeItemId& item1,
339                                const wxTreeItemId& item2);
340         // sort the children of this item using OnCompareItems
341         //
342         // NB: this function is not reentrant and not MT-safe (FIXME)!
343     void SortChildren(const wxTreeItemId& item);
344 
345     // deprecated functions: use Set/GetItemImage directly
346         // get the selected item image
GetItemSelectedImage(const wxTreeItemId & item)347     int GetItemSelectedImage(const wxTreeItemId& item) const
348         { return GetItemImage(item, wxTreeItemIcon_Selected); }
349         // set the selected item image
SetItemSelectedImage(const wxTreeItemId & item,int image)350     void SetItemSelectedImage(const wxTreeItemId& item, int image)
351         { SetItemImage(item, image, wxTreeItemIcon_Selected); }
352 
353     // implementation only from now on
354 
355     // overridden base class virtuals
356     virtual bool SetBackgroundColour(const wxColour& colour);
357     virtual bool SetForegroundColour(const wxColour& colour);
358 
359     // callbacks
360     void OnPaint( wxPaintEvent &event );
361     void OnSetFocus( wxFocusEvent &event );
362     void OnKillFocus( wxFocusEvent &event );
363     void OnChar( wxKeyEvent &event );
364     void OnMouse( wxMouseEvent &event );
365     void OnIdle( wxIdleEvent &event );
366 
367     // implementation helpers
368 protected:
369     friend class wxGenericTreeItem;
370     friend class wxTreeRenameTimer;
371     friend class wxTreeFindTimer;
372     friend class wxTreeTextCtrl;
373 
374     wxFont               m_normalFont;
375     wxFont               m_boldFont;
376 
377     wxGenericTreeItem   *m_anchor;
378     wxGenericTreeItem   *m_current,
379                         *m_key_current;
380     unsigned short       m_indent;
381     unsigned short       m_spacing;
382     int                  m_lineHeight;
383     wxPen                m_dottedPen;
384     wxBrush             *m_hilightBrush,
385                         *m_hilightUnfocusedBrush;
386     bool                 m_hasFocus;
387     bool                 m_dirty;
388     bool                 m_ownsImageListNormal,
389                          m_ownsImageListState,
390                          m_ownsImageListButtons;
391     bool                 m_isDragging; // true between BEGIN/END drag events
392     bool                 m_lastOnSame;  // last click on the same item as prev
393     wxImageList         *m_imageListNormal,
394                         *m_imageListState,
395                         *m_imageListButtons;
396 
397     int                  m_dragCount;
398     wxPoint              m_dragStart;
399     wxGenericTreeItem   *m_dropTarget;
400     wxCursor             m_oldCursor;  // cursor is changed while dragging
401     wxGenericTreeItem   *m_oldSelection;
402     wxTreeTextCtrl      *m_textCtrl;
403 
404     wxTimer             *m_renameTimer;
405 
406     wxBitmap            *m_arrowRight,
407                         *m_arrowDown;
408 
409     // incremental search data
410     wxString             m_findPrefix;
411     wxTimer             *m_findTimer;
412 
413     // the common part of all ctors
414     void Init();
415 
416     // misc helpers
417     void SendDeleteEvent(wxGenericTreeItem *itemBeingDeleted);
418 
419     void DrawBorder(const wxTreeItemId& item);
420     void DrawLine(const wxTreeItemId& item, bool below);
421     void DrawDropEffect(wxGenericTreeItem *item);
422 
423     wxTreeItemId DoInsertItem(const wxTreeItemId& parent,
424                               size_t previous,
425                               const wxString& text,
426                               int image, int selectedImage,
427                               wxTreeItemData *data);
428 
429     // called by wxTextTreeCtrl when it marks itself for deletion
430     void ResetTextControl();
431 
432     // find the first item starting with the given prefix after the given item
433     wxTreeItemId FindItem(const wxTreeItemId& id, const wxString& prefix) const;
434 
HasButtons(void)435     bool HasButtons(void) const
436         { return (m_imageListButtons != NULL)
437               || HasFlag(wxTR_TWIST_BUTTONS|wxTR_HAS_BUTTONS); }
438 
439     void CalculateLineHeight();
440     int  GetLineHeight(wxGenericTreeItem *item) const;
441     void PaintLevel( wxGenericTreeItem *item, wxDC& dc, int level, int &y );
442     void PaintItem( wxGenericTreeItem *item, wxDC& dc);
443 
444     void CalculateLevel( wxGenericTreeItem *item, wxDC &dc, int level, int &y );
445     void CalculatePositions();
446     void CalculateSize( wxGenericTreeItem *item, wxDC &dc );
447 
448     void RefreshSubtree( wxGenericTreeItem *item );
449     void RefreshLine( wxGenericTreeItem *item );
450 
451     // redraw all selected items
452     void RefreshSelected();
453 
454     // RefreshSelected() recursive helper
455     void RefreshSelectedUnder(wxGenericTreeItem *item);
456 
457     void OnRenameTimer();
458     bool OnRenameAccept(wxGenericTreeItem *item, const wxString& value);
459     void OnRenameCancelled(wxGenericTreeItem *item);
460 
461     void FillArray(wxGenericTreeItem*, wxArrayTreeItemIds&) const;
462     void SelectItemRange( wxGenericTreeItem *item1, wxGenericTreeItem *item2 );
463     bool TagAllChildrenUntilLast(wxGenericTreeItem *crt_item, wxGenericTreeItem *last_item, bool select);
464     bool TagNextChildren(wxGenericTreeItem *crt_item, wxGenericTreeItem *last_item, bool select);
465     void UnselectAllChildren( wxGenericTreeItem *item );
466 
467 private:
468     DECLARE_EVENT_TABLE()
469     DECLARE_DYNAMIC_CLASS(wxGenericTreeCtrl)
470 };
471 
472 #if !defined(__WXMSW__) || defined(__WIN16__) || defined(__WXUNIVERSAL__)
473 /*
474  * wxTreeCtrl has to be a real class or we have problems with
475  * the run-time information.
476  */
477 
478 class WXDLLEXPORT wxTreeCtrl: public wxGenericTreeCtrl
479 {
DECLARE_DYNAMIC_CLASS(wxTreeCtrl)480     DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
481 
482 public:
483     wxTreeCtrl() {}
484 
485     wxTreeCtrl(wxWindow *parent, wxWindowID id = -1,
486                const wxPoint& pos = wxDefaultPosition,
487                const wxSize& size = wxDefaultSize,
488                long style = wxTR_DEFAULT_STYLE,
489                const wxValidator &validator = wxDefaultValidator,
490                const wxString& name = wxTreeCtrlNameStr)
wxGenericTreeCtrl(parent,id,pos,size,style,validator,name)491     : wxGenericTreeCtrl(parent, id, pos, size, style, validator, name)
492     {
493     }
494 };
495 #endif // !__WXMSW__ || __WIN16__ || __WXUNIVERSAL__
496 
497 #endif // wxUSE_TREECTRL
498 
499 #endif // _GENERIC_TREECTRL_H_
500 
501