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