Permalink
Browse files

Support for custom input views, node selection, improved layout and a…

…nimation.

Defaults to support for hardware keyboard if no custom input view
specified. General bug fixes from layout testing in both directions.
Implemented node selection on touch based events.
  • Loading branch information...
epreston committed Sep 14, 2011
1 parent 1442f48 commit ecbcc7771cd6d233cd4c1496546ec9de7f2d8b73
@@ -53,9 +53,9 @@ - (void) viewDidLoad
// Specify a starting root class to inspect on launch.
[self setRootClassName:@"UIControl"];
+
}
-
// Override to allow orientations other than the default portrait orientation.
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
@@ -2,7 +2,7 @@
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">800</int>
- <string key="IBDocument.SystemVersion">11A511</string>
+ <string key="IBDocument.SystemVersion">11B26</string>
<string key="IBDocument.InterfaceBuilderVersion">1617</string>
<string key="IBDocument.AppKitVersion">1138</string>
<string key="IBDocument.HIToolboxVersion">566.00</string>
@@ -36,11 +36,10 @@
<object class="IBUIButton" id="246752469">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
- <string key="NSFrame">{{186, 7}, {37, 37}}</string>
+ <string key="NSFrame">{{191, 10}, {29, 31}}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
- <reference key="NSNextKeyView"/>
- <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUIContentMode">4</int>
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
@@ -49,7 +48,7 @@
<double key="NSSize">15</double>
<int key="NSfFlags">16</int>
</object>
- <int key="IBUIButtonType">1</int>
+ <bool key="IBUIShowsTouchWhenHighlighted">YES</bool>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="202185770">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
@@ -122,7 +121,6 @@
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="189980015"/>
<reference key="IBUIBackgroundColor" ref="202185770"/>
- <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
<int key="IBUIInterfaceOrientation">3</int>
<int key="interfaceOrientation">3</int>
@@ -131,6 +131,10 @@
- ( id <PSTreeGraphModelNode> ) modelNodeClosestToY:(CGFloat)y;
+/// Returns the visible model node that is closest to the specified x coordinate, where "x" is specified in the
+/// SubtreeView's interior (bounds) coordinate space.
+
+- ( id <PSTreeGraphModelNode> ) modelNodeClosestToX:(CGFloat)x;
#pragma mark - Debugging
@@ -63,18 +63,23 @@ - (void) setExpanded:(BOOL)flag
}
}
-- (IBAction) toggleExpansion:(id)sender
+- (IBAction) toggleExpansion:(id)sender
{
[UIView beginAnimations:@"TreeNodeExpansion" context:nil];
- // [UIView setAnimationDuration:0.5];
+// [UIView setAnimationDuration:8.0];
[UIView setAnimationBeginsFromCurrentState:YES];
- // [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
+ [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self setExpanded:![self isExpanded]];
[[self enclosingTreeGraph] layoutGraphIfNeeded];
-
- [UIView commitAnimations];
+
+ if ( [self modelNode] != nil ) {
+ NSSet *visibleSet = [NSSet setWithObject:[self modelNode]];
+ [[self enclosingTreeGraph] scrollModelNodesToVisible:visibleSet animated:NO];
+ }
+
+ [UIView commitAnimations];
}
- (BOOL) isLeaf
@@ -203,8 +208,6 @@ - (CGSize) layoutGraphIfNeeded
nextSubtreeViewOrigin = CGPointMake(0.0f, rootNodeViewSize.height + parentChildSpacing);
}
-
-
for (index = count - 1; index >= 0; index--) {
UIView *subview = [subviews objectAtIndex:index];
@@ -568,6 +571,32 @@ - (BOOL) nodeIsSelected
return [subtreeViewWithClosestNodeView modelNode];
}
+- (id <PSTreeGraphModelNode> ) modelNodeClosestToX:(CGFloat)x
+{
+ // Do a simple linear search of our subviews, ignoring non-SubtreeViews. If performance was ever
+ // an issue for this code, we could take advantage of knowing the layout order of the nodes to do
+ // a sort of binary search.
+
+ NSArray *subviews = [self subviews];
+ PSBaseSubtreeView *subtreeViewWithClosestNodeView = nil;
+ CGFloat closestNodeViewDistance = MAXFLOAT;
+
+ for (UIView *subview in subviews) {
+ if ([subview isKindOfClass:[PSBaseSubtreeView class]]) {
+ UIView *childNodeView = [(PSBaseSubtreeView *)subview nodeView];
+ if (childNodeView) {
+ CGRect rect = [self convertRect:[childNodeView bounds] fromView:childNodeView];
+ CGFloat nodeViewDistance = fabs(x - CGRectGetMidX(rect));
+ if (nodeViewDistance < closestNodeViewDistance) {
+ closestNodeViewDistance = nodeViewDistance;
+ subtreeViewWithClosestNodeView = (PSBaseSubtreeView *)subview;
+ }
+ }
+ }
+ }
+
+ return [subtreeViewWithClosestNodeView modelNode];
+}
#pragma mark - Debugging
@@ -44,7 +44,7 @@ typedef NSInteger PSTreeGraphOrientationStyle;
-@interface PSBaseTreeGraphView : UIView
+@interface PSBaseTreeGraphView : UIView <UIKeyInput>
{
@private
@@ -87,10 +87,14 @@ typedef NSInteger PSTreeGraphOrientationStyle;
CGFloat _connectingLineWidth;
PSTreeGraphConnectingLineStyle _connectingLineStyle;
+ // A debug feature that outlines the view hiarchy.
BOOL _showsSubtreeFrames;
// iOS 4 and above ONLY
// UINib *cachedNodeViewNib;
+
+ // Custom input view support
+ UIView *_inputView;
}
@@ -164,7 +168,7 @@ typedef NSInteger PSTreeGraphOrientationStyle;
@property (nonatomic, copy) NSSet *selectedModelNodes;
/// Convenience accessor that returns the selected node, if exactly one node is currently
-/// selected. Returns nil if zero, or more than one, nodees are currently selected.
+/// selected. Returns nil if zero, or more than one, nodes are currently selected.
@property (nonatomic, readonly) id <PSTreeGraphModelNode> singleSelectedModelNode;
@@ -244,11 +248,11 @@ typedef NSInteger PSTreeGraphOrientationStyle;
/// Does a [self scrollRectToVisible:] with the bounding box of the specified model nodes.
-- (void) scrollModelNodesToVisible:(NSSet *)modelNodes;
+- (void) scrollModelNodesToVisible:(NSSet *)modelNodes animated:(BOOL)animated;
/// Does a [self scrollRectToVisible:] with the bounding box of the selected model nodes.
-- (void) scrollSelectedModelNodesToVisible;
+- (void) scrollSelectedModelNodesToVisibleAnimated:(BOOL)animated;
#pragma mark - Animation Support
@@ -304,4 +308,35 @@ typedef NSInteger PSTreeGraphOrientationStyle;
@property (nonatomic, assign) BOOL showsSubtreeFrames;
+#pragma mark - Input and Navigation
+
+/// Custom input view for navigation.
+///
+/// By default, this control supports a hardware keyboard unless this property is assigned
+/// to another input view.
+///
+/// More Info:
+///
+/// A placeholder view is created to so the default keyboard is not presented to the user.
+/// When a hardware keyboard is attached, touching the TreeGraph makes it first responder
+/// and certain keyboard shortcuts become available for navigation. ie. the space bar
+/// expands and collapses the current selection. The following keys; w, a, s, d, navigate
+/// relative to the graph.
+///
+/// Custom navigation can be added by assigning a custom UIView to inputView, and linking
+/// it up to some of the actions below.
+
+@property (nonatomic, retain) IBOutlet UIView *inputView;
+
+// Model relative navigation
+- (void) moveToSiblingByRelativeIndex:(NSInteger)relativeIndex;
+- (IBAction) moveToParent:(id)sender;
+- (IBAction) moveToNearestChild:(id)sender;
+
+// Graph relative navigation
+- (IBAction) moveUp:(id)sender;
+- (IBAction) moveDown:(id)sender;
+- (IBAction) moveLeft:(id)sender;
+- (IBAction) moveRight:(id)sender;
+
@end
Oops, something went wrong.

0 comments on commit ecbcc77

Please sign in to comment.