acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
tree_item.h
1#pragma once
2
3
4#include "acme/handler/item.h"
5#include "acme/prototype/data/tree_item_base.h"
6
7
8
9
10namespace data
11{
12
13
14 template < prototype_item ITEM >
15 class tree_item;
16
17 template < prototype_item ITEM >
19
20 template < prototype_item ITEM >
21 class tree;
22
23
24} // namespace data
25
26
27namespace data
28{
29
30
31 template < prototype_item ITEM >
32 class tree_item :
33 virtual public tree_item_base
34 {
35 protected:
36
37
38 //bool m_bPrevious = false;
39 //bool m_bNext = false;
40
41 ::pointer<tree_item> m_pprevious2;
42 ::pointer<tree_item> m_pnext2;
43 ::pointer < ::pointer_array < tree_item > > m_ptreeitema2;
44 //::collection::index m_iIndex = -2;
45
46 public:
47
48
49 //enum enum_flag
50 //{
51
52 // flag_previous_or_parent = 1,
53 // flag_previous = 2,
54 // flag_next = 4,
55 // flag_next_or_parent = 8,
56 // flag_child_or_next = 16,
57 // flag_child_next_or_parent = 32,
58 // flag_previoub = flag_previous_or_parent | flag_previous,
59 // flag_nexts = flag_next | flag_next_or_parent | flag_child_or_next| flag_child_next_or_parent,
60
61 //};
62
63 //::pointer<tree_item> m_phead; // first child
64 //::pointer<tree_item> m_ptail; // last child
65 ::pointer < tree_item > m_ptreeitemParent;
66 //::collection::index m_iIndexHint;
67 tree < ITEM > * m_ptree;
68 //::collection::index m_iLevel;
69 ::pointer < ITEM > m_pitem;
70 //uptr m_dwUser;
71 //::u32 m_etreeitemstate;
72 //uptr m_dwMetaData;
73
74
75 tree_item();
76 ~tree_item() override;
77
78
79#ifdef _DEBUG
80
81
82 virtual ::i64 increment_reference_count() override
83 {
84
85 return ::particle::increment_reference_count();
86
87 }
88
89 virtual ::i64 decrement_reference_count() override
90 {
91
92 return ::particle::decrement_reference_count();
93
94 }
95
96
97#endif
98 void clear_cache() override;
99 void destroy() override;
100 bool erase_item_from_parent() override;
101
102 tree_base * _get_tree() const override;
103 void _set_tree(tree_base * ptree) override;
104
105
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);
114
115 bool insert(enum_relative erelative, tree_item * pitemNew);
116
117 ::collection::index calc_level() override;
118 ::collection::index get_level() override;
119 ::collection::index get_index() override;
120
121
122 inline auto previous()
123 {
124 return m_bPrevious ? m_pprevious2.m_p : _previous();
125 }
126 inline auto next()
127 {
128 return m_bNext ? m_pnext2.m_p : _next();
129 }
130 inline auto head()
131 {
132 return !m_ptreeitema2 || m_ptreeitema2->is_empty() ? nullptr : m_ptreeitema2->first();
133 }
134 inline auto tail()
135 {
136 return !m_ptreeitema2 || m_ptreeitema2->is_empty() ? nullptr : m_ptreeitema2->last();
137 }
138
139 tree_item_base * _get_parent() override;
140
141
142 ::pointer_array < tree_item > * itema() { return m_ptreeitema2; }
143
144
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(); }
149
150 virtual tree_item * _previous();
151 virtual tree_item * _next();
152 virtual tree_item * _head();
153 virtual tree_item * _tail();
154
155
156 tree_item * get_previous_or_parent(::collection::index * iLevelOffset = nullptr);
157 tree_item * get_previous();
158
159
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);
164
165
166 inline const tree_item * get_child_next_or_parent(::collection::index * iLevelOffset = nullptr) const
167 {
168
169 return ((tree_item *)(this))->get_child_next_or_parent(iLevelOffset);
170
171 }
172
173 //tree_item * calc_previous(bool bParent = true);
174
175 //tree_item * calc_next(bool bChild, bool bParent = true, ::collection::index * pindexLevel = nullptr);
176
177 tree_item * first_child();
178
179 // [](const ::data::tree_item * pitem1, const ::data::tree_item * pitem2)
180 virtual void sort_children(const ::function < bool(const tree_item * p1, const tree_item * p2) > & functionLess);
181
182
183
184 inline tree_item * get_proper_next(::collection::index * pindexLevel = nullptr)
185 {
186
187 if ((m_etreeitemstate & ::data::e_tree_item_state_expanded))
188 {
189
190 return get_child_next_or_parent(pindexLevel);
191
192 }
193 else
194 {
195
196 return get_next_or_parent_next(pindexLevel);
197
198 }
199
200 }
201
202 virtual tree_item * get_item(enum_tree_navigation enavigation, ::collection::index * piLevelOffset = nullptr);
203 virtual tree_item * get_item(enum_relative erelative);
204
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;
209
210 tree < ITEM > * get_tree();
211
212 // string get_text() const override;
213 // ::collection::index get_image() const override;
214 // ::image::image_list * get_image_list() const override;
215
216
217 void set_parent(tree_item * pparent);
218
219 void erase_tree_item() override;
220 void erase_tree_item_descendants() override;
221 void erase_child(tree_item * ptreeitem);
222
223 ::i32_boolean is_expanded() const override;
224 ::i32_boolean is_expandable() const override;
225
226 void on_fill_children() override;
227
228
229 bool is_descendant(tree_item * pitem);
230 bool is_ascendant(tree_item * pitem);
231
232
233 ::item * _item() override;
234 void _set_item(::item * pitem) override;
235
236
237 ::collection::index _find_child(tree_item_base * ptreeitem) const override
238 {
239 if (!m_ptreeitema2)
240 {
241
242 return -1;
243
244 }
245 return m_ptreeitema2->find_first(dynamic_cast <tree_item <ITEM >*>(ptreeitem));
246 }
247
248
249 tree_item_base * _child_at(::collection::index i) const override
250 {
251
252 if (!m_ptreeitema2)
253 {
254
255 return nullptr;
256
257 }
258
259 return m_ptreeitema2->element_at(i);
260 }
261 void erase_child_at(::collection::index i) override
262 {
263
264 if (!m_ptreeitema2)
265 {
266
267 return;
268
269 }
270
271 m_ptreeitema2->erase_at(i);
272 }
273
274
275 void _insert_child_at(::collection::index i, tree_item_base * ptreeitemNew) override
276 {
277
278 defer_construct_newø(m_ptreeitema2);
279
280 m_ptreeitema2->insert_at(i, dynamic_cast <tree_item < ITEM > *> (ptreeitemNew));
281
282 }
283
284
285 void _add_child(tree_item_base * ptreeitemNew) override
286 {
287
288 defer_construct_newø(m_ptreeitema2);
289
290 m_ptreeitema2->add_item(ptreeitemNew);
291
292 }
293
294
295 void _set_child_at(::collection::index i, tree_item_base * ptreeitemSet) override
296 {
297
298 defer_construct_newø(m_ptreeitema2);
299
300 m_ptreeitema2->set_at_grow(i, dynamic_cast <::data::tree_item < ITEM > *>(ptreeitemSet));
301
302 }
303
304
305 void erase_children() override
306 {
307
308 if (!m_ptreeitema2)
309 {
310
311 return;
312
313 }
314
315 m_ptreeitema2->clear();
316
317 }
318
319
320 };
321
322
323
324 template < prototype_item ITEM >
325 tree_item < ITEM >::tree_item()
326 {
327
328 m_iIndexHint = -1;
329 m_dwUser = 0;
330 m_ptree = nullptr;
331 m_iLevel = -1;
332
333 }
334
335
336 template < prototype_item ITEM >
337 tree_item < ITEM >::~tree_item()
338 {
339
340 }
341
342
343 template < prototype_item ITEM >
344 tree <ITEM> * tree_item < ITEM >::get_tree()
345 {
346
347 return m_ptree;
348
349 }
350
351
352 template < prototype_item ITEM >
353 void tree_item < ITEM >::set_parent(tree_item * pparent)
354 {
355
356 //if(m_ptreeitemParent == pparent || pparent == this || is_descendant(pparent) || is_ascendant(pparent))
357 if (m_ptreeitemParent == pparent || pparent == this || is_descendant(pparent))
358 {
359
360 return;
361
362 }
363
364 if (::is_set(pparent))
365 {
366
367 pparent->m_ptreeitema2->add_unique(this);
368
369 }
370
371 m_ptreeitemParent->m_ptreeitema2->erase(this);
372
373 m_ptreeitemParent = pparent;
374
375 for (auto pitem : *m_ptreeitemParent->m_ptreeitema2)
376 {
377
378 pitem->clear_cache();
379
380 }
381
382 }
383
384
385 template < prototype_item ITEM >
386 void tree_item < ITEM >::erase_tree_item()
387 {
388
389 erase_tree_item_descendants();
390
391 if (m_ptreeitemParent)
392 {
393
394 m_ptreeitemParent->erase_child(this);
395
396 }
397
398 }
399
400
401 template < prototype_item ITEM >
402 void tree_item < ITEM >::erase_child(tree_item * ptreeitem)
403 {
404
405 if (!m_ptreeitema2)
406 {
407
408 return;
409
410 }
411
412 auto iIndex = m_ptreeitema2->find_first(ptreeitem);
413
414 if (iIndex < 0)
415 {
416
417 return;
418
419 }
420
421 m_ptreeitema2->erase_at(iIndex);
422
423 for (auto pitem : *m_ptreeitema2)
424 {
425
426 pitem->clear_cache();
427
428 }
429
430 }
431
432
433 template < prototype_item ITEM >
434 void tree_item < ITEM >::erase_tree_item_descendants()
435 {
436
437 if (!m_ptreeitema2)
438 {
439
440 return;
441
442 }
443
444
445 for (auto & p : *m_ptreeitema2)
446 {
447
448 p->erase_tree_item_descendants();
449
450 p->clear_cache();
451
452 }
453
454 //list_predicate(this, [](auto p) { p->erase_tree_item(); });
455
456 //list_erase_all(this);
457
458 m_ptreeitema2->clear();
459
460 clear_cache();
461
462 }
463
464
465 template < prototype_item ITEM >
466 tree_item <ITEM> * tree_item < ITEM >::find_next_by_user_data(uptr iUserData)
467 {
468
469 auto ptreeitem = this;
470
471 while (true)
472 {
473
474 ptreeitem = ptreeitem->get_item(e_tree_navigation_expanded_forward);
475
476 if (!ptreeitem)
477 {
478
479 return nullptr;
480
481 }
482
483 if (ptreeitem->m_dwUser == (::u32)iUserData)
484 {
485
486 return ptreeitem;
487
488 }
489
490 }
491
492 }
493
494
495 template < prototype_item ITEM >
496 void tree_item < ITEM >::clear_cache()
497 {
498
499 m_bPrevious = false;
500 m_bNext = false;
501 m_iIndex = -2;
502
503 }
504
505
506 template < prototype_item ITEM >
507 void tree_item < ITEM >::destroy()
508 {
509
510 m_ptreeitemParent.release();
511
512 if (m_ptreeitema2)
513 {
514
515 m_ptreeitema2.defer_destroy_and_release();
516
517 }
518
519 m_ptree = nullptr;
520
521 }
522
523
524 template < prototype_item ITEM >
525 bool tree_item < ITEM >::erase_item_from_parent()
526 {
527
528 auto ptreeitemParent = m_ptreeitemParent;
529
530 if (!ptreeitemParent)
531 {
532
533 return true;
534
535 }
536
537 auto ptreeitema = ptreeitemParent->m_ptreeitema2;
538
539 if (!ptreeitema)
540 {
541
542 return true;
543
544 }
545
546 if (!ptreeitema->contains(this))
547 {
548
549 // self healing?
550 m_ptreeitemParent = nullptr;
551
552 return false;
553
554 }
555
556 ptreeitema->erase(this);
557
558 for (auto p : *ptreeitema)
559 {
560
561 p->clear_cache();
562
563 }
564
565 m_ptreeitemParent = nullptr;
566
567 return true;
568
569 }
570
571
572 template < prototype_item ITEM >
573 bool tree_item < ITEM >::contains(const tree_item * ptreeitem)
574 {
575
576 if (ptreeitem == this)
577 {
578
579 return true;
580
581 }
582
583 if (!m_ptreeitema2)
584 {
585
586 return false;
587
588 }
589
590 for (auto & p : *m_ptreeitema2)
591 {
592
593 if (p->contains(ptreeitem))
594 {
595
596 return true;
597
598 }
599
600 }
601
602 return false;
603
604 }
605
606
607 template < prototype_item ITEM >
608 bool tree_item < ITEM >::insert(enum_relative erelative, tree_item * pitemNew)
609 {
610
611 if (contains(pitemNew))
612 {
613
614 throw ::exception(error_wrong_state);
615
616 }
617
618 if (erelative == e_relative_first_child)
619 {
620
621 pitemNew->erase_item_from_parent();
622
623 defer_construct_newø(m_ptreeitema2);
624
625 m_ptreeitema2->insert_at(0, pitemNew);
626
627 for (auto & pitem : *m_ptreeitema2)
628 {
629
630 pitem->clear_cache();
631
632 }
633
634 pitemNew->m_iLevel = m_iLevel + 1;
635
636 pitemNew->m_ptreeitemParent = this;
637
638 return true;
639
640 }
641 else if (erelative == e_relative_last_child)
642 {
643
644 pitemNew->erase_item_from_parent();
645
646 defer_construct_newø(m_ptreeitema2);
647
648 m_ptreeitema2->add(pitemNew);
649
650 for (auto & pitem : *m_ptreeitema2)
651 {
652
653 pitem->clear_cache();
654
655 }
656
657 pitemNew->m_iLevel = m_iLevel + 1;
658
659 pitemNew->m_ptreeitemParent = this;
660
661 return true;
662
663 }
664 else if (erelative == e_relative_previous_sibling)
665 {
666
667 ASSERT(m_ptreeitemParent != nullptr);
668
669 if (m_ptreeitemParent == nullptr)
670 {
671
672 return false;
673
674 }
675
676 auto iFind = m_ptreeitemParent->m_ptreeitema2->find_first(this);
677
678 if (iFind < 0)
679 {
680
681 // self-healinng
682 m_ptreeitemParent = nullptr;
683
684 return false;
685
686 }
687
688 m_ptreeitemParent->m_ptreeitema2->insert_at(iFind, pitemNew);
689
690 for (auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
691 {
692
693 pitem->clear_cache();
694
695 }
696
697 pitemNew->m_iLevel = m_iLevel;
698
699 pitemNew->m_ptreeitemParent = m_ptreeitemParent;
700
701 return true;
702
703 }
704 else if (erelative == e_relative_next_sibling)
705 {
706
707 if (m_ptreeitemParent == nullptr)
708 {
709
710 return false;
711
712 }
713
714 auto iFind = m_ptreeitemParent->m_ptreeitema2->find_first(this);
715
716 if (iFind < 0)
717 {
718
719 // self-healing
720 m_ptreeitemParent = nullptr;
721
722 return false;
723
724 }
725
726 m_ptreeitemParent->m_ptreeitema2->insert_at(iFind + 1, pitemNew);
727
728 for (auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
729 {
730
731 pitem->clear_cache();
732
733 }
734
735 pitemNew->m_iLevel = m_iLevel;
736
737 pitemNew->m_ptreeitemParent = m_ptreeitemParent;
738
739 return true;
740
741 }
742 else if (erelative == e_relative_last_sibling)
743 {
744
745 m_ptreeitemParent->defer_construct_newø(m_ptreeitemParent->m_ptreeitema2);
746
747 m_ptreeitemParent->m_ptreeitema2->add(pitemNew);
748
749 for (auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
750 {
751
752 pitem->clear_cache();
753
754 }
755
756 pitemNew->m_iLevel = m_iLevel;
757
758 pitemNew->m_ptreeitemParent = m_ptreeitemParent;
759
760 return true;
761
762 }
763 else if (erelative == e_relative_replace)
764 {
765
766 defer_construct_newø(m_ptreeitemParent->m_ptreeitema2);
767
768 auto iFind = m_ptreeitemParent->m_ptreeitema2->find_first(this);
769
770 if (iFind < 0)
771 {
772
773 m_ptreeitemParent = nullptr;
774
775 return false;
776
777 }
778
779 m_ptreeitemParent->m_ptreeitema2->element_at(iFind) = pitemNew;
780
781 for (auto & pitem : *m_ptreeitemParent->m_ptreeitema2)
782 {
783
784 pitem->clear_cache();
785
786 }
787
788 m_ptreeitemParent = nullptr;
789
790 erase_tree_item();
791
792 return true;
793
794 }
795
796 return false;
797
798 }
799
800
801 template < prototype_item ITEM >
802 void tree_item < ITEM >::sort_children(const ::function < bool(const tree_item * p1, const tree_item * p2) > & functionLess)
803 {
804
805 if (!m_ptreeitema2)
806 {
807
808 return;
809
810 }
811
812 //data_tree_item_list_sort(this, functionLess);
813
814 m_ptreeitema2->predicate_sort(functionLess);
815
816 for (auto & pitem : *m_ptreeitema2)
817 {
818
819 pitem->clear_cache();
820
821 }
822
823
824 }
825
826
827 template < prototype_item ITEM >
828 tree_item <ITEM> * tree_item < ITEM >::get_child_by_user_data(uptr iUserData)
829 {
830
831 if (!m_ptreeitema2)
832 {
833
834 return nullptr;
835
836 }
837
838 auto iFind = m_ptreeitema2->predicate_find_first([iUserData](auto p)
839 {
840
841 return p->m_dwUser == iUserData;
842
843 });
844
845 if (iFind < 0)
846 {
847
848 return nullptr;
849
850 }
851
852 return m_ptreeitema2->element_at(iFind);
853
854 }
855
856
857 template < prototype_item ITEM >
858 void tree_item < ITEM >::get_children(tree_item_ptr_array<ITEM> & ptra)
859 {
860
861 if (m_ptreeitema2)
862 {
863
864 ptra.append(*m_ptreeitema2);
865
866 }
867
868 }
869
870
871 template < prototype_item ITEM >
872 ::collection::count tree_item < ITEM >::get_children_count()
873 {
874
875 if (!m_ptreeitema2)
876 {
877
878 return 0;
879
880 }
881
882 return m_ptreeitema2->get_count();
883
884 }
885
886
887 template < prototype_item ITEM >
888 tree_item < ITEM > * tree_item < ITEM >::get_parent()
889 {
890
891 return m_ptreeitemParent;
892
893 }
894
895
896 template < prototype_item ITEM >
897 ::collection::count tree_item < ITEM >::get_expandable_children_count()
898 {
899
900 if (!m_ptreeitema2)
901 {
902
903 return 0;
904
905 }
906
907
908 ::collection::count c = 0;
909
910 for (auto & p : *m_ptreeitema2)
911 {
912
913 if (p->get_children_count() > 0)
914 {
915
916 c++;
917
918 }
919
920 }
921
922 return c;
923
924 }
925
926
927 template < prototype_item ITEM >
928 tree_item <ITEM> * tree_item < ITEM >::get_expandable_child(::collection::index iIndex)
929 {
930
931
932 if (!m_ptreeitema2)
933 {
934
935 return nullptr;
936
937 }
938
939 ::collection::count c = 0;
940
941 auto iFind = m_ptreeitema2->predicate_find_first([&c, iIndex](auto & p)
942 {
943
944 if (p->get_children_count() > 0)
945 {
946
947 if (c == iIndex)
948 {
949
950 return true;
951
952 }
953
954 }
955
956 return false;
957
958 });
959
960 if (iFind < 0)
961 {
962
963 return nullptr;
964
965 }
966
967 return m_ptreeitema2->element_at(iFind);
968
969 }
970
971
972 template < prototype_item ITEM >
973 ::collection::count tree_item < ITEM >::get_proper_descendant_count()
974 {
975
976 ::collection::count iCount = 0;
977
978 ::collection::index iLevel = 0;
979
980 tree_item * pitem = this;
981
982 for (;;)
983 {
984
985 pitem = pitem->get_item(e_tree_navigation_proper_forward, &iLevel);
986
987 if (pitem == nullptr || iLevel <= 0)
988 {
989
990 break;
991
992 }
993
994 iCount++;
995
996 }
997
998 return iCount;
999
1000 }
1001
1002
1003 template < prototype_item ITEM >
1004 inline tree_item<ITEM> * tree_item < ITEM >::get_previous_or_parent(::collection::index * piLevel)
1005 {
1006
1007 auto p = previous();
1008
1009 if (p)
1010 {
1011
1012 return p;
1013
1014 }
1015
1016 if (m_ptreeitemParent)
1017 {
1018
1019 return m_ptreeitemParent;
1020
1021 //if (piLevel)
1022 //{
1023
1024 // (*piLevel)--;
1025
1026 //}
1027
1028 //return m_ptreeitemParent->get_previous_or_parent(piLevel);
1029
1030 }
1031
1032 return nullptr;
1033
1034 }
1035
1036
1037 template < prototype_item ITEM >
1038 tree_item<ITEM> * tree_item < ITEM >::get_previous()
1039 {
1040
1041 return previous();
1042
1043 }
1044
1045
1046 template < prototype_item ITEM >
1047 tree_item<ITEM> * tree_item < ITEM >::get_next()
1048 {
1049
1050 return next();
1051
1052 }
1053
1054
1055 template < prototype_item ITEM >
1056 ::collection::index tree_item < ITEM >::calc_level()
1057 {
1058
1059 if (m_iLevel < 0)
1060 {
1061
1062 m_iLevel = -1;
1063
1064 tree_item * p = this;
1065
1066 while (p != nullptr)
1067 {
1068
1069 m_iLevel++;
1070
1071 p = p->m_ptreeitemParent;
1072
1073 }
1074
1075 }
1076
1077 return m_iLevel;
1078
1079 }
1080
1081
1082 template < prototype_item ITEM >
1083 ::collection::index tree_item < ITEM >::get_level()
1084 {
1085
1086 return m_iLevel >= 0 ? m_iLevel : calc_level();
1087
1088 }
1089
1090
1091 template < prototype_item ITEM >
1092 tree_item<ITEM> * tree_item < ITEM >::_previous()
1093 {
1094
1095 m_bPrevious = true;
1096
1097 if (::is_null(m_ptreeitemParent))
1098 {
1099
1100 m_pprevious2.release();
1101
1102 return nullptr;
1103
1104 }
1105
1106 auto iFind = get_index();
1107
1108 if (iFind <= 0)
1109 {
1110
1111 m_pprevious2.release();
1112
1113 return nullptr;
1114
1115 }
1116
1117 return m_pprevious2 = m_ptreeitemParent->m_ptreeitema2->element_at(iFind - 1);
1118
1119 }
1120
1121
1122 template < prototype_item ITEM >
1123 tree_item <ITEM> * tree_item < ITEM >::_next()
1124 {
1125
1126 m_bNext = true;
1127
1128 if (::is_null(m_ptreeitemParent))
1129 {
1130
1131 m_pnext2.release();
1132
1133 return nullptr;
1134
1135 }
1136
1137 auto iFind = get_index();
1138
1139 if (iFind < 0 || iFind >= m_ptreeitemParent->m_ptreeitema2->get_upper_bound())
1140 {
1141
1142 m_pnext2.release();
1143
1144 return nullptr;
1145
1146 }
1147
1148 return m_pnext2 = m_ptreeitemParent->m_ptreeitema2->element_at(iFind + 1);
1149
1150 }
1151
1152
1153
1154 template < prototype_item ITEM >
1155 tree_item<ITEM> * tree_item < ITEM >::_head()
1156 {
1157
1158 if (::is_null(m_ptreeitema2))
1159 {
1160
1161 return nullptr;
1162
1163 }
1164
1165 return m_ptreeitema2->first();
1166
1167 }
1168
1169
1170 template < prototype_item ITEM >
1171 tree_item <ITEM> * tree_item < ITEM >::_tail()
1172 {
1173
1174 if (::is_null(m_ptreeitema2))
1175 {
1176
1177 return nullptr;
1178
1179 }
1180
1181 return m_ptreeitema2->last();
1182
1183 }
1184
1185
1186 template < prototype_item ITEM >
1187 tree_item_base * tree_item < ITEM >::_get_parent()
1188 {
1189
1190 return m_ptreeitemParent;
1191
1192 }
1193
1194
1195 //::data::tree_item * template < prototype_item ITEM > tree_item < ITEM >::head()
1196 //{
1197
1198 // if (m_treeitema.is_empty())
1199 // {
1200
1201 // return nullptr;
1202
1203 // }
1204
1205 // return m_treeitema.first();
1206
1207 //}
1208
1209
1210 //::data::tree_item * template < prototype_item ITEM > tree_item < ITEM >::tail()
1211 //{
1212
1213 // if (m_treeitema.is_empty())
1214 // {
1215
1216 // return nullptr;
1217
1218 // }
1219
1220 // return m_treeitema.last();
1221
1222 //}
1223
1224
1225 template < prototype_item ITEM >
1226 ::collection::index tree_item < ITEM >::get_index()
1227 {
1228
1229 if (m_iIndex >= -1)
1230 {
1231
1232 return m_iIndex;
1233
1234 }
1235
1236 if (m_ptreeitemParent == nullptr)
1237 {
1238
1239 m_iIndex = -1;
1240
1241 return -1;
1242
1243 }
1244
1245 return m_iIndex = m_ptreeitemParent->m_ptreeitema2->find_first(this);
1246
1247 }
1248
1249
1250 template < prototype_item ITEM >
1251 tree_item<ITEM> * tree_item < ITEM >::get_next_or_parent_next(::collection::index * piLevel)
1252 {
1253
1254 if (next())
1255 {
1256
1257 return next();
1258
1259 }
1260
1261 if (!m_ptreeitemParent)
1262 {
1263
1264 return nullptr;
1265
1266 }
1267
1268 if (piLevel)
1269 {
1270
1271 (*piLevel)--;
1272
1273 }
1274
1275 return m_ptreeitemParent->get_next_or_parent_next(piLevel);
1276
1277 }
1278
1279
1280 template < prototype_item ITEM >
1281 tree_item<ITEM> * tree_item < ITEM >::get_child_or_next(::collection::index * piLevel)
1282 {
1283
1284 if (head())
1285 {
1286
1287 if (piLevel)
1288 {
1289
1290 (*piLevel)++;
1291
1292 }
1293
1294 return head();
1295
1296 }
1297
1298 return next();
1299
1300 }
1301
1302
1303 template < prototype_item ITEM >
1304 tree_item<ITEM> * tree_item < ITEM >::get_child_next_or_parent(::collection::index * piLevel)
1305 {
1306
1307 if (head())
1308 {
1309
1310 if (piLevel)
1311 {
1312
1313 (*piLevel)++;
1314
1315 }
1316
1317 return head();
1318
1319 }
1320
1321 return get_next_or_parent_next(piLevel);
1322
1323 }
1324
1325
1326 template < prototype_item ITEM >
1327 tree_item<ITEM> * tree_item < ITEM >::get_item(enum_tree_navigation enavigation, ::collection::index * pindexLevel)
1328 {
1329
1330 switch (enavigation)
1331 {
1332 case e_tree_navigation_expanded_forward:
1333
1334 return get_child_next_or_parent(pindexLevel);
1335
1336 case e_tree_navigation_proper_forward:
1337
1338 return get_proper_next(pindexLevel);
1339
1340 default:
1341 // Not Expected
1342 ASSERT(false);
1343 return nullptr;
1344 }
1345
1346 }
1347
1348
1349 template < prototype_item ITEM >
1350 tree_item<ITEM> * tree_item < ITEM >::get_item(enum_relative erelative)
1351 {
1352
1353 switch (erelative)
1354 {
1355 case e_relative_first_child:
1356 {
1357 return head();
1358 }
1359 break;
1360 case e_relative_last_child:
1361 {
1362 return tail();
1363 }
1364 case e_relative_parent:
1365 {
1366 return m_ptreeitemParent;
1367 }
1368 break;
1369 case e_relative_first_sibling:
1370 {
1371 return m_ptreeitemParent->head();
1372 }
1373 break;
1374 case e_relative_previous_sibling:
1375 {
1376 return previous();
1377 }
1378 break;
1379 case e_relative_next_sibling:
1380 {
1381 return next();
1382 }
1383 break;
1384 case e_relative_last_sibling:
1385 {
1386 return m_ptreeitemParent->tail();
1387 }
1388 break;
1389 default:
1390 // Not Expected
1391 ASSERT(false);
1392 return nullptr;
1393 }
1394 }
1395
1396
1397
1398 template < prototype_item ITEM >
1399 tree_item<ITEM> * tree_item < ITEM >::first_child()
1400 {
1401
1402 return head();
1403
1404 }
1405
1406
1407 // template < prototype_item ITEM >
1408 // string tree_item < ITEM >::get_text() const
1409 // {
1410 //
1411 // if (!m_pitem)
1412 // {
1413 //
1414 // return "";
1415 //
1416 // }
1417 //
1418 // return m_pitem->data_item_get_text(m_ptree);
1419 //
1420 // }
1421 //
1422 //
1423 // template < prototype_item ITEM >
1424 // ::collection::index tree_item < ITEM >::get_image() const
1425 // {
1426 //
1427 // if (!m_pitem)
1428 // {
1429 //
1430 // return -1;
1431 //
1432 // }
1433 //
1434 // return m_pitem->data_item_get_image(m_ptree);
1435 //
1436 // }
1437 //
1438 //
1439 // template < prototype_item ITEM >
1440 // ::image::image_list * tree_item < ITEM >::get_image_list() const
1441 // {
1442 //
1443 // if (!m_pitem)
1444 // {
1445 //
1446 // return nullptr;
1447 //
1448 // }
1449 //
1450 // return m_pitem->data_item_get_image_list(m_ptree);
1451 //
1452 // }
1453
1454
1455 template < prototype_item ITEM >
1456 tree_item<ITEM> * tree_item < ITEM >::get_proper_item(::collection::index iIndex, ::collection::index * piLevel)
1457 {
1458
1459 if (*piLevel)
1460 {
1461
1462 *piLevel = 0;
1463
1464 }
1465
1466 tree_item * pitem = this;
1467
1468 while (pitem && iIndex >= 0)
1469 {
1470
1471 pitem = pitem->get_item(e_tree_navigation_proper_forward, piLevel);
1472
1473 iIndex--;
1474
1475 }
1476
1477 if (iIndex < 0)
1478 {
1479
1480 return pitem;
1481
1482 }
1483
1484 return nullptr;
1485
1486 }
1487
1488
1489 template < prototype_item ITEM >
1490 ::collection::index tree_item < ITEM >::get_proper_item_index(tree_item * pitemParam, ::collection::index * piLevel)
1491 {
1492
1493 ::i32 iIndex = 0;
1494
1495 if (piLevel)
1496 {
1497
1498 *piLevel = 0;
1499
1500 }
1501
1502 tree_item * pitem = this;
1503
1504 while (pitem)
1505 {
1506
1507 pitem = pitem->get_item(e_tree_navigation_proper_forward, piLevel);
1508
1509 if (pitem == pitemParam)
1510 {
1511
1512 return iIndex;
1513
1514 }
1515
1516 iIndex++;
1517
1518 }
1519
1520 return -1;
1521
1522 }
1523
1524
1525 template < prototype_item ITEM >
1526 ::collection::count tree_item < ITEM >::get_proper_item_count()
1527 {
1528
1529 tree_item * pitem = this;
1530
1531 ::collection::index iLevel = 0;
1532
1533 ::collection::count iCount = -1;
1534
1535 while (pitem)
1536 {
1537
1538 pitem = pitem->get_item(e_tree_navigation_proper_forward, &iLevel);
1539
1540 iCount++;
1541
1542 if (iCount >= 65536)
1543 {
1544
1545 break;
1546
1547 }
1548
1549 if (iLevel <= 0)
1550 {
1551
1552 break;
1553
1554 }
1555
1556 }
1557
1558 return iCount;
1559
1560 }
1561
1562
1563 template < prototype_item ITEM >
1564 ::i32_boolean tree_item < ITEM >::is_expanded() const
1565 {
1566
1567 return m_etreeitemstate & ::data::e_tree_item_state_expanded;
1568
1569 }
1570
1571
1572 template < prototype_item ITEM >
1573 ::i32_boolean tree_item < ITEM >::is_expandable() const
1574 {
1575
1576 return m_etreeitemstate & ::data::e_tree_item_state_expandable;
1577
1578 }
1579
1580
1581 template < prototype_item ITEM >
1582 bool tree_item < ITEM >::is_descendant(tree_item * pitem)
1583 {
1584
1585 if (pitem == nullptr)
1586 {
1587
1588 return false;
1589
1590 }
1591
1592 return pitem->is_ascendant(this);
1593
1594 }
1595
1596
1597 template < prototype_item ITEM >
1598 bool tree_item < ITEM >::is_ascendant(tree_item * pitem)
1599 {
1600
1601 if (pitem == nullptr)
1602 {
1603
1604 return false;
1605
1606 }
1607
1608 tree_item * pparent = m_ptreeitemParent;
1609
1610 if (pparent == nullptr)
1611 {
1612
1613 return false;
1614
1615 }
1616
1617 while (pparent != nullptr)
1618 {
1619
1620 if (pparent == pitem)
1621 return true;
1622
1623 pparent = pparent->m_ptreeitemParent;
1624
1625 }
1626
1627 return false;
1628
1629 }
1630
1631
1632 template < prototype_item ITEM >
1633 void
1634 tree_item < ITEM >::on_fill_children()
1635 {
1636
1637 //if (m_pitem)
1638 //{
1639
1640 // m_pitem->data_item_on_fill_children(this);
1641
1642 //}
1643
1644 for (auto & p : *m_ptreeitema2)
1645 {
1646
1647 if (p->is_expanded())
1648 {
1649
1650 p->on_fill_children();
1651
1652 }
1653
1654 };
1655
1656 }
1657
1658
1659 template < prototype_item ITEM >
1660 ::item * tree_item < ITEM >::_item()
1661 {
1662
1663 return m_pitem;
1664
1665 }
1666
1667
1668 template < prototype_item ITEM >
1669 void tree_item < ITEM >::_set_item(::item * pitem)
1670 {
1671
1672 m_pitem = pitem;
1673
1674 }
1675
1676
1677 template < prototype_item ITEM >
1679 public pointer_array < tree_item < ITEM > >
1680 {
1681 public:
1682 };
1683
1684
1685} // namespace acme
1686
1687
Definition tree_base.h:20
Definition tree_item_base.h:18
Definition tree_item.h:1680
Definition tree_item.h:34
Definition tree.h:17
Definition boolean.h:7
Definition item.h:93
Definition pointer_array.h:1882