Skip to content
This repository

Added flipped tree graph orientations #18

Merged
merged 1 commit into from over 1 year ago

2 participants

Chad Koski Ed Preston
Chad Koski

Added two new PSTreeGraphOrientations:
PSTreeGraphOrientationHizontalFlipped and
PSTreeGraphOrientationVerticalFlipped. These orientations draw the
root node of the graph on right or bottom respectively. This layout is
useful for trees representing elimination tournaments.

Also fixes a typo in the name of the configureDefaults method of
PSBaseTreeGraphView

Add flipped layout
Added two new PSTreeGraphOrientations:
PSTreeGraphOrientationHizontalFlipped and
PSTreeGraphOrientationVerticalFlipped.  These orientations draw the
root node of the graph on right or bottom respectively.  This layout is
useful for trees representing elimination tournaments.

Also fixes a typo in the name of the configureDefaults method of
PSBaseTreeGraphView
cb6bcdd
Ed Preston
Owner

Brilliant contribution! I am looking and testing through it now.

Ed Preston
Owner

So let it be written, so let it be merged.

Ed Preston epreston merged commit 9be5bed into from August 20, 2012
Ed Preston epreston closed this August 20, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Aug 19, 2012
Add flipped layout
Added two new PSTreeGraphOrientations:
PSTreeGraphOrientationHizontalFlipped and
PSTreeGraphOrientationVerticalFlipped.  These orientations draw the
root node of the graph on right or bottom respectively.  This layout is
useful for trees representing elimination tournaments.

Also fixes a typo in the name of the configureDefaults method of
PSBaseTreeGraphView
cb6bcdd
This page is out of date. Refresh to see the latest.
2  Example 1/Classes/Controller/PSHTreeGraphViewController.m
@@ -44,6 +44,8 @@ - (void) setRootClassName:(NSString *)newRootClassName
44 44
         [rootClassName_ release];
45 45
         rootClassName_ = [newRootClassName copy];
46 46
 
  47
+        treeGraphView_.treeGraphOrientation  = PSTreeGraphOrientationStyleHorizontalFlipped;
  48
+
47 49
         // Get an ObjCClassWrapper for the named Objective-C Class, and set it as the TreeGraph's root.
48 50
         [treeGraphView_ setModelRoot:[ObjCClassWrapper wrapperForClassNamed:rootClassName_]];
49 51
     }
23  PSTreeGraphView/PSBaseBranchView.m
@@ -50,7 +50,8 @@ - (UIBezierPath *) directConnectionsPath
50 50
 
51 51
 	PSTreeGraphOrientationStyle treeDirection = [[self enclosingTreeGraph] treeGraphOrientation];
52 52
 
53  
-	if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
  53
+	if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
  54
+        ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
54 55
 		rootPoint = CGPointMake(CGRectGetMinX(bounds),
55 56
                                 CGRectGetMidY(bounds));
