RATreeNode.m 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //The MIT License (MIT)
  2. //
  3. //Copyright (c) 2013 Rafał Augustyniak
  4. //
  5. //Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. //this software and associated documentation files (the "Software"), to deal in
  7. //the Software without restriction, including without limitation the rights to
  8. //use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. //the Software, and to permit persons to whom the Software is furnished to do so,
  10. //subject to the following conditions:
  11. //
  12. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. //FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. //COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. //IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. //CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. //
  19. #import "RATreeNode.h"
  20. #import "RATreeNodeInfo.h"
  21. #import "RATreeNodeInfo+Private.h"
  22. typedef enum RATreeDepthLevel {
  23. RATreeDepthLevelNotInitialized
  24. } RATreeDepthLevel;
  25. @interface RATreeNode ()
  26. @property (nonatomic, getter = isExpanded, readwrite) BOOL expanded;
  27. @property (nonatomic) NSInteger treeDepthLevel;
  28. @property (strong, nonatomic, readwrite) id item;
  29. @property (strong, nonatomic, readwrite) NSArray *descendants;
  30. @property (strong, nonatomic, readwrite) RATreeNodeInfo *treeNodeInfo;
  31. @end
  32. @implementation RATreeNode
  33. - (id)initWithItem:(id)item parent:(RATreeNode *)parent expanded:(BOOL)expanded
  34. {
  35. self = [super init];
  36. if (self) {
  37. self.treeDepthLevel = RATreeDepthLevelNotInitialized;
  38. self.item = item;
  39. self.parent = parent;
  40. self.expanded = expanded;
  41. self.children = [NSArray array];
  42. }
  43. return self;
  44. }
  45. #pragma mark Public methods
  46. - (BOOL)isVisible
  47. {
  48. return self.parent.expanded || self.parent == nil;
  49. }
  50. - (void)addChildNode:(RATreeNode *)child
  51. {
  52. NSMutableArray *children = [self.children mutableCopy];
  53. [children addObject:child];
  54. self.children = [NSArray arrayWithArray:children];
  55. }
  56. - (NSInteger)numberOfVisibleDescendants
  57. {
  58. return [[self visibleDescendants] count];
  59. }
  60. - (NSArray *)visibleDescendants
  61. {
  62. if (self.expanded) {
  63. NSMutableArray *visibleDescendants = [NSMutableArray array];
  64. for (RATreeNode *treeNode in self.children) {
  65. [visibleDescendants addObject:treeNode];
  66. if (treeNode.expanded) {
  67. [visibleDescendants addObjectsFromArray:[treeNode visibleDescendants]];
  68. }
  69. }
  70. return visibleDescendants;
  71. } else {
  72. return nil;
  73. }
  74. }
  75. - (void)expand
  76. {
  77. self.expanded = YES;
  78. [self.parent expand];
  79. }
  80. - (void)collapse
  81. {
  82. self.expanded = NO;
  83. for (RATreeNode *treeNode in self.children) {
  84. [treeNode collapse];
  85. }
  86. }
  87. - (NSInteger)startIndex
  88. {
  89. NSInteger startIndex;
  90. if (self.parent.parent == nil) {
  91. startIndex = 0;
  92. } else {
  93. startIndex = [self.parent startIndex] + 1;
  94. }
  95. for (RATreeNode *treeNode in self.parent.children) {
  96. if (treeNode != self) {
  97. startIndex += 1;
  98. if (treeNode.expanded) {
  99. startIndex += [treeNode numberOfVisibleDescendants];
  100. }
  101. } else {
  102. break;
  103. }
  104. }
  105. return startIndex;
  106. }
  107. - (NSInteger)endIndex
  108. {
  109. NSInteger startIndex = [self startIndex];
  110. return startIndex + [self numberOfVisibleDescendants];
  111. }
  112. #pragma mark Properties
  113. - (RATreeNodeInfo *)treeNodeInfo
  114. {
  115. if (_treeNodeInfo == nil) {
  116. RATreeNodeInfo *treeNodeInfo = [[RATreeNodeInfo alloc] initWithParent:self.parent
  117. children:self.children];
  118. treeNodeInfo.treeDepthLevel = [self treeDepthLevel];
  119. treeNodeInfo.siblingsNumber = [self.parent.children count];
  120. treeNodeInfo.positionInSiblings = [self.parent.children indexOfObject:self];
  121. _treeNodeInfo = treeNodeInfo;
  122. }
  123. _treeNodeInfo.item = self.item;
  124. _treeNodeInfo.expanded = self.expanded;
  125. return _treeNodeInfo;
  126. }
  127. - (NSArray *)descendants
  128. {
  129. if (_descendants == nil) {
  130. NSMutableArray *descendants = [NSMutableArray array];
  131. for (RATreeNode *treeNode in self.children) {
  132. [descendants addObject:treeNode];
  133. [descendants addObjectsFromArray:[treeNode descendants]];
  134. }
  135. _descendants = descendants;
  136. }
  137. return _descendants;
  138. }
  139. #pragma mark Private Helpers
  140. - (NSInteger)treeDepthLevel
  141. {
  142. if (_treeDepthLevel == RATreeDepthLevelNotInitialized) {
  143. NSInteger treeDepthLevel = 0;
  144. RATreeNode *current = self.parent.parent;
  145. while (current != nil) {
  146. treeDepthLevel++;
  147. current = current.parent;
  148. }
  149. _treeDepthLevel = treeDepthLevel;
  150. }
  151. return _treeDepthLevel;
  152. }
  153. @end