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:
@@ -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)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -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
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user