From 502a2b1810943f9a446a16e73ef780321eb69a06 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 23 Dec 2001 01:00:32 +0000 Subject: [PATCH] fixed sorting the items which have indirect data (i.e. images set for open/closed state) and made indirect data handling much simpler and more efficient as a side effect git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13164 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/treectrl.h | 14 ++++---- src/msw/treectrl.cpp | 76 +++++++++++++++++++++++++-------------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index ef9f23cff1..b99a97724a 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -433,14 +433,13 @@ private: void DeleteTextCtrl(); - // support for additional item images - friend class wxTreeItemIndirectData; + // support for additional item images which we implement using + // wxTreeItemIndirectData technique - see the comments in msw/treectrl.cpp void SetIndirectItemData(const wxTreeItemId& item, - wxTreeItemIndirectData *data); + class wxTreeItemIndirectData *data); bool HasIndirectData(const wxTreeItemId& item) const; - - // the array storing all item ids which have indirect data - wxArrayTreeItemIds m_itemsWithIndirectData; + bool IsDataIndirect(wxTreeItemData *data) const + { return data->GetId().m_pItem == 0; } // the hash storing the items attributes (indexed by items ids) wxHashTable m_attrs; @@ -454,6 +453,9 @@ private: // the starting item for selection with Shift WXHTREEITEM m_htSelStart; + friend class wxTreeItemIndirectData; + friend class wxTreeSortHelper; + DECLARE_DYNAMIC_CLASS(wxTreeCtrl) }; diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 4481d86387..b5612512f6 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -401,11 +401,12 @@ private: // // There is only one problem with this: when we retrieve the item's data, we // don't know whether we get a pointer to wxTreeItemData or -// wxTreeItemIndirectData. So we have to maintain a list of all items which -// have indirect data inside the listctrl itself. +// wxTreeItemIndirectData. So we always set the item id to an invalid value +// in this class and the code using the client data checks for it and retrieves +// the real client data in this case. // ---------------------------------------------------------------------------- -class wxTreeItemIndirectData +class wxTreeItemIndirectData : public wxTreeItemData { public: // ctor associates this data with the item and the real item data becomes @@ -425,7 +426,7 @@ public: } // dtor deletes the associated data as well - ~wxTreeItemIndirectData() { delete m_data; } + virtual ~wxTreeItemIndirectData() { delete m_data; } // accessors // get the real data associated with the item @@ -444,6 +445,7 @@ private: // all the images associated with the item int m_images[wxTreeItemIcon_Max]; + // the real client data wxTreeItemData *m_data; }; @@ -966,14 +968,13 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const return NULL; } - if ( HasIndirectData(item) ) - { - return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData(); - } - else + wxTreeItemData *data = (wxTreeItemData *)tvItem.lParam; + if ( IsDataIndirect(data) ) { - return (wxTreeItemData *)tvItem.lParam; + data = ((wxTreeItemIndirectData *)data)->GetData(); } + + return data; } void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) @@ -1013,14 +1014,21 @@ void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item, // wxTreeItemIndirectData as well wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") ); - SetItemData(item, (wxTreeItemData *)data); - - m_itemsWithIndirectData.Add(item); + SetItemData(item, data); } bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const { - return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND; + // query the item itself + wxTreeViewItem tvItem(item, TVIF_PARAM); + if ( !DoGetItem(&tvItem) ) + { + return FALSE; + } + + wxTreeItemData *data = (wxTreeItemData *)tvItem.lParam; + + return data && IsDataIndirect(data); } void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) @@ -1738,14 +1746,37 @@ bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, // sorting stuff // ---------------------------------------------------------------------------- -static int CALLBACK TreeView_CompareCallback(wxTreeItemData *pItem1, - wxTreeItemData *pItem2, - wxTreeCtrl *tree) +// this is just a tiny namespace which is friend to wxTreeCtrl and so can use +// functions such as IsDataIndirect() +class wxTreeSortHelper +{ +public: + static int CALLBACK Compare(LPARAM data1, LPARAM data2, LPARAM tree); + +private: + static wxTreeItemId GetIdFromData(wxTreeCtrl *tree, LPARAM item) + { + wxTreeItemData *data = (wxTreeItemData *)item; + if ( tree->IsDataIndirect(data) ) + { + data = ((wxTreeItemIndirectData *)data)->GetData(); + } + + return data->GetId(); + } +}; + +int CALLBACK wxTreeSortHelper::Compare(LPARAM pItem1, + LPARAM pItem2, + LPARAM htree) { wxCHECK_MSG( pItem1 && pItem2, 0, wxT("sorting tree without data doesn't make sense") ); - return tree->OnCompareItems(pItem1->GetId(), pItem2->GetId()); + wxTreeCtrl *tree = (wxTreeCtrl *)htree; + + return tree->OnCompareItems(GetIdFromData(tree, pItem1), + GetIdFromData(tree, pItem2)); } int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1, @@ -1767,7 +1798,7 @@ void wxTreeCtrl::SortChildren(const wxTreeItemId& item) { TV_SORTCB tvSort; tvSort.hParent = HITEM(item); - tvSort.lpfnCompare = (PFNTVCOMPARE)TreeView_CompareCallback; + tvSort.lpfnCompare = wxTreeSortHelper::Compare; tvSort.lParam = (LPARAM)this; TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0 /* reserved */); } @@ -2335,13 +2366,6 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) wxTreeItemIndirectData *data = (wxTreeItemIndirectData *) tv->itemOld.lParam; delete data; // can't be NULL here - - m_itemsWithIndirectData.Remove(item); -#if 0 - int iIndex = m_itemsWithIndirectData.Index(item); - wxASSERT( iIndex != wxNOT_FOUND) ; - m_itemsWithIndirectData.wxBaseArray::RemoveAt((size_t)iIndex); -#endif } else { -- 2.47.2