56 57
 	} else {
@@ -70,7 +71,8 @@ - (UIBezierPath *) directConnectionsPath
70 71
                 CGRect subviewBounds = [subview bounds];
71 72
 				CGPoint targetPoint = CGPointZero;
72 73
 
73  
-				if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
  74
+                if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
  75
+                    ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
74 76
 					targetPoint = [self convertPoint:CGPointMake(CGRectGetMinX(subviewBounds), CGRectGetMidY(subviewBounds))
75 77
                                             fromView:subview];
76 78
 				} else {
@@ -116,6 +118,14 @@ - (UIBezierPath *) orthogonalConnectionsPath
116 118
 		// Compute point at right edge of root node, from which its connecting line to the vertical line will emerge.
117 119
 		rootPoint = CGPointMake(CGRectGetMinX(bounds),
118 120
                                 CGRectGetMidY(bounds));
  121
+	} else if ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped ){
  122
+		// Compute point at left edge of root node, from which its connecting line to the vertical line will emerge.
  123
+		rootPoint = CGPointMake(CGRectGetMaxX(bounds),
  124
+                                CGRectGetMidY(bounds));
  125
+	} else if ( treeDirection == PSTreeGraphOrientationStyleVerticalFlipped ){
  126
+		// Compute point at top edge of root node, from which its connecting line to the vertical line will emerge.
  127
+		rootPoint = CGPointMake(CGRectGetMidX(bounds),
  128
+                                CGRectGetMaxY(bounds));
119 129
 	} else {
120 130
 		rootPoint = CGPointMake(CGRectGetMidX(bounds),
121 131
                                 CGRectGetMinY(bounds));
@@ -165,7 +175,8 @@ - (UIBezierPath *) orthogonalConnectionsPath
165 175
                 CGRect subviewBounds = [subview bounds];
166 176
 				CGPoint targetPoint = CGPointZero;
167 177
 
168  
-				if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
  178
+                if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
  179
+                    ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
169 180
 					targetPoint = [self convertPoint:CGPointMake(CGRectGetMinX(subviewBounds), CGRectGetMidY(subviewBounds))
170 181
                                             fromView:subview];
171 182
 				} else {
@@ -181,7 +192,8 @@ - (UIBezierPath *) orthogonalConnectionsPath
181 192
 
182 193
                 // TODO: Make clean line joins (test at high values of line thickness to see the problem).
183 194
 
184  
-				if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
  195
+                if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
  196
+                    ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
185 197
 					[path moveToPoint:CGPointMake(rootIntersection.x, targetPoint.y)];
186 198
 
187 199
 					if (minY > targetPoint.y) {
@@ -212,7 +224,8 @@ - (UIBezierPath *) orthogonalConnectionsPath
212 224
         [path moveToPoint:rootPoint];
213 225
         [path addLineToPoint:rootIntersection];
214 226
 
215  
-		if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
  227
+        if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
  228
+            ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
216 229
 			// Add a stroke for the vertical connecting line.
217 230
 			[path moveToPoint:CGPointMake(rootIntersection.x, minY)];
218 231
 			[path addLineToPoint:CGPointMake(rootIntersection.x, maxY)];
3  PSTreeGraphView/PSBaseSubtreeView.h
@@ -74,6 +74,9 @@
74 74
 
75 75
 - (CGSize) layoutGraphIfNeeded;
76 76
 
  77
+// Flip the treeGraph end for end (or top for bottom)
  78
+- (void) flipTreeGraph;
  79
+
77 80
 /// Resizes this subtree's nodeView to the minimum size required to hold its content, and returns the nodeView's
78 81
 /// new size.  (This currently does nothing, and is just stubbed out for future use.)
79 82
 
50  PSTreeGraphView/PSBaseSubtreeView.m
@@ -197,6 +197,35 @@ - (CGSize) sizeNodeViewToFitContent
197 197
     return [self.nodeView frame].size;
198 198
 }
199 199
 
  200
+- (void) flipTreeGraph
  201
+{
  202
+    // Recurse for descendant SubtreeViews.
  203
+    CGFloat             myWidth             = self.frame.size.width;
  204
+    CGFloat             myHeight             = self.frame.size.height;
  205
+    PSBaseTreeGraphView *treeGraph = [self enclosingTreeGraph];
  206
+	PSTreeGraphOrientationStyle treeOrientation = [treeGraph treeGraphOrientation];
  207
+
  208
+    NSArray *subviews = [self subviews];
  209
+    for (UIView *subview in subviews) {
  210
+        CGPoint             subviewCenter       = subview.center;
  211
+        CGPoint             newCenter;
  212
+        CGFloat             offset;
  213
+        if (treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped ){
  214
+            offset      = subviewCenter.x;
  215
+            newCenter   = CGPointMake(myWidth-offset, subviewCenter.y);
  216
+        }
  217
+        else{
  218
+            offset      = subviewCenter.y;
  219
+            newCenter   = CGPointMake(subviewCenter.x, myHeight-offset);
  220
+        }
  221
+        subview.center                          = newCenter;
  222
+        if ([subview isKindOfClass:[PSBaseSubtreeView class]]) {
  223
+            [(PSBaseSubtreeView *)subview flipTreeGraph];
  224
+        }
  225
+    }
  226
+}
  227
+
  228
+
200 229
 - (CGSize) layoutGraphIfNeeded
201 230
 {
202 231
     // Return early if layout not needed
@@ -246,7 +275,8 @@ - (CGSize) layoutExpandedGraph
246 275
     CGFloat maxHeight = 0.0f;
247 276
     CGPoint nextSubtreeViewOrigin = CGPointZero;
248 277
 
249  
-    if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  278
+    if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  279
+        ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
250 280
         nextSubtreeViewOrigin = CGPointMake(rootNodeViewSize.width + parentChildSpacing, 0.0f);
251 281
     } else {
252 282
         nextSubtreeViewOrigin = CGPointMake(0.0f, rootNodeViewSize.height + parentChildSpacing);
@@ -267,7 +297,8 @@ - (CGSize) layoutExpandedGraph
267 297
             // Position the SubtreeView.
268 298
             // [(animateLayout ? [subview animator] : subview) setFrameOrigin:nextSubtreeViewOrigin];
269 299
 
270  
-            if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  300
+            if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) || 
  301
+                (treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )) {
271 302
                 // Since SubtreeView is unflipped, lay out our child SubtreeViews going upward from our
272 303
                 // bottom edge, from last to first.
273 304
                 subview.frame = CGRectMake( nextSubtreeViewOrigin.x,
@@ -308,7 +339,8 @@ - (CGSize) layoutExpandedGraph
308 339
     CGFloat totalHeight = 0.0f;
309 340
     CGFloat totalWidth = 0.0f;
310 341
 
311  
-    if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  342
+    if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) || 
  343
+        (treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )) {
312 344
         totalHeight = nextSubtreeViewOrigin.y;
313 345
         if (subtreeViewCount > 0) {
314 346
             totalHeight -= siblingSpacing;
@@ -325,7 +357,8 @@ - (CGSize) layoutExpandedGraph
325 357
     if (subtreeViewCount > 0) {
326 358
 
327 359
         // Determine our width and height.
328  
-        if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  360
+        if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) || 
  361
+            ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )) {
329 362
             selfTargetSize = CGSizeMake(rootNodeViewSize.width + parentChildSpacing + maxWidth,
330 363
                                         MAX(totalHeight, rootNodeViewSize.height) );
331 364
         } else {
@@ -341,7 +374,8 @@ - (CGSize) layoutExpandedGraph
341 374
                                 selfTargetSize.height );
