You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/Controls/TreeCtrlUtils.h

323 lines
11 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_CONTROLS_TREECTRLUTILS_H
#define CRYINCLUDE_EDITOR_CONTROLS_TREECTRLUTILS_H
#pragma once
#include <iterator>
namespace TreeCtrlUtils
{
template <typename P>
class TreeItemIterator
: public P
{
public:
typedef P Traits;
//iterator traits, required by STL
typedef ptrdiff_t difference_type;
typedef HTREEITEM value_type;
typedef HTREEITEM* pointer;
typedef HTREEITEM& reference;
typedef std::forward_iterator_tag iterator_category;
TreeItemIterator()
: pCtrl(0)
, hItem(0) {}
explicit TreeItemIterator(const P& traits)
: P(traits)
, pCtrl(0)
, hItem(0) {}
TreeItemIterator(const TreeItemIterator& other)
: P(other)
, pCtrl(other.pCtrl)
, hItem(other.hItem) {}
TreeItemIterator(CTreeCtrl* pCtrl, HTREEITEM hItem)
: pCtrl(pCtrl)
, hItem(hItem) {}
TreeItemIterator(CTreeCtrl* pCtrl, HTREEITEM hItem, const P& traits)
: P(traits)
, pCtrl(pCtrl)
, hItem(hItem) {}
HTREEITEM operator*() {return hItem; }
bool operator==(const TreeItemIterator& other) const {return pCtrl == other.pCtrl && hItem == other.hItem; }
bool operator!=(const TreeItemIterator& other) const {return pCtrl != other.pCtrl || hItem != other.hItem; }
TreeItemIterator& operator++()
{
HTREEITEM hNextItem = 0;
if (RecurseToChildren(hItem))
{
hNextItem = (pCtrl ? pCtrl->GetChildItem(hItem) : 0);
}
while (pCtrl && hItem && !hNextItem)
{
hNextItem = pCtrl->GetNextSiblingItem(hItem);
if (!hNextItem)
{
hItem = pCtrl->GetParentItem(hItem);
}
}
hItem = hNextItem;
return *this;
}
TreeItemIterator operator++(int) {TreeItemIterator old = *this; ++(*this); return old; }
CTreeCtrl* pCtrl;
HTREEITEM hItem;
};
class NonRecursiveTreeItemIteratorTraits
{
public:
bool RecurseToChildren(HTREEITEM hItem) {return false; }
};
typedef TreeItemIterator<NonRecursiveTreeItemIteratorTraits> NonRecursiveTreeItemIterator;
class RecursiveTreeItemIteratorTraits
{
public:
bool RecurseToChildren(HTREEITEM hItem) {return true; }
};
typedef TreeItemIterator<RecursiveTreeItemIteratorTraits> RecursiveTreeItemIterator;
inline RecursiveTreeItemIterator BeginTreeItemsRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
if (hItem == 0)
{
hItem = (pCtrl ? pCtrl->GetRootItem() : 0);
}
return RecursiveTreeItemIterator(pCtrl, hItem);
}
inline RecursiveTreeItemIterator EndTreeItemsRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
HTREEITEM hEndItem = 0;
HTREEITEM hParent = hItem;
do
{
if (hParent)
{
hEndItem = pCtrl->GetNextSiblingItem(hParent);
}
hParent = (pCtrl && hParent ? pCtrl->GetParentItem(hParent) : 0);
}
while (hParent && !hEndItem);
return RecursiveTreeItemIterator(pCtrl, hEndItem);
}
inline NonRecursiveTreeItemIterator BeginTreeItemsNonRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
if (hItem == 0)
{
hItem = (pCtrl ? pCtrl->GetRootItem() : 0);
}
if (hItem)
{
hItem = pCtrl->GetChildItem(hItem);
}
return NonRecursiveTreeItemIterator(pCtrl, hItem);
}
inline NonRecursiveTreeItemIterator EndTreeItemsNonRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
HTREEITEM hEndItem = 0;
HTREEITEM hParent = 0;
while (hParent && !hEndItem)
{
hParent = (pCtrl && hItem ? pCtrl->GetParentItem(hItem) : 0);
if (hParent)
{
hEndItem = pCtrl->GetNextSiblingItem(hParent);
}
}
return NonRecursiveTreeItemIterator(pCtrl, hEndItem);
}
template <typename T, typename P>
class TreeItemDataIterator
{
public:
typedef T Type;
typedef TreeItemIterator<P> InternalIterator;
//iterator traits, required by STL
typedef ptrdiff_t difference_type;
typedef Type* value_type;
typedef Type** pointer;
typedef Type*& reference;
typedef std::forward_iterator_tag iterator_category;
TreeItemDataIterator() {}
TreeItemDataIterator(const TreeItemDataIterator& other)
: iterator(other.iterator) {AdvanceToValidIterator(); }
explicit TreeItemDataIterator(const InternalIterator& iterator)
: iterator(iterator) {AdvanceToValidIterator(); }
Type* operator*() {return reinterpret_cast<Type*>(iterator.pCtrl->GetItemData(iterator.hItem)); }
bool operator==(const TreeItemDataIterator& other) const {return iterator == other.iterator; }
bool operator!=(const TreeItemDataIterator& other) const {return iterator != other.iterator; }
HTREEITEM GetTreeItem() {return iterator.hItem; }
TreeItemDataIterator& operator++()
{
++iterator;
AdvanceToValidIterator();
return *this;
}
TreeItemDataIterator operator++(int) {TreeItemDataIterator old = *this; ++(*this); return old; }
private:
void AdvanceToValidIterator()
{
while (iterator.pCtrl && iterator.hItem && !iterator.pCtrl->GetItemData(iterator.hItem))
{
++iterator;
}
}
InternalIterator iterator;
};
template <typename T>
class RecursiveItemDataIteratorType
{
public: typedef TreeItemDataIterator<T, RecursiveTreeItemIteratorTraits> type;
};
template <typename T>
inline TreeItemDataIterator<T, RecursiveTreeItemIteratorTraits> BeginTreeItemDataRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
return TreeItemDataIterator<T, RecursiveTreeItemIteratorTraits>(BeginTreeItemsRecursive(pCtrl, hItem));
}
template <typename T>
inline TreeItemDataIterator<T, RecursiveTreeItemIteratorTraits> EndTreeItemDataRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
return TreeItemDataIterator<T, RecursiveTreeItemIteratorTraits>(EndTreeItemsRecursive(pCtrl, hItem));
}
template <typename T>
class NonRecursiveItemDataIteratorType
{
typedef TreeItemDataIterator<T, NonRecursiveTreeItemIteratorTraits> type;
};
template <typename T>
inline TreeItemDataIterator<T, NonRecursiveTreeItemIteratorTraits> BeginTreeItemDataNonRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
return TreeItemDataIterator<T, NonRecursiveTreeItemIteratorTraits>(BeginTreeItemsNonRecursive(pCtrl, hItem));
}
template <typename T>
inline TreeItemDataIterator<T, NonRecursiveTreeItemIteratorTraits> EndTreeItemDataNonRecursive(CTreeCtrl* pCtrl, HTREEITEM hItem = 0)
{
return TreeItemDataIterator<T, NonRecursiveTreeItemIteratorTraits>(EndTreeItemsNonRecursive(pCtrl, hItem));
}
class SelectedTreeItemIterator
{
public:
SelectedTreeItemIterator()
: pCtrl(0)
, hItem(0) {}
SelectedTreeItemIterator(const SelectedTreeItemIterator& other)
: pCtrl(other.pCtrl)
, hItem(other.hItem) {}
SelectedTreeItemIterator(CXTTreeCtrl* pCtrl, HTREEITEM hItem)
: pCtrl(pCtrl)
, hItem(hItem) {}
HTREEITEM operator*() {return hItem; }
bool operator==(const SelectedTreeItemIterator& other) const {return pCtrl == other.pCtrl && hItem == other.hItem; }
bool operator!=(const SelectedTreeItemIterator& other) const {return pCtrl != other.pCtrl || hItem != other.hItem; }
SelectedTreeItemIterator& operator++()
{
hItem = (pCtrl ? pCtrl->GetNextSelectedItem(hItem) : 0);
return *this;
}
SelectedTreeItemIterator operator++(int) {SelectedTreeItemIterator old = *this; ++(*this); return old; }
CXTTreeCtrl* pCtrl;
HTREEITEM hItem;
};
SelectedTreeItemIterator BeginSelectedTreeItems(CXTTreeCtrl* pCtrl)
{
return SelectedTreeItemIterator(pCtrl, (pCtrl ? pCtrl->GetFirstSelectedItem() : 0));
}
SelectedTreeItemIterator EndSelectedTreeItems(CXTTreeCtrl* pCtrl)
{
return SelectedTreeItemIterator(pCtrl, 0);
}
template <typename T>
class SelectedTreeItemDataIterator
{
public:
typedef T Type;
typedef SelectedTreeItemIterator InternalIterator;
SelectedTreeItemDataIterator() {}
SelectedTreeItemDataIterator(const SelectedTreeItemDataIterator& other)
: iterator(other.iterator) {AdvanceToValidIterator(); }
explicit SelectedTreeItemDataIterator(const InternalIterator& iterator)
: iterator(iterator) {AdvanceToValidIterator(); }
Type* operator*() {return reinterpret_cast<Type*>(iterator.pCtrl->GetItemData(iterator.hItem)); }
bool operator==(const SelectedTreeItemDataIterator& other) const {return iterator == other.iterator; }
bool operator!=(const SelectedTreeItemDataIterator& other) const {return iterator != other.iterator; }
HTREEITEM GetTreeItem() {return iterator.hItem; }
SelectedTreeItemDataIterator& operator++()
{
++iterator;
AdvanceToValidIterator();
return *this;
}
SelectedTreeItemDataIterator operator++(int) {SelectedTreeItemDataIterator old = *this; ++(*this); return old; }
private:
void AdvanceToValidIterator()
{
while (iterator.pCtrl && iterator.hItem && !iterator.pCtrl->GetItemData(iterator.hItem))
{
++iterator;
}
}
InternalIterator iterator;
};
template <typename T>
SelectedTreeItemDataIterator<T> BeginSelectedTreeItemData(CXTTreeCtrl* pCtrl)
{
return SelectedTreeItemDataIterator<T>(BeginSelectedTreeItems(pCtrl));
}
template <typename T>
SelectedTreeItemDataIterator<T> EndSelectedTreeItemData(CXTTreeCtrl* pCtrl)
{
return SelectedTreeItemDataIterator<T>(EndSelectedTreeItems(pCtrl));
}
}
#endif // CRYINCLUDE_EDITOR_CONTROLS_TREECTRLUTILS_H