PageRenderTime 32ms CodeModel.GetById 16ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 0ms

/PSTreeGraphView/PSBaseTreeGraphView.h

https://code.google.com/
C++ Header | 333 lines | 91 code | 126 blank | 116 comment | 0 complexity | 500726416cfbc901a2d57d8b581c55ac MD5 | raw file
  1//
  2//  PSBaseTreeGraphView.h
  3//  PSTreeGraphView
  4//
  5//  Created by Ed Preston on 7/25/10.
  6//  Copyright 2010 Preston Software. All rights reserved.
  7//
  8//
  9//  This is a port of the sample code from Max OS X to iOS (iPad).
 10//
 11//  WWDC 2010 Session 141, “Crafting Custom Cocoa Views�
 12//
 13
 14
 15#import <UIKit/UIKit.h>
 16#import <CoreGraphics/CoreGraphics.h>
 17
 18
 19
 20// A TreeGraph's nodes may be connected by either "direct" or "orthogonal" lines.
 21 
 22typedef enum {
 23    PSTreeGraphConnectingLineStyleDirect = 0,
 24    PSTreeGraphConnectingLineStyleOrthogonal = 1,
 25} PSTreeGraphConnectingLineStyle;
 26
 27
 28// A TreeGraph's orientation may be either "horizontal" or "vertical".
 29
 30typedef enum {
 31    PSTreeGraphOrientationStyleHorizontal = 0,
 32    PSTreeGraphOrientationStyleVertical = 1,
 33} PSTreeGraphOrientationStyle;
 34
 35
 36@class PSBaseSubtreeView;
 37
 38
 39@protocol PSTreeGraphModelNode;
 40@protocol PSTreeGraphDelegate;
 41
 42
 43
 44@interface PSBaseTreeGraphView : UIView <UIKeyInput>
 45{
 46    
 47@private
 48	// Model
 49    id <PSTreeGraphModelNode> _modelRoot;
 50	
 51	// Delegate
 52	id <PSTreeGraphDelegate> _delegate;
 53	
 54    // Model Object -> SubtreeView Mapping
 55	NSMutableDictionary *_modelNodeToSubtreeViewMapTable;
 56	
 57    // Node View Nib Specification
 58    NSString *_nodeViewNibName;
 59    NSBundle *_nodeViewNibBundle;
 60	
 61    // Selection State
 62    NSSet *_selectedModelNodes;
 63	
 64    // Layout State
 65    CGSize _minimumFrameSize;
 66	
 67    // Animation Support
 68    BOOL _animatesLayout;
 69    BOOL _layoutAnimationSuppressed;
 70	
 71    // Layout Metrics
 72    CGFloat _contentMargin;
 73    CGFloat _parentChildSpacing;
 74    CGFloat _siblingSpacing;
 75	
 76    // Layout Behavior
 77    BOOL _resizesToFillEnclosingScrollView;
 78	PSTreeGraphOrientationStyle _treeGraphOrientation;
 79	
 80    // Styling
 81    // UIColor *backgroundColor;
 82	
 83    UIColor *_connectingLineColor;
 84    CGFloat _connectingLineWidth;
 85    PSTreeGraphConnectingLineStyle _connectingLineStyle;
 86	
 87    // A debug feature that outlines the view hiarchy.
 88    BOOL _showsSubtreeFrames;
 89	
 90	// iOS 4 and above ONLY
 91    UINib *_cachedNodeViewNib;
 92    
 93    // Custom input view support
 94    UIView *_inputView;
 95}
 96
 97
 98#pragma mark - Delegate
 99
