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
This commit is contained in:
Vadim Zeitlin
2001-12-23 01:00:32 +00:00
parent d6acfcb5f6
commit 502a2b1810
2 changed files with 58 additions and 32 deletions

View File

@@ -433,14 +433,13 @@ private:
void DeleteTextCtrl(); void DeleteTextCtrl();
// support for additional item images // support for additional item images which we implement using
friend class wxTreeItemIndirectData; // wxTreeItemIndirectData technique - see the comments in msw/treectrl.cpp
void SetIndirectItemData(const wxTreeItemId& item, void SetIndirectItemData(const wxTreeItemId& item,
wxTreeItemIndirectData *data); class wxTreeItemIndirectData *data);
bool HasIndirectData(const wxTreeItemId& item) const; bool HasIndirectData(const wxTreeItemId& item) const;
bool IsDataIndirect(wxTreeItemData *data) const
// the array storing all item ids which have indirect data { return data->GetId().m_pItem == 0; }
wxArrayTreeItemIds m_itemsWithIndirectData;
// the hash storing the items attributes (indexed by items ids) // the hash storing the items attributes (indexed by items ids)
wxHashTable m_attrs; wxHashTable m_attrs;
@@ -454,6 +453,9 @@ private:
// the starting item for selection with Shift // the starting item for selection with Shift
WXHTREEITEM m_htSelStart; WXHTREEITEM m_htSelStart;
friend class wxTreeItemIndirectData;
friend class wxTreeSortHelper;
DECLARE_DYNAMIC_CLASS(wxTreeCtrl) DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
}; };

View File

@@ -401,11 +401,12 @@ private:
// //
// There is only one problem with this: when we retrieve the item's data, we // 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 // don't know whether we get a pointer to wxTreeItemData or
// wxTreeItemIndirectData. So we have to maintain a list of all items which // wxTreeItemIndirectData. So we always set the item id to an invalid value
// have indirect data inside the listctrl itself. // 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: public:
// ctor associates this data with the item and the real item data becomes // 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 // dtor deletes the associated data as well
~wxTreeItemIndirectData() { delete m_data; } virtual ~wxTreeItemIndirectData() { delete m_data; }
// accessors // accessors
// get the real data associated with the item // get the real data associated with the item
@@ -444,6 +445,7 @@ private:
// all the images associated with the item // all the images associated with the item
int m_images[wxTreeItemIcon_Max]; int m_images[wxTreeItemIcon_Max];
// the real client data
wxTreeItemData *m_data; wxTreeItemData *m_data;
}; };
@@ -966,14 +968,13 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
return NULL; return NULL;
} }
if ( HasIndirectData(item) ) wxTreeItemData *data = (wxTreeItemData *)tvItem.lParam;
if ( IsDataIndirect(data) )
{ {
return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData(); data = ((wxTreeItemIndirectData *)data)->GetData();
}
else
{
return (wxTreeItemData *)tvItem.lParam;
} }
return data;
} }
void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
@@ -1013,14 +1014,21 @@ void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
// wxTreeItemIndirectData as well // wxTreeItemIndirectData as well
wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") ); wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
SetItemData(item, (wxTreeItemData *)data); SetItemData(item, data);
m_itemsWithIndirectData.Add(item);
} }
bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const 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) void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
@@ -1738,14 +1746,37 @@ bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
// sorting stuff // sorting stuff
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
static int CALLBACK TreeView_CompareCallback(wxTreeItemData *pItem1, // this is just a tiny namespace which is friend to wxTreeCtrl and so can use
wxTreeItemData *pItem2, // functions such as IsDataIndirect()
wxTreeCtrl *tree) 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, wxCHECK_MSG( pItem1 && pItem2, 0,
wxT("sorting tree without data doesn't make sense") ); 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, int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
@@ -1767,7 +1798,7 @@ void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
{ {
TV_SORTCB tvSort; TV_SORTCB tvSort;
tvSort.hParent = HITEM(item); tvSort.hParent = HITEM(item);
tvSort.lpfnCompare = (PFNTVCOMPARE)TreeView_CompareCallback; tvSort.lpfnCompare = wxTreeSortHelper::Compare;
tvSort.lParam = (LPARAM)this; tvSort.lParam = (LPARAM)this;
TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0 /* reserved */); TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0 /* reserved */);
} }
@@ -2335,13 +2366,6 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
wxTreeItemIndirectData *data = (wxTreeItemIndirectData *) wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
tv->itemOld.lParam; tv->itemOld.lParam;
delete data; // can't be NULL here 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 else
{ {