]> git.saurik.com Git - wxWidgets.git/blame - src/common/treebase.cpp
implement button support for pre-XP systems (or with themes disabled); using only...
[wxWidgets.git] / src / common / treebase.cpp
CommitLineData
484523cf
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: treebase.cpp
3// Purpose: Base wxTreeCtrl classes
4// Author: Julian Smart
5// Created: 01/02/97
6// Modified:
7// Id: $Id$
8// Copyright: (c) 1998 Robert Roebling, Julian Smart et al
65571936 9// Licence: wxWindows licence
484523cf
JS
10/////////////////////////////////////////////////////////////////////////////
11
12// =============================================================================
13// declarations
14// =============================================================================
15
16// -----------------------------------------------------------------------------
17// headers
18// -----------------------------------------------------------------------------
19
484523cf
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
1e6feb95 24 #pragma hdrstop
484523cf
JS
25#endif
26
1e6feb95
VZ
27#if wxUSE_TREECTRL
28
8cee4a30 29#include "wx/treectrl.h"
42e53e77 30#include "wx/imaglist.h"
ed2ec17c
GT
31
32// ----------------------------------------------------------------------------
33// events
34// ----------------------------------------------------------------------------
35
9b11752c
VZ
36wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEvent );
37wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_RDRAG, wxTreeEvent );
38wxDEFINE_EVENT( wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxTreeEvent );
39wxDEFINE_EVENT( wxEVT_COMMAND_TREE_END_LABEL_EDIT, wxTreeEvent );
40wxDEFINE_EVENT( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEvent );
41wxDEFINE_EVENT( wxEVT_COMMAND_TREE_GET_INFO, wxTreeEvent );
42wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SET_INFO, wxTreeEvent );
43wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEvent );
44wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_EXPANDING, wxTreeEvent );
45wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxTreeEvent );
46wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_COLLAPSING, wxTreeEvent );
47wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEvent );
48wxDEFINE_EVENT( wxEVT_COMMAND_TREE_SEL_CHANGING, wxTreeEvent );
49wxDEFINE_EVENT( wxEVT_COMMAND_TREE_KEY_DOWN, wxTreeEvent );
50wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEvent );
51wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, wxTreeEvent );
52wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, wxTreeEvent );
53wxDEFINE_EVENT( wxEVT_COMMAND_TREE_END_DRAG, wxTreeEvent );
54wxDEFINE_EVENT( wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK, wxTreeEvent );
55wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, wxTreeEvent );
56wxDEFINE_EVENT( wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEvent );
ed2ec17c 57
484523cf
JS
58// ----------------------------------------------------------------------------
59// Tree event
60// ----------------------------------------------------------------------------
61
e47859da 62IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxNotifyEvent)
b8fbf1a0 63
09f277d6
VZ
64wxTreeEvent::wxTreeEvent(wxEventType commandType,
65 wxTreeCtrlBase *tree,
66 const wxTreeItemId& item)
67 : wxNotifyEvent(commandType, tree->GetId()),
68 m_item(item)
484523cf 69{
cb719f2e 70 m_editCancelled = false;
09f277d6
VZ
71
72 SetEventObject(tree);
73
74 if ( item.IsOk() )
75 SetClientObject(tree->GetItemData(item));
484523cf
JS
76}
77
49b6ebb7
RD
78wxTreeEvent::wxTreeEvent(wxEventType commandType, int id)
79 : wxNotifyEvent(commandType, id)
80{
81 m_itemOld = 0l;
82 m_editCancelled = false;
83}
84
0cd936a4
WS
85wxTreeEvent::wxTreeEvent(const wxTreeEvent & event)
86 : wxNotifyEvent(event)
87{
88 m_evtKey = event.m_evtKey;
89 m_item = event.m_item;
90 m_itemOld = event.m_itemOld;
91 m_pointDrag = event.m_pointDrag;
92 m_label = event.m_label;
93 m_editCancelled = event.m_editCancelled;
94}
95
8cee4a30
VZ
96// ----------------------------------------------------------------------------
97// wxTreeCtrlBase
98// ----------------------------------------------------------------------------
99
100wxTreeCtrlBase::~wxTreeCtrlBase()
101{
102 if (m_ownsImageListNormal)
103 delete m_imageListNormal;
104 if (m_ownsImageListState)
105 delete m_imageListState;
106}
107
03966fcb
RR
108void wxTreeCtrlBase::SetItemState(const wxTreeItemId& item, int state)
109{
110 if ( state == wxTREE_ITEMSTATE_NEXT )
111 {
4754ab16
RR
112 int current = GetItemState(item);
113 if ( current == wxTREE_ITEMSTATE_NONE )
114 return;
115 state = current + 1;
03966fcb
RR
116 if ( m_imageListState && state >= m_imageListState->GetImageCount() )
117 state = 0;
118 }
119 else if ( state == wxTREE_ITEMSTATE_PREV )
120 {
4754ab16
RR
121 int current = GetItemState(item);
122 if ( current == wxTREE_ITEMSTATE_NONE )
123 return;
124 state = current - 1;
03966fcb
RR
125 if ( state == -1 )
126 state = m_imageListState ? m_imageListState->GetImageCount() - 1 : 0;
127 }
128 // else: wxTREE_ITEMSTATE_NONE depending on platform
129
130 DoSetItemState(item, state);
131}
132
fbf8436c
VZ
133static void
134wxGetBestTreeSize(const wxTreeCtrlBase* treeCtrl, wxTreeItemId id, wxSize& size)
7c384067
JS
135{
136 wxRect rect;
70934138 137
fbf8436c 138 if ( treeCtrl->GetBoundingRect(id, rect, true /* just the item */) )
7c384067 139 {
9e7642ae 140 // Translate to logical position so we get the full extent
9766efc3 141#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
9e7642ae
JS
142 rect.x += treeCtrl->GetScrollPos(wxHORIZONTAL);
143 rect.y += treeCtrl->GetScrollPos(wxVERTICAL);
9766efc3 144#endif
9e7642ae 145
fbf8436c 146 size.IncTo(wxSize(rect.GetRight(), rect.GetBottom()));
7c384067
JS
147 }
148
149 wxTreeItemIdValue cookie;
150 for ( wxTreeItemId item = treeCtrl->GetFirstChild(id, cookie);
151 item.IsOk();
3e748fca 152 item = treeCtrl->GetNextChild(id, cookie) )
7c384067
JS
153 {
154 wxGetBestTreeSize(treeCtrl, item, size);
155 }
156}
157
8cee4a30
VZ
158wxSize wxTreeCtrlBase::DoGetBestSize() const
159{
160 wxSize size;
161
162 // this doesn't really compute the total bounding rectangle of all items
163 // but a not too bad guess of it which has the advantage of not having to
164 // examine all (potentially hundreds or thousands) items in the control
70934138 165
7c384067 166 if (GetQuickBestSize())
8cee4a30 167 {
7c384067
JS
168 for ( wxTreeItemId item = GetRootItem();
169 item.IsOk();
170 item = GetLastChild(item) )
8cee4a30 171 {
7c384067
JS
172 wxRect rect;
173
174 // last parameter is "true" to get only the dimensions of the text
175 // label, we don't want to get the entire item width as it's determined
176 // by the current size
177 if ( GetBoundingRect(item, rect, true) )
178 {
179 if ( size.x < rect.x + rect.width )
180 size.x = rect.x + rect.width;
181 if ( size.y < rect.y + rect.height )
182 size.y = rect.y + rect.height;
183 }
8cee4a30
VZ
184 }
185 }
fbf8436c
VZ
186 else // use precise, if potentially slow, size computation method
187 {
188 // iterate over all items recursively
16f32ee7
VZ
189 wxTreeItemId idRoot = GetRootItem();
190 if ( idRoot.IsOk() )
191 wxGetBestTreeSize(this, idRoot, size);
fbf8436c
VZ
192 }
193
8cee4a30
VZ
194 // need some minimal size even for empty tree
195 if ( !size.x || !size.y )
196 size = wxControl::DoGetBestSize();
b24069f2 197 else
54a4121a
VZ
198 {
199 // Add border size
200 size += GetWindowBorderSize();
201
b24069f2 202 CacheBestSize(size);
54a4121a 203 }
8cee4a30
VZ
204
205 return size;
206}
207
70934138
VZ
208void wxTreeCtrlBase::ExpandAll()
209{
9248adc8
VZ
210 if ( IsEmpty() )
211 return;
212
70934138
VZ
213 ExpandAllChildren(GetRootItem());
214}
215
216void wxTreeCtrlBase::ExpandAllChildren(const wxTreeItemId& item)
217{
624f89c2 218 Freeze();
70934138
VZ
219 // expand this item first, this might result in its children being added on
220 // the fly
e660f922
VZ
221 if ( item != GetRootItem() || !HasFlag(wxTR_HIDE_ROOT) )
222 Expand(item);
223 //else: expanding hidden root item is unsupported and unnecessary
70934138
VZ
224
225 // then (recursively) expand all the children
226 wxTreeItemIdValue cookie;
227 for ( wxTreeItemId idCurr = GetFirstChild(item, cookie);
228 idCurr.IsOk();
229 idCurr = GetNextChild(item, cookie) )
230 {
231 ExpandAllChildren(idCurr);
232 }
624f89c2 233 Thaw();
70934138
VZ
234}
235
9248adc8
VZ
236void wxTreeCtrlBase::CollapseAll()
237{
238 if ( IsEmpty() )
239 return;
240
241 CollapseAllChildren(GetRootItem());
242}
243
244void wxTreeCtrlBase::CollapseAllChildren(const wxTreeItemId& item)
245{
624f89c2 246 Freeze();
9248adc8
VZ
247 // first (recursively) collapse all the children
248 wxTreeItemIdValue cookie;
249 for ( wxTreeItemId idCurr = GetFirstChild(item, cookie);
250 idCurr.IsOk();
251 idCurr = GetNextChild(item, cookie) )
252 {
253 CollapseAllChildren(idCurr);
254 }
255
256 // then collapse this element too
257 Collapse(item);
624f89c2 258 Thaw();
9248adc8
VZ
259}
260
261bool wxTreeCtrlBase::IsEmpty() const
262{
263 return !GetRootItem().IsOk();
264}
265
1e6feb95 266#endif // wxUSE_TREECTRL