1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/treebase.cpp
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 extern WXDLLEXPORT_DATA(const char) wxTreeCtrlNameStr
[] = "treeCtrl";
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_DRAG
, wxTreeEvent
);
39 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_RDRAG
, wxTreeEvent
);
40 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
, wxTreeEvent
);
41 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_END_LABEL_EDIT
, wxTreeEvent
);
42 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_DELETE_ITEM
, wxTreeEvent
);
43 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_GET_INFO
, wxTreeEvent
);
44 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SET_INFO
, wxTreeEvent
);
45 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_EXPANDED
, wxTreeEvent
);
46 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_EXPANDING
, wxTreeEvent
);
47 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_COLLAPSED
, wxTreeEvent
);
48 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_COLLAPSING
, wxTreeEvent
);
49 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SEL_CHANGED
, wxTreeEvent
);
50 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SEL_CHANGING
, wxTreeEvent
);
51 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_KEY_DOWN
, wxTreeEvent
);
52 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_ACTIVATED
, wxTreeEvent
);
53 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK
, wxTreeEvent
);
54 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK
, wxTreeEvent
);
55 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_END_DRAG
, wxTreeEvent
);
56 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK
, wxTreeEvent
);
57 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP
, wxTreeEvent
);
58 wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_MENU
, wxTreeEvent
);
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 wxDEFINE_FLAGS( wxTreeCtrlStyle
)
65 wxBEGIN_FLAGS( wxTreeCtrlStyle
)
66 // new style border flags, we put them first to
67 // use them for streaming out
68 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
69 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
70 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
71 wxFLAGS_MEMBER(wxBORDER_RAISED
)
72 wxFLAGS_MEMBER(wxBORDER_STATIC
)
73 wxFLAGS_MEMBER(wxBORDER_NONE
)
75 // old style border flags
76 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
77 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
78 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
79 wxFLAGS_MEMBER(wxRAISED_BORDER
)
80 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
81 wxFLAGS_MEMBER(wxBORDER
)
83 // standard window styles
84 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
85 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
86 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
87 wxFLAGS_MEMBER(wxWANTS_CHARS
)
88 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
89 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
90 wxFLAGS_MEMBER(wxVSCROLL
)
91 wxFLAGS_MEMBER(wxHSCROLL
)
93 wxFLAGS_MEMBER(wxTR_EDIT_LABELS
)
94 wxFLAGS_MEMBER(wxTR_NO_BUTTONS
)
95 wxFLAGS_MEMBER(wxTR_HAS_BUTTONS
)
96 wxFLAGS_MEMBER(wxTR_TWIST_BUTTONS
)
97 wxFLAGS_MEMBER(wxTR_NO_LINES
)
98 wxFLAGS_MEMBER(wxTR_FULL_ROW_HIGHLIGHT
)
99 wxFLAGS_MEMBER(wxTR_LINES_AT_ROOT
)
100 wxFLAGS_MEMBER(wxTR_HIDE_ROOT
)
101 wxFLAGS_MEMBER(wxTR_ROW_LINES
)
102 wxFLAGS_MEMBER(wxTR_HAS_VARIABLE_ROW_HEIGHT
)
103 wxFLAGS_MEMBER(wxTR_SINGLE
)
104 wxFLAGS_MEMBER(wxTR_MULTIPLE
)
105 #if WXWIN_COMPATIBILITY_2_8
106 wxFLAGS_MEMBER(wxTR_EXTENDED
)
108 wxFLAGS_MEMBER(wxTR_DEFAULT_STYLE
)
109 wxEND_FLAGS( wxTreeCtrlStyle
)
111 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl
, wxControl
, "wx/treectrl.h")
113 wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl
)
114 wxEVENT_PROPERTY( TextUpdated
, wxEVT_COMMAND_TEXT_UPDATED
, wxCommandEvent
)
115 wxEVENT_RANGE_PROPERTY( TreeEvent
, wxEVT_COMMAND_TREE_BEGIN_DRAG
, \
116 wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK
, wxTreeEvent
)
118 wxPROPERTY_FLAGS( WindowStyle
, wxTreeCtrlStyle
, long, SetWindowStyleFlag
, \
119 GetWindowStyleFlag
, wxEMPTY_PARAMETER_VALUE
, 0 /*flags*/, \
120 wxT("Helpstring"), wxT("group")) // style
121 wxEND_PROPERTIES_TABLE()
123 wxEMPTY_HANDLERS_TABLE(wxTreeCtrl
)
125 wxCONSTRUCTOR_5( wxTreeCtrl
, wxWindow
*, Parent
, wxWindowID
, Id
, \
126 wxPoint
, Position
, wxSize
, Size
, long, WindowStyle
)
128 // ----------------------------------------------------------------------------
130 // ----------------------------------------------------------------------------
132 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent
, wxNotifyEvent
)
134 wxTreeEvent::wxTreeEvent(wxEventType commandType
,
135 wxTreeCtrlBase
*tree
,
136 const wxTreeItemId
& item
)
137 : wxNotifyEvent(commandType
, tree
->GetId()),
140 m_editCancelled
= false;
142 SetEventObject(tree
);
145 SetClientObject(tree
->GetItemData(item
));
148 wxTreeEvent::wxTreeEvent(wxEventType commandType
, int id
)
149 : wxNotifyEvent(commandType
, id
)
152 m_editCancelled
= false;
155 wxTreeEvent::wxTreeEvent(const wxTreeEvent
& event
)
156 : wxNotifyEvent(event
)
158 m_evtKey
= event
.m_evtKey
;
159 m_item
= event
.m_item
;
160 m_itemOld
= event
.m_itemOld
;
161 m_pointDrag
= event
.m_pointDrag
;
162 m_label
= event
.m_label
;
163 m_editCancelled
= event
.m_editCancelled
;
166 // ----------------------------------------------------------------------------
168 // ----------------------------------------------------------------------------
170 wxTreeCtrlBase::~wxTreeCtrlBase()
172 if (m_ownsImageListNormal
)
173 delete m_imageListNormal
;
174 if (m_ownsImageListState
)
175 delete m_imageListState
;
178 void wxTreeCtrlBase::SetItemState(const wxTreeItemId
& item
, int state
)
180 if ( state
== wxTREE_ITEMSTATE_NEXT
)
182 int current
= GetItemState(item
);
183 if ( current
== wxTREE_ITEMSTATE_NONE
)
186 if ( m_imageListState
&& state
>= m_imageListState
->GetImageCount() )
189 else if ( state
== wxTREE_ITEMSTATE_PREV
)
191 int current
= GetItemState(item
);
192 if ( current
== wxTREE_ITEMSTATE_NONE
)
196 state
= m_imageListState
? m_imageListState
->GetImageCount() - 1 : 0;
198 // else: wxTREE_ITEMSTATE_NONE depending on platform
200 DoSetItemState(item
, state
);
204 wxGetBestTreeSize(const wxTreeCtrlBase
* treeCtrl
, wxTreeItemId id
, wxSize
& size
)
208 if ( treeCtrl
->GetBoundingRect(id
, rect
, true /* just the item */) )
210 // Translate to logical position so we get the full extent
211 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
212 rect
.x
+= treeCtrl
->GetScrollPos(wxHORIZONTAL
);
213 rect
.y
+= treeCtrl
->GetScrollPos(wxVERTICAL
);
216 size
.IncTo(wxSize(rect
.GetRight(), rect
.GetBottom()));
219 wxTreeItemIdValue cookie
;
220 for ( wxTreeItemId item
= treeCtrl
->GetFirstChild(id
, cookie
);
222 item
= treeCtrl
->GetNextChild(id
, cookie
) )
224 wxGetBestTreeSize(treeCtrl
, item
, size
);
228 wxSize
wxTreeCtrlBase::DoGetBestSize() const
232 // this doesn't really compute the total bounding rectangle of all items
233 // but a not too bad guess of it which has the advantage of not having to
234 // examine all (potentially hundreds or thousands) items in the control
236 if (GetQuickBestSize())
238 for ( wxTreeItemId item
= GetRootItem();
240 item
= GetLastChild(item
) )
244 // last parameter is "true" to get only the dimensions of the text
245 // label, we don't want to get the entire item width as it's determined
246 // by the current size
247 if ( GetBoundingRect(item
, rect
, true) )
249 if ( size
.x
< rect
.x
+ rect
.width
)
250 size
.x
= rect
.x
+ rect
.width
;
251 if ( size
.y
< rect
.y
+ rect
.height
)
252 size
.y
= rect
.y
+ rect
.height
;
256 else // use precise, if potentially slow, size computation method
258 // iterate over all items recursively
259 wxTreeItemId idRoot
= GetRootItem();
261 wxGetBestTreeSize(this, idRoot
, size
);
264 // need some minimal size even for empty tree
265 if ( !size
.x
|| !size
.y
)
266 size
= wxControl::DoGetBestSize();
270 size
+= GetWindowBorderSize();
278 void wxTreeCtrlBase::ExpandAll()
283 ExpandAllChildren(GetRootItem());
286 void wxTreeCtrlBase::ExpandAllChildren(const wxTreeItemId
& item
)
289 // expand this item first, this might result in its children being added on
291 if ( item
!= GetRootItem() || !HasFlag(wxTR_HIDE_ROOT
) )
293 //else: expanding hidden root item is unsupported and unnecessary
295 // then (recursively) expand all the children
296 wxTreeItemIdValue cookie
;
297 for ( wxTreeItemId idCurr
= GetFirstChild(item
, cookie
);
299 idCurr
= GetNextChild(item
, cookie
) )
301 ExpandAllChildren(idCurr
);
306 void wxTreeCtrlBase::CollapseAll()
311 CollapseAllChildren(GetRootItem());
314 void wxTreeCtrlBase::CollapseAllChildren(const wxTreeItemId
& item
)
317 // first (recursively) collapse all the children
318 wxTreeItemIdValue cookie
;
319 for ( wxTreeItemId idCurr
= GetFirstChild(item
, cookie
);
321 idCurr
= GetNextChild(item
, cookie
) )
323 CollapseAllChildren(idCurr
);
326 // then collapse this element too unless it's the hidden root which can't
328 if ( item
!= GetRootItem() || !HasFlag(wxTR_HIDE_ROOT
) )
333 bool wxTreeCtrlBase::IsEmpty() const
335 return !GetRootItem().IsOk();
338 #endif // wxUSE_TREECTRL