#endif
#ifndef WX_PRECOMP
- #include "wx.h"
+ #include "wx/wx.h"
#endif
#if defined(__WIN95__)
#include "wx/log.h"
+#include "wx/dynarray.h"
#include "wx/imaglist.h"
+#include "wx/msw/treectrl.h"
#include "wx/msw/private.h"
-#ifndef __GNUWIN32__
+#ifdef __GNUWIN32__
+#include "wx/msw/gnuwin32/extra.h"
+#endif
+
+#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__)
#include <commctrl.h>
#endif
#undef GetNextSibling
#endif
-#include "wx/msw/treectrl.h"
+#ifdef GetClassInfo
+#undef GetClassInfo
+#endif
// Bug in headers, sometimes
#ifndef TVIS_FOCUSED
SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
}
+size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively)
+{
+ long cookie;
+
+ size_t result = 0;
+
+ wxArrayLong children;
+ wxTreeItemId child = GetFirstChild(item, cookie);
+ while ( child.IsOk() )
+ {
+ if ( recursively )
+ {
+ // recursive call
+ result += GetChildrenCount(child, TRUE);
+ }
+
+ // add the child to the result in any case
+ result++;
+
+ child = GetNextChild(item, cookie);
+ }
+
+ return result;
+}
+
// ----------------------------------------------------------------------------
// Item access
// ----------------------------------------------------------------------------
wxTreeItemId wxTreeCtrl::GetNextChild(const wxTreeItemId& WXUNUSED(item),
long& _cookie) const
{
- wxTreeItemId l=wxTreeItemId((WXHTREEITEM) TreeView_GetNextSibling(wxhWnd,
- (HTREEITEM) (WXHTREEITEM)_cookie));
- _cookie=(long)l;
+ wxTreeItemId l = wxTreeItemId((WXHTREEITEM)TreeView_GetNextSibling(wxhWnd,
+ (HTREEITEM)(WXHTREEITEM)_cookie));
+ _cookie = (long)l;
+
return l;
}
+wxTreeItemId wxTreeCtrl::GetLastChild(const wxTreeItemId& item) const
+{
+ // can this be done more efficiently?
+ long cookie;
+
+ wxTreeItemId childLast,
+ child = GetFirstChild(item, cookie);
+ while ( child.IsOk() )
+ {
+ childLast = child;
+ child = GetNextChild(item, cookie);
+ }
+
+ return childLast;
+}
+
wxTreeItemId wxTreeCtrl::GetNextSibling(const wxTreeItemId& item) const
{
return wxTreeItemId((WXHTREEITEM) TreeView_GetNextSibling(wxhWnd, (HTREEITEM) (WXHTREEITEM) item));
}
}
+// delete all children (but don't delete the item itself)
+void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
+{
+ long cookie;
+
+ wxArrayLong children;
+ wxTreeItemId child = GetFirstChild(item, cookie);
+ while ( child.IsOk() )
+ {
+ children.Add((long)(WXHTREEITEM)child);
+
+ child = GetNextChild(item, cookie);
+ }
+
+ size_t nCount = children.Count();
+ for ( size_t n = 0; n < nCount; n++ )
+ {
+ if ( !TreeView_DeleteItem(wxhWnd, (HTREEITEM)children[n]) )
+ {
+ wxLogLastError("TreeView_DeleteItem");
+ }
+ }
+}
+
void wxTreeCtrl::DeleteAllItems()
{
if ( !TreeView_DeleteAllItems(wxhWnd) )
return wxTreeItemId((WXHTREEITEM) hitTestInfo.hItem);
}
-void wxTreeCtrl::SortChildren(const wxTreeItemId& item,
- wxTreeItemCmpFunc *cmpFunction)
+bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item,
+ wxRect& rect,
+ bool textOnly) const
{
- if ( cmpFunction == NULL )
+ RECT rc;
+ if ( TreeView_GetItemRect(wxhWnd, (HTREEITEM)(WXHTREEITEM)item,
+ &rc, textOnly) )
{
- TreeView_SortChildren(wxhWnd, (HTREEITEM) (WXHTREEITEM) item, 0);
+ rect = wxRect(wxPoint(rc.left, rc.top), wxPoint(rc.right, rc.bottom));
+
+ return TRUE;
}
else
{
- // TODO: use TreeView_SortChildrenCB
- wxFAIL_MSG("wxTreeCtrl::SortChildren not implemented");
+ // couldn't retrieve rect: for example, item isn't visible
+ return FALSE;
}
}
-// TODO
-size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively)
+// ----------------------------------------------------------------------------
+// sorting stuff
+// ----------------------------------------------------------------------------
+
+static int CALLBACK TreeView_CompareCallback(wxTreeItemData *pItem1,
+ wxTreeItemData *pItem2,
+ wxTreeCtrl *tree)
{
- return 0;
+ return tree->OnCompareItems(pItem1->GetId(), pItem2->GetId());
}
-// delete all children (but don't delete the item itself)
-// NB: this won't send wxEVT_COMMAND_TREE_ITEM_DELETED events
-void wxTreeCtrl::DeleteChildren(const wxTreeItemId& item)
+int wxTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
+ const wxTreeItemId& item2)
{
- // TODO
+ return strcmp(GetItemText(item1), GetItemText(item2));
+}
+
+void wxTreeCtrl::SortChildren(const wxTreeItemId& item)
+{
+ // rely on the fact that TreeView_SortChildren does the same thing as our
+ // default behaviour, i.e. sorts items alphabetically and so call it
+ // directly if we're not in derived class (much more efficient!)
+ if ( GetClassInfo() == CLASSINFO(wxTreeCtrl) )
+ {
+ TreeView_SortChildren(wxhWnd, (HTREEITEM)(WXHTREEITEM)item, 0);
+ }
+ else
+ {
+ TV_SORTCB tvSort;
+ tvSort.hParent = (HTREEITEM)(WXHTREEITEM)item;
+ tvSort.lpfnCompare = (PFNTVCOMPARE)TreeView_CompareCallback;
+ tvSort.lParam = (LPARAM)this;
+ TreeView_SortChildrenCB(wxhWnd, &tvSort, 0 /* reserved */);
+ }
}
// ----------------------------------------------------------------------------
TV_KEYDOWN *info = (TV_KEYDOWN *)lParam;
event.m_code = wxCharCodeMSWToWX(info->wVKey);
+
+ // a separate event for this case
+ if ( info->wVKey == VK_SPACE || info->wVKey == VK_RETURN )
+ {
+ wxTreeEvent event2(wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
+ m_windowId);
+ event2.SetEventObject(this);
+
+ GetEventHandler()->ProcessEvent(event2);
+ }
break;
}