1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Base wxTreeCtrl classes
4 // Author: Julian Smart
8 // Copyright: (c) 1998 Robert Roebling, Julian Smart et al
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // =============================================================================
14 // =============================================================================
16 // -----------------------------------------------------------------------------
18 // -----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
29 #include "wx/treectrl.h"
30 #include "wx/imaglist.h"
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_DRAG
, wxTreeEvent
);
37 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_RDRAG
, wxTreeEvent
);
38 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
, wxTreeEvent
);
39 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_END_LABEL_EDIT
, wxTreeEvent
);
40 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_DELETE_ITEM
, wxTreeEvent
);
41 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_GET_INFO
, wxTreeEvent
);
42 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SET_INFO
, wxTreeEvent
);
43 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_EXPANDED
, wxTreeEvent
);
44 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_EXPANDING
, wxTreeEvent
);
45 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_COLLAPSED
, wxTreeEvent
);
46 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_COLLAPSING
, wxTreeEvent
);
47 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SEL_CHANGED
, wxTreeEvent
);
48 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SEL_CHANGING
, wxTreeEvent
);
49 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_KEY_DOWN
, wxTreeEvent
);
50 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_ACTIVATED
, wxTreeEvent
);
51 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK
, wxTreeEvent
);
52 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK
, wxTreeEvent
);
53 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_END_DRAG
, wxTreeEvent
);
54 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK
, wxTreeEvent
);
55 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP
, wxTreeEvent
);
56 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_MENU
, wxTreeEvent
);
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 wxDEFINE_FLAGS( wxTreeCtrlStyle
)
63 wxBEGIN_FLAGS( wxTreeCtrlStyle
)
64 // new style border flags, we put them first to
65 // use them for streaming out
66 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
67 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
68 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
69 wxFLAGS_MEMBER(wxBORDER_RAISED
)
70 wxFLAGS_MEMBER(wxBORDER_STATIC
)
71 wxFLAGS_MEMBER(wxBORDER_NONE
)
73 // old style border flags
74 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
75 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
76 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
77 wxFLAGS_MEMBER(wxRAISED_BORDER
)
78 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
79 wxFLAGS_MEMBER(wxBORDER
)
81 // standard window styles
82 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
83 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
84 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
85 wxFLAGS_MEMBER(wxWANTS_CHARS
)
86 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
87 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
88 wxFLAGS_MEMBER(wxVSCROLL
)
89 wxFLAGS_MEMBER(wxHSCROLL
)
91 wxFLAGS_MEMBER(wxTR_EDIT_LABELS
)
92 wxFLAGS_MEMBER(wxTR_NO_BUTTONS
)
93 wxFLAGS_MEMBER(wxTR_HAS_BUTTONS
)
94 wxFLAGS_MEMBER(wxTR_TWIST_BUTTONS
)
95 wxFLAGS_MEMBER(wxTR_NO_LINES
)
96 wxFLAGS_MEMBER(wxTR_FULL_ROW_HIGHLIGHT
)
97 wxFLAGS_MEMBER(wxTR_LINES_AT_ROOT
)
98 wxFLAGS_MEMBER(wxTR_HIDE_ROOT
)
99 wxFLAGS_MEMBER(wxTR_ROW_LINES
)
100 wxFLAGS_MEMBER(wxTR_HAS_VARIABLE_ROW_HEIGHT
)
101 wxFLAGS_MEMBER(wxTR_SINGLE
)
102 wxFLAGS_MEMBER(wxTR_MULTIPLE
)
103 #if WXWIN_COMPATIBILITY_2_8
104 wxFLAGS_MEMBER(wxTR_EXTENDED
)
106 wxFLAGS_MEMBER(wxTR_DEFAULT_STYLE
)
107 wxEND_FLAGS( wxTreeCtrlStyle
)
109 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl
, wxControl
, "wx/treectrl.h")
111 wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl
)
112 wxEVENT_PROPERTY( TextUpdated
, wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEvent
)
113 wxEVENT_RANGE_PROPERTY( TreeEvent
, wxEVT_COMMAND_TREE_BEGIN_DRAG
, \
114 wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK
, wxTreeEvent
)
116 wxPROPERTY_FLAGS( WindowStyle
, wxTreeCtrlStyle
, long, SetWindowStyleFlag
, \
117 GetWindowStyleFlag
, wxEMPTY_PARAMETER_VALUE
, 0 /*flags*/, \
118 wxT("Helpstring"), wxT("group")) // style
119 wxEND_PROPERTIES_TABLE()
121 wxEMPTY_HANDLERS_TABLE(wxTreeCtrl
)
123 wxCONSTRUCTOR_5( wxTreeCtrl
, wxWindow
*, Parent
, wxWindowID
, Id
, \
124 wxPoint
, Position
, wxSize
, Size
, long, WindowStyle
)
126 // ----------------------------------------------------------------------------
128 // ----------------------------------------------------------------------------
130 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent
, wxNotifyEvent
)
132 wxTreeEvent::wxTreeEvent(wxEventType commandType
,
133 wxTreeCtrlBase
*tree
,
134 const wxTreeItemId
& item
)
135 : wxNotifyEvent(commandType
, tree
->GetId()),
138 m_editCancelled
= false;
140 SetEventObject(tree
);
143 SetClientObject(tree
->GetItemData(item
));
146 wxTreeEvent::wxTreeEvent(wxEventType commandType
, int id
)
147 : wxNotifyEvent(commandType
, id
)
150 m_editCancelled
= false;
153 wxTreeEvent::wxTreeEvent(const wxTreeEvent
& event
)
154 : wxNotifyEvent(event
)
156 m_evtKey
= event
.m_evtKey
;
157 m_item
= event
.m_item
;
158 m_itemOld
= event
.m_itemOld
;
159 m_pointDrag
= event
.m_pointDrag
;
160 m_label
= event
.m_label
;
161 m_editCancelled
= event
.m_editCancelled
;
164 // ----------------------------------------------------------------------------
166 // ----------------------------------------------------------------------------
168 wxTreeCtrlBase::~wxTreeCtrlBase()
170 if (m_ownsImageListNormal
)
171 delete m_imageListNormal
;
172 if (m_ownsImageListState
)
173 delete m_imageListState
;
176 void wxTreeCtrlBase::SetItemState(const wxTreeItemId
& item
, int state
)
178 if ( state
== wxTREE_ITEMSTATE_NEXT
)
180 int current
= GetItemState(item
);
181 if ( current
== wxTREE_ITEMSTATE_NONE
)
184 if ( m_imageListState
&& state
>= m_imageListState
->GetImageCount() )
187 else if ( state
== wxTREE_ITEMSTATE_PREV
)
189 int current
= GetItemState(item
);
190 if ( current
== wxTREE_ITEMSTATE_NONE
)
194 state
= m_imageListState
? m_imageListState
->GetImageCount() - 1 : 0;
196 // else: wxTREE_ITEMSTATE_NONE depending on platform
198 DoSetItemState(item
, state
);
202 wxGetBestTreeSize(const wxTreeCtrlBase
* treeCtrl
, wxTreeItemId id
, wxSize
& size
)
206 if ( treeCtrl
->GetBoundingRect(id
, rect
, true /* just the item */) )
208 // Translate to logical position so we get the full extent
209 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
210 rect
.x
+= treeCtrl
->GetScrollPos(wxHORIZONTAL
);
211 rect
.y
+= treeCtrl
->GetScrollPos(wxVERTICAL
);
214 size
.IncTo(wxSize(rect
.GetRight(), rect
.GetBottom()));
217 wxTreeItemIdValue cookie
;
218 for ( wxTreeItemId item
= treeCtrl
->GetFirstChild(id
, cookie
);
220 item
= treeCtrl
->GetNextChild(id
, cookie
) )
222 wxGetBestTreeSize(treeCtrl
, item
, size
);
226 wxSize
wxTreeCtrlBase::DoGetBestSize() const
230 // this doesn't really compute the total bounding rectangle of all items
231 // but a not too bad guess of it which has the advantage of not having to
232 // examine all (potentially hundreds or thousands) items in the control
234 if (GetQuickBestSize())
236 for ( wxTreeItemId item
= GetRootItem();
238 item
= GetLastChild(item
) )
242 // last parameter is "true" to get only the dimensions of the text
243 // label, we don't want to get the entire item width as it's determined
244 // by the current size
245 if ( GetBoundingRect(item
, rect
, true) )
247 if ( size
.x
< rect
.x
+ rect
.width
)
248 size
.x
= rect
.x
+ rect
.width
;
249 if ( size
.y
< rect
.y
+ rect
.height
)
250 size
.y
= rect
.y
+ rect
.height
;
254 else // use precise, if potentially slow, size computation method
256 // iterate over all items recursively
257 wxTreeItemId idRoot
= GetRootItem();
259 wxGetBestTreeSize(this, idRoot
, size
);
262 // need some minimal size even for empty tree
263 if ( !size
.x
|| !size
.y
)
264 size
= wxControl::DoGetBestSize();
268 size
+= GetWindowBorderSize();
276 void wxTreeCtrlBase::ExpandAll()
281 ExpandAllChildren(GetRootItem());
284 void wxTreeCtrlBase::ExpandAllChildren(const wxTreeItemId
& item
)
287 // expand this item first, this might result in its children being added on
289 if ( item
!= GetRootItem() || !HasFlag(wxTR_HIDE_ROOT
) )
291 //else: expanding hidden root item is unsupported and unnecessary
293 // then (recursively) expand all the children
294 wxTreeItemIdValue cookie
;
295 for ( wxTreeItemId idCurr
= GetFirstChild(item
, cookie
);
297 idCurr
= GetNextChild(item
, cookie
) )
299 ExpandAllChildren(idCurr
);
304 void wxTreeCtrlBase::CollapseAll()
309 CollapseAllChildren(GetRootItem());
312 void wxTreeCtrlBase::CollapseAllChildren(const wxTreeItemId
& item
)
315 // first (recursively) collapse all the children
316 wxTreeItemIdValue cookie
;
317 for ( wxTreeItemId idCurr
= GetFirstChild(item
, cookie
);
319 idCurr
= GetNextChild(item
, cookie
) )
321 CollapseAllChildren(idCurr
);
324 // then collapse this element too
329 bool wxTreeCtrlBase::IsEmpty() const
331 return !GetRootItem().IsOk();
334 #endif // wxUSE_TREECTRL