git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13164
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
- // 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,
void SetIndirectItemData(const wxTreeItemId& item,
- wxTreeItemIndirectData *data);
+ class wxTreeItemIndirectData *data);
bool HasIndirectData(const wxTreeItemId& item) const;
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;
// the hash storing the items attributes (indexed by items ids)
wxHashTable m_attrs;
// the starting item for selection with Shift
WXHTREEITEM m_htSelStart;
// the starting item for selection with Shift
WXHTREEITEM m_htSelStart;
+ friend class wxTreeItemIndirectData;
+ friend class wxTreeSortHelper;
+
DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
};
DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
};
//
// 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
//
// 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
{
public:
// ctor associates this data with the item and the real item data becomes
}
// dtor deletes the associated data as well
}
// 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
// accessors
// get the real data associated with the item
// all the images associated with the item
int m_images[wxTreeItemIcon_Max];
// all the images associated with the item
int m_images[wxTreeItemIcon_Max];
+ // the real client data
wxTreeItemData *m_data;
};
wxTreeItemData *m_data;
};
- 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();
}
void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
}
void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
// wxTreeItemIndirectData as well
wxASSERT_MSG( !HasIndirectData(item), wxT("setting indirect data twice?") );
// 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
{
}
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)
// sorting stuff
// ----------------------------------------------------------------------------
// 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") );
{
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,
}
int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
{
TV_SORTCB tvSort;
tvSort.hParent = HITEM(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 */);
}
tvSort.lParam = (LPARAM)this;
TreeView_SortChildrenCB(GetHwnd(), &tvSort, 0 /* reserved */);
}
wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
tv->itemOld.lParam;
delete data; // can't be NULL here
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