342 375
 
343 376
         CGPoint nodeViewOrigin = CGPointZero;
344  
-        if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  377
+        if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  378
+            ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
345 379
             // Position our nodeView vertically centered along the left edge of our new bounds.
346 380
             nodeViewOrigin = CGPointMake(0.0f, 0.5f * (selfTargetSize.height - rootNodeViewSize.height));
347 381
 
@@ -372,7 +406,8 @@ - (CGSize) layoutExpandedGraph
372 406
 
373 407
         // [_connectorsView setContentMode:UIViewContentModeScaleToFill ];
374 408
 
375  
-        if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  409
+        if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  410
+            ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
376 411
             connectorsView_.frame = CGRectMake(rootNodeViewSize.width,
377 412
                                                0.0f,
378 413
                                                parentChildSpacing,
@@ -444,7 +479,8 @@ - (CGSize) layoutCollapsedGraph
444 479
             // [_connectorsView setContentMode:UIViewContentModeScaleToFill ];
445 480
 
446 481
             PSTreeGraphOrientationStyle treeOrientation = [[self enclosingTreeGraph] treeGraphOrientation];
447  
-            if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  482
+            if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) || 
  483
+                ( treeOrientation == PSTreeGraphOrientationStyleHorizontal )){
448 484
                 connectorsView_.frame = CGRectMake(0.0f,
449 485
                                                    0.5f * selfTargetSize.height,
450 486
                                                    0.0f,
8  PSTreeGraphView/PSBaseTreeGraphView.h
@@ -28,6 +28,8 @@ typedef enum PSTreeGraphConnectingLineStyle : NSUInteger {
28 28
 typedef enum PSTreeGraphOrientationStyle : NSUInteger {
29 29
     PSTreeGraphOrientationStyleHorizontal = 0,
30 30
     PSTreeGraphOrientationStyleVertical = 1,
  31
+    PSTreeGraphOrientationStyleHorizontalFlipped = 2,
  32
+    PSTreeGraphOrientationStyleVerticalFlipped = 3,
31 33
 } PSTreeGraphOrientationStyle;
32 34
 
33 35
 
@@ -148,6 +150,12 @@ typedef enum PSTreeGraphOrientationStyle : NSUInteger {
148 150
 
149 151
 @property (nonatomic, assign) PSTreeGraphOrientationStyle treeGraphOrientation;
150 152
 
  153
+/// Is the TreeGraph flipped 
  154
+/// Flipped means the graph is drawn with the branches to the left or top and the root node
  155
+/// to the right or bottom.  Default is NO
  156
+
  157
+@property (nonatomic, assign) BOOL treeGraphFlipped;
  158
+
151 159
 /// Returns YES if the tree needs relayout.
152 160
 
153 161
 - (BOOL) needsGraphLayout;
44  PSTreeGraphView/PSBaseTreeGraphView.m
@@ -56,6 +56,7 @@ @interface PSBaseTreeGraphView ()
56 56
     // Layout Behavior
57 57
     BOOL resizesToFillEnclosingScrollView_;
58 58
 	PSTreeGraphOrientationStyle treeGraphOrientation_;
  59
+    BOOL treeGraphFlipped_;
59 60
     
60 61
     // Styling
61 62
     // UIColor *backgroundColor;
@@ -77,7 +78,7 @@ @interface PSBaseTreeGraphView ()
77 78
     UIView *inputView_;
78 79
 }
79 80
 
80  
-- (void) configureDetaults;
  81
+- (void) configureDefaults;
81 82
 - (PSBaseSubtreeView *) newGraphForModelNode:(id <PSTreeGraphModelNode> )modelNode;
82 83
 - (void) buildGraph;
83 84
 - (void) updateFrameSizeForContentAndClipView;
@@ -153,6 +154,16 @@ - (void) setTreeGraphOrientation:(PSTreeGraphOrientationStyle)newTreeGraphOrient
153 154
     }
154 155
 }
155 156
 
  157
+@synthesize treeGraphFlipped = treeGraphFlipped_;
  158
+
  159
+- (void) setTreeGraphFlipped:(BOOL)newTreeGraphFlipped
  160
+{
  161
+    if (treeGraphFlipped_ != newTreeGraphFlipped) {
  162
+        treeGraphFlipped_ = newTreeGraphFlipped;
  163
+        [[self rootSubtreeView] recursiveSetConnectorsViewsNeedDisplay];
  164
+    }
  165
+}
  166
+
156 167
 @synthesize connectingLineStyle = connectingLineStyle_;
157 168
 
158 169
 - (void) setConnectingLineStyle:(PSTreeGraphConnectingLineStyle)newConnectingLineStyle
@@ -196,7 +207,7 @@ - (void) setShowsSubtreeFrames:(BOOL)newShowsSubtreeFrames
196 207
 
197 208
 #pragma mark - Initialization
198 209
 
199  
-- (void) configureDetaults
  210
+- (void) configureDefaults
200 211
 {
201 212
 	[self setBackgroundColor: [UIColor colorWithRed:0.55 green:0.76 blue:0.93 alpha:1.0]];
202 213
 	//[self setClipsToBounds:YES];
@@ -211,6 +222,7 @@ - (void) configureDetaults
211 222
 	siblingSpacing_ = 10.0;
212 223
 	animatesLayout_ = YES;
213 224
 	resizesToFillEnclosingScrollView_ = YES;
  225
+	treeGraphFlipped_ = NO;
214 226
 	treeGraphOrientation_ = PSTreeGraphOrientationStyleHorizontal ;
215 227
 	connectingLineStyle_ = PSTreeGraphConnectingLineStyleOrthogonal ;
216 228
 	connectingLineWidth_ = 1.0;
@@ -254,7 +266,7 @@ - (id) initWithFrame:(CGRect)frame
254 266
 {
255 267
     self = [super initWithFrame:frame];
256 268
     if (self) {
257  
-        [self configureDetaults];
  269
+        [self configureDefaults];
258 270
     }
259 271
     return self;
260 272
 }
@@ -282,7 +294,7 @@ - (id) initWithCoder:(NSCoder *)decoder
282 294
     self = [super initWithCoder:decoder];
283 295
     if (self) {
284 296
 
285  
-        [self configureDetaults];
  297
+        [self configureDefaults];
286 298
 
287 299
         if ([decoder containsValueForKey:@"animatesLayout"])
288 300
             animatesLayout_ = [decoder decodeBoolForKey:@"animatesLayout"];
@@ -558,7 +570,8 @@ - (void) updateRootSubtreeViewPositionForSize:(CGSize)rootSubtreeViewSize
558 570
     if ( [self resizesToFillEnclosingScrollView] ) {
559 571
         CGRect bounds = [self bounds];
560 572
 
561  
-		if ( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontal ) {
  573
+		if (( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontal ) ||
  574
+            ( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontalFlipped )){
562 575
 			newOrigin = CGPointMake([self contentMargin],
563 576
                                     0.5 * (bounds.size.height - rootSubtreeViewSize.height));
564 577
 		} else {
@@ -617,7 +630,11 @@ - (CGSize) layoutGraphIfNeeded
617 630
 
618 631
         // Position the TreeGraph's root SubtreeView.
619 632
         [self updateRootSubtreeViewPositionForSize:rootSubtreeViewSize];
620  
-
  633
+        
  634
+		if (( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontalFlipped ) ||
  635
+            ( [self treeGraphOrientation] == PSTreeGraphOrientationStyleVerticalFlipped )){
  636
+            [rootSubtreeView flipTreeGraph];
  637
+        }
621 638
         return rootSubtreeViewSize;
622 639
     } else {
623 640
         return rootSubtreeView ? [rootSubtreeView frame].size : CGSizeZero;
@@ -831,7 +848,8 @@ - (IBAction) moveToNearestChild:(id)sender
831 848
             if (nodeView) {
832 849
                 CGRect nodeViewFrame = [nodeView frame];
833 850
                 id <PSTreeGraphModelNode> nearestChild = nil;
834  
-                if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  851
+                if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  852
+                    ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
835 853
                     nearestChild = [subtreeView modelNodeClosestToY:CGRectGetMidY(nodeViewFrame)];
836 854
                 } else {
837 855
                     nearestChild = [subtreeView modelNodeClosestToX:CGRectGetMidX(nodeViewFrame)];
@@ -852,7 +870,8 @@ - (IBAction) moveToNearestChild:(id)sender
852 870
 
853 871
 - (void) moveUp:(id)sender
854 872
 {
855  
-    if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  873
+    if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  874
+        ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
856 875
         [self moveToSiblingByRelativeIndex:1];
857 876
     } else {
858 877
         [self moveToParent:sender];
@@ -862,7 +881,8 @@ - (void) moveUp:(id)sender
862 881
 
863 882
 - (void) moveDown:(id)sender
864 883
 {
865  
-    if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  884
+    if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  885
+        ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
866 886
         [self moveToSiblingByRelativeIndex:-1];
867 887
     } else {
868 888
         [self moveToNearestChild:sender];
@@ -872,7 +892,8 @@ - (void) moveDown:(id)sender
872 892
 
873 893
 - (void) moveLeft:(id)sender
874 894
 {
875  
-    if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  895
+    if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  896
+        ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
876 897
         [self moveToParent:sender];
877 898
     } else {
878 899
         [self moveToSiblingByRelativeIndex:1];
@@ -882,7 +903,8 @@ - (void) moveLeft:(id)sender
882 903
 
883 904
 - (void) moveRight:(id)sender
884 905
 {
885  
-    if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
  906
+    if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
  907
+        ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
886 908
         [self moveToNearestChild:sender];
887 909
     } else {
888 910
         [self moveToSiblingByRelativeIndex:-1];
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.