Skip to content
This repository has been archived by the owner on Jun 25, 2021. It is now read-only.

Commit

Permalink
Add flipped layout
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Chad Koski committed Aug 20, 2012
1 parent 6fd2f55 commit cb6bcdd
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 23 deletions.
2 changes: 2 additions & 0 deletions Example 1/Classes/Controller/PSHTreeGraphViewController.m
Expand Up @@ -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_]];
}
Expand Down
23 changes: 18 additions & 5 deletions PSTreeGraphView/PSBaseBranchView.m
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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)];
Expand Down
3 changes: 3 additions & 0 deletions PSTreeGraphView/PSBaseSubtreeView.h
Expand Up @@ -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.)

Expand Down
50 changes: 43 additions & 7 deletions PSTreeGraphView/PSBaseSubtreeView.m
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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));

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions PSTreeGraphView/PSBaseTreeGraphView.h
Expand Up @@ -28,6 +28,8 @@ typedef enum PSTreeGraphConnectingLineStyle : NSUInteger {
typedef enum PSTreeGraphOrientationStyle : NSUInteger {
PSTreeGraphOrientationStyleHorizontal = 0,
PSTreeGraphOrientationStyleVertical = 1,
PSTreeGraphOrientationStyleHorizontalFlipped = 2,
PSTreeGraphOrientationStyleVerticalFlipped = 3,
} PSTreeGraphOrientationStyle;


Expand Down Expand Up @@ -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;
Expand Down
44 changes: 33 additions & 11 deletions PSTreeGraphView/PSBaseTreeGraphView.m
Expand Up @@ -56,6 +56,7 @@ @interface PSBaseTreeGraphView ()
// Layout Behavior
BOOL resizesToFillEnclosingScrollView_;
PSTreeGraphOrientationStyle treeGraphOrientation_;
BOOL treeGraphFlipped_;

// Styling
// UIColor *backgroundColor;
Expand All @@ -77,7 +78,7 @@ @interface PSBaseTreeGraphView ()
UIView *inputView_;
}

- (void) configureDetaults;
- (void) configureDefaults;
- (PSBaseSubtreeView *) newGraphForModelNode:(id <PSTreeGraphModelNode> )modelNode;
- (void) buildGraph;
- (void) updateFrameSizeForContentAndClipView;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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];
Expand All @@ -211,6 +222,7 @@ - (void) configureDetaults
siblingSpacing_ = 10.0;
animatesLayout_ = YES;
resizesToFillEnclosingScrollView_ = YES;
treeGraphFlipped_ = NO;
treeGraphOrientation_ = PSTreeGraphOrientationStyleHorizontal ;
connectingLineStyle_ = PSTreeGraphConnectingLineStyleOrthogonal ;
connectingLineWidth_ = 1.0;
Expand Down Expand Up @@ -254,7 +266,7 @@ - (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self configureDetaults];
[self configureDefaults];
}
return self;
}
Expand Down Expand Up @@ -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"];
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)];
Expand All @@ -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];
Expand All @@ -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];
Expand All @@ -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];
Expand All @@ -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];
Expand Down

0 comments on commit cb6bcdd

Please sign in to comment.