100@property (nonatomic, assign) id delegate;
101
102
103#pragma mark - Parent Resize Notification
104
105/// Use this method to keep the view in sync for now.
106
107- (void) parentClipViewDidResize:(id)object;
108
109
110#pragma mark - Creating Instances
111
112/// Initializes a new TreeGraph instance.  (TreeGraph's designated initializer is the same as 
113/// UIView's: -initWithFrame:.)  The TreeGraph has default appearance properties and layout 
114/// metrics, but to have a usable TreeGraph with actual content, you need to specify a 
115/// nodeViewNibName, an optional nodeViewNibBundle, and a modelRoot.
116 
117- (id) initWithFrame:(CGRect)frame;
118
119
120#pragma mark - Connection to Model
121
122/// The root of the model node tree that the TreeGraph is being asked to display.  (The modelRoot
123/// may have ancestor nodes, but TreeGraph will ignore them and treat modelRoot as the root.)  May
124/// be set to nil, in which case the TreeGraph displays no content.  The modelRoot object, and all
125/// of its desdendants as exposed through recursive application of the "-childModelNodes" accessor
126/// to traverse the model tree, must conform to the TreeGraphModelNode protocol declared in 
127/// TreeGraphModelNode.h
128 
129@property (nonatomic, retain) id <PSTreeGraphModelNode> modelRoot;
130
131
132#pragma mark - Root SubtreeView Access
133
134/// A TreeGraph builds the tree it displays using recursively nested SubtreeView instances.  This
135/// read-only accessor provides a way to get the rootmost SubtreeView (the one that corresponds 
136/// to the modelRoot model node).
137 
138@property (nonatomic, readonly) PSBaseSubtreeView *rootSubtreeView;
139
140
141#pragma mark - Node View Nib Specification
142
143/// The name of the .nib file from which to instantiate node views.  (This API design assumes that
144/// all node views should be instantiated from the same .nib.  If a tree of heterogeneous nodes 
145/// was desired, we could switch to a different mechanism for identifying the .nib to instantiate.)
146/// Must specify a "View" .nib file, whose File's Owner is a SubtreeView, or the TreeGraph will be
147/// unable to instantiate node views.
148 
149@property (nonatomic, copy) NSString *nodeViewNibName;
150
151
152#pragma mark - Selection State
153
154/// The unordered set of model nodes that are currently selected in the TreeGraph.  When no nodes
155/// are selected, this is an empty NSSet.  It will never be nil (and attempting to set it to nil
156/// will raise an exception).  Every member of this set must be a descendant of the TreeGraph's 
157/// modelRoot (or modelRoot itself).  If any member is not, TreeGraph will raise an exception.
158 
159@property (nonatomic, copy) NSSet *selectedModelNodes;
160
161/// Convenience accessor that returns the selected node, if exactly one node is currently 
162/// selected.  Returns nil if zero, or more than one, nodes are currently selected.
163 
164@property (nonatomic, readonly) id <PSTreeGraphModelNode> singleSelectedModelNode;
165
166/// Returns the bounding box of the selectedModelNodes.  The bounding box takes only the selected
167/// nodes into account, disregarding any descendants they might have.
168 
169@property (nonatomic, readonly) CGRect selectionBounds;
170
171
172#pragma mark - Node Hit-Testing
173
174/// Returns the model node under the given point, which must be expressed in the TreeGraph's 
175/// interior (bounds) coordinate space.  If there is a collapsed subtree at the given point, 
176/// returns the model node at the root of the collapsed subtree.  If there is no model node 
177/// at the given point, returns nil.
178 
179- (id <PSTreeGraphModelNode> ) modelNodeAtPoint:(CGPoint)p;
180
181
182#pragma mark - Sizing and Layout
183
184/// A TreeGraph's minimumFrameSize is the size needed to accommodate its content (as currently 
185/// laid out) and margins.  Changes to the TreeGraph's content, layout, or margins will update 
186/// this.  When a TreeGraph is the documentView of an UIScrollView, its actual frame may be larger
187/// than its minimumFrameSize, since we automatically expand the TreeGraph to always be at least 
188/// as large as the UIScrollView's clip area (contentView) to provide a nicer user experience.
189 
190@property (nonatomic, assign) CGSize minimumFrameSize;
191
192/// If YES, and if the TreeGraph is the documentView of an UIScrollView, the TreeGraph will 
193/// automatically resize itself as needed to ensure that it always at least fills the content 
194/// area of its enclosing UIScrollView.  If NO, or if the TreeGraph is not the documentView of 
195/// an UIScrollView, the TreeGraph's size is determined only by its content and margins.
196 
197@property (nonatomic, assign) BOOL resizesToFillEnclosingScrollView;
198
199/// The style for tree graph orientation  
200//(See the TreeGraphOrientationStyle enumeration above.)
201
202@property (nonatomic, assign) PSTreeGraphOrientationStyle treeGraphOrientation;
203
204/// Returns YES if the tree needs relayout.
205 
206- (BOOL) needsGraphLayout;
207
208/// Marks the tree as needing relayout.
209 
210- (void) setNeedsGraphLayout;
211
212/// Performs graph layout, if the tree is marked as needing it.  Returns the size computed for the
213/// tree (not including contentMargin).
214 
215- (CGSize) layoutGraphIfNeeded;
216
217/// Collapses the root node, if it is currently expanded.
218 
219- (void) collapseRoot;
220
221/// Expands the root node, if it is currently collapsed.
222 
223- (void) expandRoot;
224
225/// Toggles the expansion state of the TreeGraph's selectedModelNodes, expanding those that are
226/// currently collapsed, and collapsing those that are currently expanded.
227 
228- (IBAction) toggleExpansionOfSelectedModelNodes:(id)sender;
229
230/// Returns the bounding box of the node views that represent the specified modelNodes.  Model 
231/// nodes that aren't part of the displayed tree, or are part of a collapsed subtree, are ignored
232/// and don't contribute to the returned bounding box.  The bounding box takes only the specified
233/// nodes into account, disregarding any descendants they might have.
234 
235- (CGRect) boundsOfModelNodes:(NSSet *)modelNodes;
236
237
238#pragma mark - Scrolling
239
240/// Does a [self scrollRectToVisible:] with the bounding box of the specified model nodes.
241 
242- (void) scrollModelNodesToVisible:(NSSet *)modelNodes animated:(BOOL)animated;
243
244/// Does a [self scrollRectToVisible:] with the bounding box of the selected model nodes.
245 
246- (void) scrollSelectedModelNodesToVisibleAnimated:(BOOL)animated;
247
248
249#pragma mark - Animation Support
250
251/// Whether the TreeGraph animates layout operations.  Defaults to YES.  If set to NO, layout 
252/// jumpst instantaneously to the tree's new state.
253 
254@property (nonatomic, assign) BOOL animatesLayout;
255
256/// Used to temporarily suppress layout animation during event tracking.  Layout animation happens
257/// only if animatesLayout is YES and this is NO.
258 
259@property (nonatomic, assign) BOOL layoutAnimationSuppressed;
260
261
262#pragma mark - Layout Metrics
263
264/// The amount of padding to leave between the displayed tree and each of the four edges of the 
265/// TreeGraph's bounds.
266 
267@property (nonatomic, assign) CGFloat contentMargin;
268
269/// The horizonal spacing between each parent node and its child nodes.
270 
271@property (nonatomic, assign) CGFloat parentChildSpacing;
272
273/// The vertical spacing betwen sibling nodes.
274 
275@property (nonatomic, assign) CGFloat siblingSpacing;
276
277
278#pragma mark - Styling
279
280// The fill color for the TreeGraph's content area.
281 
282// @property(copy) UIColor *backgroundColor;
283
284/// The stroke color for node connecting lines.
285 
286@property (nonatomic, retain) UIColor *connectingLineColor;
287
288/// The width for node connecting lines.
289 
290@property (nonatomic, assign) CGFloat connectingLineWidth;
291
292/// The style for node connecting lines.  (See the PSTreeGraphConnectingLineStyle enumeration above.)
293 
294@property (nonatomic, assign) PSTreeGraphConnectingLineStyle connectingLineStyle;
295
296/// Defaults to NO.  If YES, a stroked outline is shown around each of the TreeGraph's 
297/// SubtreeViews.  This can be helpful for visualizing the TreeGraph's structure and layout.
298 
299@property (nonatomic, assign) BOOL showsSubtreeFrames;
300
301
302#pragma mark - Input and Navigation
303
304/// Custom input view for navigation.  
305///
306/// By default, this control supports a hardware keyboard unless this property is assigned
307/// to another input view.
308///
309/// More Info:
310/// 
311/// A placeholder view is created to so the default keyboard is not presented to the user.
312/// When a hardware keyboard is attached, touching the TreeGraph makes it first responder
313/// and certain keyboard shortcuts become available for navigation. ie. the space bar 
314/// expands and collapses the current selection. The following keys; w, a, s, d, navigate
315/// relative to the graph.
316///
317/// Custom navigation can be added by assigning a custom UIView to inputView, and linking
318/// it up to some of the actions below.
319
320@property (nonatomic, retain) IBOutlet UIView *inputView;
321
322// Model relative navigation
323- (void) moveToSiblingByRelativeIndex:(NSInteger)relativeIndex;
324- (IBAction) moveToParent:(id)sender;
325- (IBAction) moveToNearestChild:(id)sender;
326
327// Graph relative navigation
328- (IBAction) moveUp:(id)sender;
329- (IBAction) moveDown:(id)sender;
330- (IBAction) moveLeft:(id)sender;
331- (IBAction) moveRight:(id)sender;
332
333@end