Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added flipped tree graph orientations #18

Merged
merged 1 commit into from

2 participants

@cekoski

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

Chad Koski 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
@epreston
Owner

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

@epreston
Owner

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

@epreston epreston merged commit 9be5bed into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 20, 2012
  1. Add flipped layout

    Chad Koski authored
    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
This page is out of date. Refresh to see the latest.
View
2  Example 1/Classes/Controller/PSHTreeGraphViewController.m
@@ -44,6 +44,8 @@ - (void) setRootClassName:(NSString *)newRootClassName
[rootClassName_ release];
rootClassName_ = [newRootClassName copy];
+ treeGraphView_.treeGraphOrientation = PSTreeGraphOrientationStyleHorizontalFlipped;
+
// Get an ObjCClassWrapper for the named Objective-C Class, and set it as the TreeGraph's root.
[treeGraphView_ setModelRoot:[ObjCClassWrapper wrapperForClassNamed:rootClassName_]];
}
View
23 PSTreeGraphView/PSBaseBranchView.m
@@ -50,7 +50,8 @@ - (UIBezierPath *) directConnectionsPath
PSTreeGraphOrientationStyle treeDirection = [[self enclosingTreeGraph] treeGraphOrientation];
- if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
rootPoint = CGPointMake(CGRectGetMinX(bounds),
CGRectGetMidY(bounds));
} else {
@@ -70,7 +71,8 @@ - (UIBezierPath *) directConnectionsPath
CGRect subviewBounds = [subview bounds];
CGPoint targetPoint = CGPointZero;
- if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
targetPoint = [self convertPoint:CGPointMake(CGRectGetMinX(subviewBounds), CGRectGetMidY(subviewBounds))
fromView:subview];
} else {
@@ -116,6 +118,14 @@ - (UIBezierPath *) orthogonalConnectionsPath
// Compute point at right edge of root node, from which its connecting line to the vertical line will emerge.
rootPoint = CGPointMake(CGRectGetMinX(bounds),
CGRectGetMidY(bounds));
+ } else if ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped ){
+ // Compute point at left edge of root node, from which its connecting line to the vertical line will emerge.
+ rootPoint = CGPointMake(CGRectGetMaxX(bounds),
+ CGRectGetMidY(bounds));
+ } else if ( treeDirection == PSTreeGraphOrientationStyleVerticalFlipped ){
+ // Compute point at top edge of root node, from which its connecting line to the vertical line will emerge.
+ rootPoint = CGPointMake(CGRectGetMidX(bounds),
+ CGRectGetMaxY(bounds));
} else {
rootPoint = CGPointMake(CGRectGetMidX(bounds),
CGRectGetMinY(bounds));
@@ -165,7 +175,8 @@ - (UIBezierPath *) orthogonalConnectionsPath
CGRect subviewBounds = [subview bounds];
CGPoint targetPoint = CGPointZero;
- if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
targetPoint = [self convertPoint:CGPointMake(CGRectGetMinX(subviewBounds), CGRectGetMidY(subviewBounds))
fromView:subview];
} else {
@@ -181,7 +192,8 @@ - (UIBezierPath *) orthogonalConnectionsPath
// TODO: Make clean line joins (test at high values of line thickness to see the problem).
- if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
[path moveToPoint:CGPointMake(rootIntersection.x, targetPoint.y)];
if (minY > targetPoint.y) {
@@ -212,7 +224,8 @@ - (UIBezierPath *) orthogonalConnectionsPath
[path moveToPoint:rootPoint];
[path addLineToPoint:rootIntersection];
- if ( treeDirection == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeDirection == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeDirection == PSTreeGraphOrientationStyleHorizontalFlipped )){
// Add a stroke for the vertical connecting line.
[path moveToPoint:CGPointMake(rootIntersection.x, minY)];
[path addLineToPoint:CGPointMake(rootIntersection.x, maxY)];
View
3  PSTreeGraphView/PSBaseSubtreeView.h
@@ -74,6 +74,9 @@
- (CGSize) layoutGraphIfNeeded;
+// Flip the treeGraph end for end (or top for bottom)
+- (void) flipTreeGraph;
+
/// Resizes this subtree's nodeView to the minimum size required to hold its content, and returns the nodeView's
/// new size. (This currently does nothing, and is just stubbed out for future use.)
View
50 PSTreeGraphView/PSBaseSubtreeView.m
@@ -197,6 +197,35 @@ - (CGSize) sizeNodeViewToFitContent
return [self.nodeView frame].size;
}
+- (void) flipTreeGraph
+{
+ // Recurse for descendant SubtreeViews.
+ CGFloat myWidth = self.frame.size.width;
+ CGFloat myHeight = self.frame.size.height;
+ PSBaseTreeGraphView *treeGraph = [self enclosingTreeGraph];
+ PSTreeGraphOrientationStyle treeOrientation = [treeGraph treeGraphOrientation];
+
+ NSArray *subviews = [self subviews];
+ for (UIView *subview in subviews) {
+ CGPoint subviewCenter = subview.center;
+ CGPoint newCenter;
+ CGFloat offset;
+ if (treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped ){
+ offset = subviewCenter.x;
+ newCenter = CGPointMake(myWidth-offset, subviewCenter.y);
+ }
+ else{
+ offset = subviewCenter.y;
+ newCenter = CGPointMake(subviewCenter.x, myHeight-offset);
+ }
+ subview.center = newCenter;
+ if ([subview isKindOfClass:[PSBaseSubtreeView class]]) {
+ [(PSBaseSubtreeView *)subview flipTreeGraph];
+ }
+ }
+}
+
+
- (CGSize) layoutGraphIfNeeded
{
// Return early if layout not needed
@@ -246,7 +275,8 @@ - (CGSize) layoutExpandedGraph
CGFloat maxHeight = 0.0f;
CGPoint nextSubtreeViewOrigin = CGPointZero;
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
nextSubtreeViewOrigin = CGPointMake(rootNodeViewSize.width + parentChildSpacing, 0.0f);
} else {
nextSubtreeViewOrigin = CGPointMake(0.0f, rootNodeViewSize.height + parentChildSpacing);
@@ -267,7 +297,8 @@ - (CGSize) layoutExpandedGraph
// Position the SubtreeView.
// [(animateLayout ? [subview animator] : subview) setFrameOrigin:nextSubtreeViewOrigin];
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ (treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )) {
// Since SubtreeView is unflipped, lay out our child SubtreeViews going upward from our
// bottom edge, from last to first.
subview.frame = CGRectMake( nextSubtreeViewOrigin.x,
@@ -308,7 +339,8 @@ - (CGSize) layoutExpandedGraph
CGFloat totalHeight = 0.0f;
CGFloat totalWidth = 0.0f;
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ (treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )) {
totalHeight = nextSubtreeViewOrigin.y;
if (subtreeViewCount > 0) {
totalHeight -= siblingSpacing;
@@ -325,7 +357,8 @@ - (CGSize) layoutExpandedGraph
if (subtreeViewCount > 0) {
// Determine our width and height.
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )) {
selfTargetSize = CGSizeMake(rootNodeViewSize.width + parentChildSpacing + maxWidth,
MAX(totalHeight, rootNodeViewSize.height) );
} else {
@@ -341,7 +374,8 @@ - (CGSize) layoutExpandedGraph
selfTargetSize.height );
CGPoint nodeViewOrigin = CGPointZero;
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
// Position our nodeView vertically centered along the left edge of our new bounds.
nodeViewOrigin = CGPointMake(0.0f, 0.5f * (selfTargetSize.height - rootNodeViewSize.height));
@@ -372,7 +406,8 @@ - (CGSize) layoutExpandedGraph
// [_connectorsView setContentMode:UIViewContentModeScaleToFill ];
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
connectorsView_.frame = CGRectMake(rootNodeViewSize.width,
0.0f,
parentChildSpacing,
@@ -444,7 +479,8 @@ - (CGSize) layoutCollapsedGraph
// [_connectorsView setContentMode:UIViewContentModeScaleToFill ];
PSTreeGraphOrientationStyle treeOrientation = [[self enclosingTreeGraph] treeGraphOrientation];
- if ( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( treeOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( treeOrientation == PSTreeGraphOrientationStyleHorizontal )){
connectorsView_.frame = CGRectMake(0.0f,
0.5f * selfTargetSize.height,
0.0f,
View
8 PSTreeGraphView/PSBaseTreeGraphView.h
@@ -28,6 +28,8 @@ typedef enum PSTreeGraphConnectingLineStyle : NSUInteger {
typedef enum PSTreeGraphOrientationStyle : NSUInteger {
PSTreeGraphOrientationStyleHorizontal = 0,
PSTreeGraphOrientationStyleVertical = 1,
+ PSTreeGraphOrientationStyleHorizontalFlipped = 2,
+ PSTreeGraphOrientationStyleVerticalFlipped = 3,
} PSTreeGraphOrientationStyle;
@@ -148,6 +150,12 @@ typedef enum PSTreeGraphOrientationStyle : NSUInteger {
@property (nonatomic, assign) PSTreeGraphOrientationStyle treeGraphOrientation;
+/// Is the TreeGraph flipped
+/// Flipped means the graph is drawn with the branches to the left or top and the root node
+/// to the right or bottom. Default is NO
+
+@property (nonatomic, assign) BOOL treeGraphFlipped;
+
/// Returns YES if the tree needs relayout.
- (BOOL) needsGraphLayout;
View
44 PSTreeGraphView/PSBaseTreeGraphView.m
@@ -56,6 +56,7 @@ @interface PSBaseTreeGraphView ()
// Layout Behavior
BOOL resizesToFillEnclosingScrollView_;
PSTreeGraphOrientationStyle treeGraphOrientation_;
+ BOOL treeGraphFlipped_;
// Styling
// UIColor *backgroundColor;
@@ -77,7 +78,7 @@ @interface PSBaseTreeGraphView ()
UIView *inputView_;
}
-- (void) configureDetaults;
+- (void) configureDefaults;
- (PSBaseSubtreeView *) newGraphForModelNode:(id <PSTreeGraphModelNode> )modelNode;
- (void) buildGraph;
- (void) updateFrameSizeForContentAndClipView;
@@ -153,6 +154,16 @@ - (void) setTreeGraphOrientation:(PSTreeGraphOrientationStyle)newTreeGraphOrient
}
}
+@synthesize treeGraphFlipped = treeGraphFlipped_;
+
+- (void) setTreeGraphFlipped:(BOOL)newTreeGraphFlipped
+{
+ if (treeGraphFlipped_ != newTreeGraphFlipped) {
+ treeGraphFlipped_ = newTreeGraphFlipped;
+ [[self rootSubtreeView] recursiveSetConnectorsViewsNeedDisplay];
+ }
+}
+
@synthesize connectingLineStyle = connectingLineStyle_;
- (void) setConnectingLineStyle:(PSTreeGraphConnectingLineStyle)newConnectingLineStyle
@@ -196,7 +207,7 @@ - (void) setShowsSubtreeFrames:(BOOL)newShowsSubtreeFrames
#pragma mark - Initialization
-- (void) configureDetaults
+- (void) configureDefaults
{
[self setBackgroundColor: [UIColor colorWithRed:0.55 green:0.76 blue:0.93 alpha:1.0]];
//[self setClipsToBounds:YES];
@@ -211,6 +222,7 @@ - (void) configureDetaults
siblingSpacing_ = 10.0;
animatesLayout_ = YES;
resizesToFillEnclosingScrollView_ = YES;
+ treeGraphFlipped_ = NO;
treeGraphOrientation_ = PSTreeGraphOrientationStyleHorizontal ;
connectingLineStyle_ = PSTreeGraphConnectingLineStyleOrthogonal ;
connectingLineWidth_ = 1.0;
@@ -254,7 +266,7 @@ - (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
- [self configureDetaults];
+ [self configureDefaults];
}
return self;
}
@@ -282,7 +294,7 @@ - (id) initWithCoder:(NSCoder *)decoder
self = [super initWithCoder:decoder];
if (self) {
- [self configureDetaults];
+ [self configureDefaults];
if ([decoder containsValueForKey:@"animatesLayout"])
animatesLayout_ = [decoder decodeBoolForKey:@"animatesLayout"];
@@ -558,7 +570,8 @@ - (void) updateRootSubtreeViewPositionForSize:(CGSize)rootSubtreeViewSize
if ( [self resizesToFillEnclosingScrollView] ) {
CGRect bounds = [self bounds];
- if ( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontalFlipped )){
newOrigin = CGPointMake([self contentMargin],
0.5 * (bounds.size.height - rootSubtreeViewSize.height));
} else {
@@ -617,7 +630,11 @@ - (CGSize) layoutGraphIfNeeded
// Position the TreeGraph's root SubtreeView.
[self updateRootSubtreeViewPositionForSize:rootSubtreeViewSize];
-
+
+ if (( [self treeGraphOrientation] == PSTreeGraphOrientationStyleHorizontalFlipped ) ||
+ ( [self treeGraphOrientation] == PSTreeGraphOrientationStyleVerticalFlipped )){
+ [rootSubtreeView flipTreeGraph];
+ }
return rootSubtreeViewSize;
} else {
return rootSubtreeView ? [rootSubtreeView frame].size : CGSizeZero;
@@ -831,7 +848,8 @@ - (IBAction) moveToNearestChild:(id)sender
if (nodeView) {
CGRect nodeViewFrame = [nodeView frame];
id <PSTreeGraphModelNode> nearestChild = nil;
- if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
nearestChild = [subtreeView modelNodeClosestToY:CGRectGetMidY(nodeViewFrame)];
} else {
nearestChild = [subtreeView modelNodeClosestToX:CGRectGetMidX(nodeViewFrame)];
@@ -852,7 +870,8 @@ - (IBAction) moveToNearestChild:(id)sender
- (void) moveUp:(id)sender
{
- if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
[self moveToSiblingByRelativeIndex:1];
} else {
[self moveToParent:sender];
@@ -862,7 +881,8 @@ - (void) moveUp:(id)sender
- (void) moveDown:(id)sender
{
- if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
[self moveToSiblingByRelativeIndex:-1];
} else {
[self moveToNearestChild:sender];
@@ -872,7 +892,8 @@ - (void) moveDown:(id)sender
- (void) moveLeft:(id)sender
{
- if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
[self moveToParent:sender];
} else {
[self moveToSiblingByRelativeIndex:1];
@@ -882,7 +903,8 @@ - (void) moveLeft:(id)sender
- (void) moveRight:(id)sender
{
- if ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) {
+ if (( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontal ) ||
+ ( self.treeGraphOrientation == PSTreeGraphOrientationStyleHorizontalFlipped )){
[self moveToNearestChild:sender];
} else {
[self moveToSiblingByRelativeIndex:-1];
Something went wrong with that request. Please try again.