4#include "acme/handler/item.h"
5#include "acme/prototype/data/tree_item_base.h"
14 template < prototype_item ITEM >
17 template < prototype_item ITEM >
20 template < prototype_item ITEM >
31 template < prototype_item ITEM >
33 virtual public tree_item_base
41 ::pointer<tree_item> m_pprevious2;
42 ::pointer<tree_item> m_pnext2;
43 ::pointer < ::pointer_array < tree_item > > m_ptreeitema2;
65 ::pointer < tree_item > m_ptreeitemParent;
67 tree < ITEM > * m_ptree;
69 ::pointer < ITEM > m_pitem;
76 ~tree_item()
override;
82 virtual ::i64 increment_reference_count()
override
85 return ::particle::increment_reference_count();
89 virtual ::i64 decrement_reference_count()
override
92 return ::particle::decrement_reference_count();
98 void clear_cache()
override;
99 void destroy()
override;
100 bool erase_item_from_parent()
override;
103 void _set_tree(
tree_base * ptree)
override;
106 tree_item * get_child_by_user_data(uptr iUserData);
107 tree_item * find_next_by_user_data(uptr iUserData);
108 void get_children(::data::tree_item_ptr_array < ITEM > & ptra);
109 ::collection::count get_children_count()
override;
110 tree_item * get_parent();
111 ::collection::count get_expandable_children_count()
override;
112 ::collection::count get_proper_descendant_count()
override;
113 virtual tree_item * get_expandable_child(::collection::index iIndex);
115 bool insert(enum_relative erelative, tree_item * pitemNew);
117 ::collection::index calc_level()
override;
118 ::collection::index get_level()
override;
119 ::collection::index get_index()
override;
122 inline auto previous()
124 return m_bPrevious ? m_pprevious2.m_p : _previous();
128 return m_bNext ? m_pnext2.m_p : _next();
132 return !m_ptreeitema2 || m_ptreeitema2->is_empty() ? nullptr : m_ptreeitema2->first();
136 return !m_ptreeitema2 || m_ptreeitema2->is_empty() ? nullptr : m_ptreeitema2->last();
139 tree_item_base * _get_parent()
override;
142 ::pointer_array < tree_item > * itema() {
return m_ptreeitema2; }
145 tree_item_base * __previous()
override {
return previous(); }
146 tree_item_base * __next()
override {
return next(); }
147 tree_item_base * __head()
override {
return head(); }
148 tree_item_base * __tail()
override {
return tail(); }
150 virtual tree_item * _previous();
151 virtual tree_item * _next();
152 virtual tree_item * _head();
153 virtual tree_item * _tail();
156 tree_item * get_previous_or_parent(::collection::index * iLevelOffset =
nullptr);
157 tree_item * get_previous();
160 tree_item * get_next();
161 tree_item * get_next_or_parent_next(::collection::index * iLevelOffset =
nullptr);
162 tree_item * get_child_or_next(::collection::index * iLevelOffset =
nullptr);
163 tree_item * get_child_next_or_parent(::collection::index * iLevelOffset =
nullptr);
166 inline const tree_item * get_child_next_or_parent(::collection::index * iLevelOffset =
nullptr)
const
169 return ((tree_item *)(
this))->get_child_next_or_parent(iLevelOffset);
177 tree_item * first_child();
180 virtual void sort_children(const ::function <
bool(
const tree_item * p1,
const tree_item * p2) > & functionLess);
184 inline tree_item * get_proper_next(::collection::index * pindexLevel =
nullptr)
187 if ((m_etreeitemstate & ::data::e_tree_item_state_expanded))
190 return get_child_next_or_parent(pindexLevel);
196 return get_next_or_parent_next(pindexLevel);
202 virtual tree_item * get_item(enum_tree_navigation enavigation, ::collection::index * piLevelOffset =
nullptr);
203 virtual tree_item * get_item(enum_relative erelative);
205 virtual bool contains(
const tree_item * ptreeitem);
206 virtual tree_item * get_proper_item(::collection::index iIndex, ::collection::index * piLevel);
207 virtual ::collection::index get_proper_item_index(tree_item * pitem, ::collection::index * piLevel);
208 ::collection::count get_proper_item_count()
override;
210 tree < ITEM > * get_tree();
217 void set_parent(tree_item * pparent);
219 void erase_tree_item()
override;
220 void erase_tree_item_descendants()
override;
221 void erase_child(tree_item * ptreeitem);
226 void on_fill_children()
override;
229 bool is_descendant(tree_item * pitem);
230 bool is_ascendant(tree_item * pitem);
233 ::item * _item()
override;
234 void _set_item(
::item * pitem)
override;
237 ::collection::index _find_child(tree_item_base * ptreeitem)
const override
245 return m_ptreeitema2->find_first(
dynamic_cast <tree_item <ITEM >*
>(ptreeitem));
249 tree_item_base * _child_at(::collection::index i)
const override
259 return m_ptreeitema2->element_at(i);
261 void erase_child_at(::collection::index i)
override
271 m_ptreeitema2->erase_at(i);
275 void _insert_child_at(::collection::index i, tree_item_base * ptreeitemNew)
override
278 defer_construct_newø(m_ptreeitema2);
280 m_ptreeitema2->insert_at(i,
dynamic_cast <tree_item < ITEM > *
> (ptreeitemNew));
285 void _add_child(tree_item_base * ptreeitemNew)
override
288 defer_construct_newø(m_ptreeitema2);
290 m_ptreeitema2->add_item(ptreeitemNew);
295 void _set_child_at(::collection::index i, tree_item_base * ptreeitemSet)
override
298 defer_construct_newø(m_ptreeitema2);
300 m_ptreeitema2->set_at_grow(i,
dynamic_cast <::data::tree_item < ITEM > *
>(ptreeitemSet));
305 void erase_children()
override
315 m_ptreeitema2->clear();
324 template < prototype_item ITEM >
325 tree_item < ITEM >::tree_item()
336 template < prototype_item ITEM >
337 tree_item < ITEM >::~tree_item()
343 template < prototype_item ITEM >
344 tree <ITEM> * tree_item < ITEM >::get_tree()
352 template < prototype_item ITEM >
353 void tree_item < ITEM >::set_parent(
tree_item * pparent)
357 if (m_ptreeitemParent == pparent || pparent ==
this || is_descendant(pparent))
364 if (::is_set(pparent))
367 pparent->m_ptreeitema2->add_unique(
this);
371 m_ptreeitemParent->m_ptreeitema2->erase(
this);
373 m_ptreeitemParent = pparent;
375 for (
auto pitem : *m_ptreeitemParent->m_ptreeitema2)
378 pitem->clear_cache();
385 template < prototype_item ITEM >
386 void tree_item < ITEM >::erase_tree_item()
389 erase_tree_item_descendants();
391 if (m_ptreeitemParent)
394 m_ptreeitemParent->erase_child(
this);
401 template < prototype_item ITEM >
402 void tree_item < ITEM >::erase_child(
tree_item * ptreeitem)
412 auto iIndex = m_ptreeitema2->find_first(ptreeitem);
421 m_ptreeitema2->erase_at(iIndex);
423 for (
auto pitem : *m_ptreeitema2)
426 pitem->clear_cache();
433 template < prototype_item ITEM >
434 void tree_item < ITEM >::erase_tree_item_descendants()
445 for (
auto & p : *m_ptreeitema2)
448 p->erase_tree_item_descendants();
458 m_ptreeitema2->clear();
465 template < prototype_item ITEM >
466 tree_item <ITEM> * tree_item < ITEM >::find_next_by_user_data(uptr iUserData)
469 auto ptreeitem =
this;
474 ptreeitem = ptreeitem->get_item(e_tree_navigation_expanded_forward);
483 if (ptreeitem->m_dwUser == (::u32)iUserData)
495 template < prototype_item ITEM >
496 void tree_item < ITEM >::clear_cache()
506 template < prototype_item ITEM >
507 void tree_item < ITEM >::destroy()
510 m_ptreeitemParent.release();
515 m_ptreeitema2.defer_destroy_and_release();
524 template < prototype_item ITEM >
525 bool tree_item < ITEM >::erase_item_from_parent()
528 auto ptreeitemParent = m_ptreeitemParent;
530 if (!ptreeitemParent)
537 auto ptreeitema = ptreeitemParent->m_ptreeitema2;
546 if (!ptreeitema->contains(
this))
550 m_ptreeitemParent =
nullptr;
556 ptreeitema->erase(
this);
558 for (
auto p : *ptreeitema)
565 m_ptreeitemParent =
nullptr;
572 template < prototype_item ITEM >
573 bool tree_item < ITEM >::contains(
const tree_item * ptreeitem)
576 if (ptreeitem ==
this)
590 for (
auto & p : *m_ptreeitema2)
593 if (p->contains(ptreeitem))
607 template < prototype_item ITEM >
608 bool tree_item < ITEM >::insert(enum_relative erelative,
tree_item * pitemNew)
611 if (contains(pitemNew))
614 throw ::exception(error_wrong_state);
618 if (erelative == e_relative_first_child)
621 pitemNew->erase_item_from_parent();
623 defer_construct_newø(m_ptreeitema2);
625 m_ptreeitema2->insert_at(0, pitemNew);
627 for (
auto & pitem : *m_ptreeitema2)
630 pitem->clear_cache();
634 pitemNew->m_iLevel = m_iLevel + 1;
636 pitemNew->m_ptreeitemParent =
this;
641 else if (erelative == e_relative_last_child)
644 pitemNew->erase_item_from_parent();
646 defer_construct_newø(m_ptreeitema2);
648 m_ptreeitema2->add(pitemNew);
650 for (
auto & pitem : *m_ptreeitema2)
653 pitem->clear_cache();
657 pitemNew->m_iLevel = m_iLevel + 1;
659 pitemNew->m_ptreeitemParent =
this;
664 else if (erelative == e_relative_previous_sibling)
667 ASSERT(m_ptreeitemParent !=
nullptr);
669 if (m_ptreeitemParent ==
nullptr)
676 auto iFind = m_ptreeitemParent->m_ptreeitema2->find_first(
this);
682 m_ptreeitemParent =
nullptr;
688 m_ptreeitemParent->m_ptreeitema2->insert_at(iFind, pitemNew);
690 for (
auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
693 pitem->clear_cache();
697 pitemNew->m_iLevel = m_iLevel;
699 pitemNew->m_ptreeitemParent = m_ptreeitemParent;
704 else if (erelative == e_relative_next_sibling)
707 if (m_ptreeitemParent ==
nullptr)
714 auto iFind = m_ptreeitemParent->m_ptreeitema2->find_first(
this);
720 m_ptreeitemParent =
nullptr;
726 m_ptreeitemParent->m_ptreeitema2->insert_at(iFind + 1, pitemNew);
728 for (
auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
731 pitem->clear_cache();
735 pitemNew->m_iLevel = m_iLevel;
737 pitemNew->m_ptreeitemParent = m_ptreeitemParent;
742 else if (erelative == e_relative_last_sibling)
745 m_ptreeitemParent->defer_construct_newø(m_ptreeitemParent->m_ptreeitema2);
747 m_ptreeitemParent->m_ptreeitema2->add(pitemNew);
749 for (
auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
752 pitem->clear_cache();
756 pitemNew->m_iLevel = m_iLevel;
758 pitemNew->m_ptreeitemParent = m_ptreeitemParent;
763 else if (erelative == e_relative_replace)
766 defer_construct_newø(m_ptreeitemParent->m_ptreeitema2);
768 auto iFind = m_ptreeitemParent->m_ptreeitema2->find_first(
this);
773 m_ptreeitemParent =
nullptr;
779 m_ptreeitemParent->m_ptreeitema2->element_at(iFind) = pitemNew;
781 for (
auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
784 pitem->clear_cache();
788 m_ptreeitemParent =
nullptr;
801 template < prototype_item ITEM >
802 void tree_item < ITEM >::sort_children(const ::function < bool(
const tree_item * p1,
const tree_item * p2) > & functionLess)
814 m_ptreeitema2->predicate_sort(functionLess);
816 for (
auto & pitem : *m_ptreeitema2)
819 pitem->clear_cache();
827 template < prototype_item ITEM >
828 tree_item <ITEM> * tree_item < ITEM >::get_child_by_user_data(uptr iUserData)
838 auto iFind = m_ptreeitema2->predicate_find_first([iUserData](
auto p)
841 return p->m_dwUser == iUserData;
852 return m_ptreeitema2->element_at(iFind);
857 template < prototype_item ITEM >
864 ptra.append(*m_ptreeitema2);
871 template < prototype_item ITEM >
872 ::collection::count tree_item < ITEM >::get_children_count()
882 return m_ptreeitema2->get_count();
887 template < prototype_item ITEM >
888 tree_item < ITEM > * tree_item < ITEM >::get_parent()
891 return m_ptreeitemParent;
896 template < prototype_item ITEM >
897 ::collection::count tree_item < ITEM >::get_expandable_children_count()
908 ::collection::count c = 0;
910 for (
auto & p : *m_ptreeitema2)
913 if (p->get_children_count() > 0)
927 template < prototype_item ITEM >
928 tree_item <ITEM> * tree_item < ITEM >::get_expandable_child(::collection::index iIndex)
939 ::collection::count c = 0;
941 auto iFind = m_ptreeitema2->predicate_find_first([&c, iIndex](
auto & p)
944 if (p->get_children_count() > 0)
967 return m_ptreeitema2->element_at(iFind);
972 template < prototype_item ITEM >
973 ::collection::count tree_item < ITEM >::get_proper_descendant_count()
976 ::collection::count iCount = 0;
978 ::collection::index iLevel = 0;
985 pitem = pitem->get_item(e_tree_navigation_proper_forward, &iLevel);
987 if (pitem ==
nullptr || iLevel <= 0)
1003 template < prototype_item ITEM >
1004 inline tree_item<ITEM> * tree_item < ITEM >::get_previous_or_parent(::collection::index * piLevel)
1007 auto p = previous();
1016 if (m_ptreeitemParent)
1019 return m_ptreeitemParent;
1037 template < prototype_item ITEM >
1046 template < prototype_item ITEM >
1055 template < prototype_item ITEM >
1056 ::collection::index tree_item < ITEM >::calc_level()
1066 while (p !=
nullptr)
1071 p = p->m_ptreeitemParent;
1082 template < prototype_item ITEM >
1083 ::collection::index tree_item < ITEM >::get_level()
1086 return m_iLevel >= 0 ? m_iLevel : calc_level();
1091 template < prototype_item ITEM >
1097 if (::is_null(m_ptreeitemParent))
1100 m_pprevious2.release();
1106 auto iFind = get_index();
1111 m_pprevious2.release();
1117 return m_pprevious2 = m_ptreeitemParent->m_ptreeitema2->element_at(iFind - 1);
1122 template < prototype_item ITEM >
1123 tree_item <ITEM> * tree_item < ITEM >::_next()
1128 if (::is_null(m_ptreeitemParent))
1137 auto iFind = get_index();
1139 if (iFind < 0 || iFind >= m_ptreeitemParent->m_ptreeitema2->get_upper_bound())
1148 return m_pnext2 = m_ptreeitemParent->m_ptreeitema2->element_at(iFind + 1);
1154 template < prototype_item ITEM >
1158 if (::is_null(m_ptreeitema2))
1165 return m_ptreeitema2->first();
1170 template < prototype_item ITEM >
1171 tree_item <ITEM> * tree_item < ITEM >::_tail()
1174 if (::is_null(m_ptreeitema2))
1181 return m_ptreeitema2->last();
1186 template < prototype_item ITEM >
1190 return m_ptreeitemParent;
1225 template < prototype_item ITEM >
1226 ::collection::index tree_item < ITEM >::get_index()
1236 if (m_ptreeitemParent ==
nullptr)
1245 return m_iIndex = m_ptreeitemParent->m_ptreeitema2->find_first(
this);
1250 template < prototype_item ITEM >
1251 tree_item<ITEM> * tree_item < ITEM >::get_next_or_parent_next(::collection::index * piLevel)
1261 if (!m_ptreeitemParent)
1275 return m_ptreeitemParent->get_next_or_parent_next(piLevel);
1280 template < prototype_item ITEM >
1281 tree_item<ITEM> * tree_item < ITEM >::get_child_or_next(::collection::index * piLevel)
1303 template < prototype_item ITEM >
1304 tree_item<ITEM> * tree_item < ITEM >::get_child_next_or_parent(::collection::index * piLevel)
1321 return get_next_or_parent_next(piLevel);
1326 template < prototype_item ITEM >
1327 tree_item<ITEM> * tree_item < ITEM >::get_item(enum_tree_navigation enavigation, ::collection::index * pindexLevel)
1330 switch (enavigation)
1332 case e_tree_navigation_expanded_forward:
1334 return get_child_next_or_parent(pindexLevel);
1336 case e_tree_navigation_proper_forward:
1338 return get_proper_next(pindexLevel);
1349 template < prototype_item ITEM >
1350 tree_item<ITEM> * tree_item < ITEM >::get_item(enum_relative erelative)
1355 case e_relative_first_child:
1360 case e_relative_last_child:
1364 case e_relative_parent:
1366 return m_ptreeitemParent;
1369 case e_relative_first_sibling:
1371 return m_ptreeitemParent->head();
1374 case e_relative_previous_sibling:
1379 case e_relative_next_sibling:
1384 case e_relative_last_sibling:
1386 return m_ptreeitemParent->tail();
1398 template < prototype_item ITEM >
1455 template < prototype_item ITEM >
1456 tree_item<ITEM> * tree_item < ITEM >::get_proper_item(::collection::index iIndex, ::collection::index * piLevel)
1468 while (pitem && iIndex >= 0)
1471 pitem = pitem->get_item(e_tree_navigation_proper_forward, piLevel);
1489 template < prototype_item ITEM >
1490 ::collection::index tree_item < ITEM >::get_proper_item_index(
tree_item * pitemParam, ::collection::index * piLevel)
1507 pitem = pitem->get_item(e_tree_navigation_proper_forward, piLevel);
1509 if (pitem == pitemParam)
1525 template < prototype_item ITEM >
1526 ::collection::count tree_item < ITEM >::get_proper_item_count()
1531 ::collection::index iLevel = 0;
1533 ::collection::count iCount = -1;
1538 pitem = pitem->get_item(e_tree_navigation_proper_forward, &iLevel);
1542 if (iCount >= 65536)
1563 template < prototype_item ITEM >
1564 ::i32_boolean tree_item < ITEM >::is_expanded()
const
1567 return m_etreeitemstate & ::data::e_tree_item_state_expanded;
1572 template < prototype_item ITEM >
1573 ::i32_boolean tree_item < ITEM >::is_expandable()
const
1576 return m_etreeitemstate & ::data::e_tree_item_state_expandable;
1581 template < prototype_item ITEM >
1582 bool tree_item < ITEM >::is_descendant(
tree_item * pitem)
1585 if (pitem ==
nullptr)
1592 return pitem->is_ascendant(
this);
1597 template < prototype_item ITEM >
1598 bool tree_item < ITEM >::is_ascendant(
tree_item * pitem)
1601 if (pitem ==
nullptr)
1608 tree_item * pparent = m_ptreeitemParent;
1610 if (pparent ==
nullptr)
1617 while (pparent !=
nullptr)
1620 if (pparent == pitem)
1623 pparent = pparent->m_ptreeitemParent;
1632 template < prototype_item ITEM >
1634 tree_item < ITEM >::on_fill_children()
1644 for (
auto & p : *m_ptreeitema2)
1647 if (p->is_expanded())
1650 p->on_fill_children();
1659 template < prototype_item ITEM >
1660 ::item * tree_item < ITEM >::_item()
1668 template < prototype_item ITEM >
1669 void tree_item < ITEM >::_set_item(::item * pitem)
1677 template < prototype_item ITEM >
Definition tree_base.h:20
Definition tree_item_base.h:18
Definition tree_item.h:1680
Definition tree_item.h:34
Definition pointer_array.h:1882