Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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
  • Loading branch information...
commit cb6bcdde24fa16fa0827020f9072a32048b0bb94 1 parent 6fd2f55
Chad Koski authored
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];
Please sign in to comment.
Something went wrong with that request. Please try again.