/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. #import <UIKit/UIKit.h>
  14. #import <CoreGraphics/CoreGraphics.h>
  15. // A TreeGraph's nodes may be connected by either "direct" or "orthogonal" lines.
  16. typedef enum {
  17. PSTreeGraphConnectingLineStyleDirect = 0,
  18. PSTreeGraphConnectingLineStyleOrthogonal = 1,
  19. } PSTreeGraphConnectingLineStyle;
  20. // A TreeGraph's orientation may be either "horizontal" or "vertical".
  21. typedef enum {
  22. PSTreeGraphOrientationStyleHorizontal = 0,
  23. PSTreeGraphOrientationStyleVertical = 1,
  24. } PSTreeGraphOrientationStyle;
  25. @class PSBaseSubtreeView;
  26. @protocol PSTreeGraphModelNode;
  27. @protocol PSTreeGraphDelegate;
  28. @interface PSBaseTreeGraphView : UIView <UIKeyInput>
  29. {
  30. @private
  31. // Model
  32. id <PSTreeGraphModelNode> _modelRoot;
  33. // Delegate
  34. id <PSTreeGraphDelegate> _delegate;
  35. // Model Object -> SubtreeView Mapping
  36. NSMutableDictionary *_modelNodeToSubtreeViewMapTable;
  37. // Node View Nib Specification
  38. NSString *_nodeViewNibName;
  39. NSBundle *_nodeViewNibBundle;
  40. // Selection State
  41. NSSet *_selectedModelNodes;
  42. // Layout State
  43. CGSize _minimumFrameSize;
  44. // Animation Support
  45. BOOL _animatesLayout;
  46. BOOL _layoutAnimationSuppressed;
  47. // Layout Metrics
  48. CGFloat _contentMargin;
  49. CGFloat _parentChildSpacing;
  50. CGFloat _siblingSpacing;
  51. // Layout Behavior
  52. BOOL _resizesToFillEnclosingScrollView;
  53. PSTreeGraphOrientationStyle _treeGraphOrientation;
  54. // Styling
  55. // UIColor *backgroundColor;
  56. UIColor *_connectingLineColor;
  57. CGFloat _connectingLineWidth;
  58. PSTreeGraphConnectingLineStyle _connectingLineStyle;
  59. // A debug feature that outlines the view hiarchy.
  60. BOOL _showsSubtreeFrames;
  61. // iOS 4 and above ONLY
  62. UINib *_cachedNodeViewNib;
  63. // Custom input view support
  64. UIView *_inputView;
  65. }
  66. #pragma mark - Delegate
  67. @property (nonatomic, assign) id delegate;
  68. #pragma mark - Parent Resize Notification
  69. /// Use this method to keep the view in sync for now.
  70. - (void) parentClipViewDidResize:(id)object;
  71. #pragma mark - Creating Instances
  72. /// Initializes a new TreeGraph instance. (TreeGraph's designated initializer is the same as
  73. /// UIView's: -initWithFrame:.) The TreeGraph has default appearance properties and layout
  74. /// metrics, but to have a usable TreeGraph with actual content, you need to specify a
  75. /// nodeViewNibName, an optional nodeViewNibBundle, and a modelRoot.
  76. - (id) initWithFrame:(CGRect)frame;
  77. #pragma mark - Connection to Model
  78. /// The root of the model node tree that the TreeGraph is being asked to display. (The modelRoot
  79. /// may have ancestor nodes, but TreeGraph will ignore them and treat modelRoot as the root.) May
  80. /// be set to nil, in which case the TreeGraph displays no content. The modelRoot object, and all
  81. /// of its desdendants as exposed through recursive application of the "-childModelNodes" accessor
  82. /// to traverse the model tree, must conform to the TreeGraphModelNode protocol declared in
  83. /// TreeGraphModelNode.h
  84. @property (nonatomic, retain) id <PSTreeGraphModelNode> modelRoot;
  85. #pragma mark - Root SubtreeView Access
  86. /// A TreeGraph builds the tree it displays using recursively nested SubtreeView instances. This
  87. /// read-only accessor provides a way to get the rootmost SubtreeView (the one that corresponds
  88. /// to the modelRoot model node).
  89. @property (nonatomic, readonly) PSBaseSubtreeView *rootSubtreeView;
  90. #pragma mark - Node View Nib Specification
  91. /// The name of the .nib file from which to instantiate node views. (This API design assumes that
  92. /// all node views should be instantiated from the same .nib. If a tree of heterogeneous nodes
  93. /// was desired, we could switch to a different mechanism for identifying the .nib to instantiate.)
  94. /// Must specify a "View" .nib file, whose File's Owner is a SubtreeView, or the TreeGraph will be
  95. /// unable to instantiate node views.
  96. @property (nonatomic, copy) NSString *nodeViewNibName;
  97. #pragma mark - Selection State
  98. /// The unordered set of model nodes that are currently selected in the TreeGraph. When no nodes
  99. /// are selected, this is an empty NSSet. It will never be nil (and attempting to set it to nil
  100. /// will raise an exception). Every member of this set must be a descendant of the TreeGraph's
  101. /// modelRoot (or modelRoot itself). If any member is not, TreeGraph will raise an exception.
  102. @property (nonatomic, copy) NSSet *selectedModelNodes;
  103. /// Convenience accessor that returns the selected node, if exactly one node is currently
  104. /// selected. Returns nil if zero, or more than one, nodes are currently selected.
  105. @property (nonatomic, readonly) id <PSTreeGraphModelNode> singleSelectedModelNode;
  106. /// Returns the bounding box of the selectedModelNodes. The bounding box takes only the selected
  107. /// nodes into account, disregarding any descendants they might have.
  108. @property (nonatomic, readonly) CGRect selectionBounds;
  109. #pragma mark - Node Hit-Testing
  110. /// Returns the model node under the given point, which must be expressed in the TreeGraph's
  111. /// interior (bounds) coordinate space. If there is a collapsed subtree at the given point,
  112. /// returns the model node at the root of the collapsed subtree. If there is no model node
  113. /// at the given point, returns nil.
  114. - (id <PSTreeGraphModelNode> ) modelNodeAtPoint:(CGPoint)p;
  115. #pragma mark - Sizing and Layout
  116. /// A TreeGraph's minimumFrameSize is the size needed to accommodate its content (as currently
  117. /// laid out) and margins. Changes to the TreeGraph's content, layout, or margins will update
  118. /// this. When a TreeGraph is the documentView of an UIScrollView, its actual frame may be larger
  119. /// than its minimumFrameSize, since we automatically expand the TreeGraph to always be at least
  120. /// as large as the UIScrollView's clip area (contentView) to provide a nicer user experience.
  121. @property (nonatomic, assign) CGSize minimumFrameSize;
  122. /// If YES, and if the TreeGraph is the documentView of an UIScrollView, the TreeGraph will
  123. /// automatically resize itself as needed to ensure that it always at least fills the content
  124. /// area of its enclosing UIScrollView. If NO, or if the TreeGraph is not the documentView of
  125. /// an UIScrollView, the TreeGraph's size is determined only by its content and margins.
  126. @property (nonatomic, assign) BOOL resizesToFillEnclosingScrollView;
  127. /// The style for tree graph orientation
  128. //(See the TreeGraphOrientationStyle enumeration above.)
  129. @property (nonatomic, assign) PSTreeGraphOrientationStyle treeGraphOrientation;
  130. /// Returns YES if the tree needs relayout.
  131. - (BOOL) needsGraphLayout;
  132. /// Marks the tree as needing relayout.
  133. - (void) setNeedsGraphLayout;
  134. /// Performs graph layout, if the tree is marked as needing it. Returns the size computed for the
  135. /// tree (not including contentMargin).
  136. - (CGSize) layoutGraphIfNeeded;
  137. /// Collapses the root node, if it is currently expanded.
  138. - (void) collapseRoot;
  139. /// Expands the root node, if it is currently collapsed.
  140. - (void) expandRoot;
  141. /// Toggles the expansion state of the TreeGraph's selectedModelNodes, expanding those that are
  142. /// currently collapsed, and collapsing those that are currently expanded.
  143. - (IBAction) toggleExpansionOfSelectedModelNodes:(id)sender;
  144. /// Returns the bounding box of the node views that represent the specified modelNodes. Model
  145. /// nodes that aren't part of the displayed tree, or are part of a collapsed subtree, are ignored
  146. /// and don't contribute to the returned bounding box. The bounding box takes only the specified
  147. /// nodes into account, disregarding any descendants they might have.
  148. - (CGRect) boundsOfModelNodes:(NSSet *)modelNodes;
  149. #pragma mark - Scrolling
  150. /// Does a [self scrollRectToVisible:] with the bounding box of the specified model nodes.
  151. - (void) scrollModelNodesToVisible:(NSSet *)modelNodes animated:(BOOL)animated;
  152. /// Does a [self scrollRectToVisible:] with the bounding box of the selected model nodes.
  153. - (void) scrollSelectedModelNodesToVisibleAnimated:(BOOL)animated;
  154. #pragma mark - Animation Support
  155. /// Whether the TreeGraph animates layout operations. Defaults to YES. If set to NO, layout
  156. /// jumpst instantaneously to the tree's new state.
  157. @property (nonatomic, assign) BOOL animatesLayout;
  158. /// Used to temporarily suppress layout animation during event tracking. Layout animation happens
  159. /// only if animatesLayout is YES and this is NO.
  160. @property (nonatomic, assign) BOOL layoutAnimationSuppressed;
  161. #pragma mark - Layout Metrics
  162. /// The amount of padding to leave between the displayed tree and each of the four edges of the
  163. /// TreeGraph's bounds.
  164. @property (nonatomic, assign) CGFloat contentMargin;
  165. /// The horizonal spacing between each parent node and its child nodes.
  166. @property (nonatomic, assign) CGFloat parentChildSpacing;
  167. /// The vertical spacing betwen sibling nodes.
  168. @property (nonatomic, assign) CGFloat siblingSpacing;
  169. #pragma mark - Styling
  170. // The fill color for the TreeGraph's content area.
  171. // @property(copy) UIColor *backgroundColor;
  172. /// The stroke color for node connecting lines.
  173. @property (nonatomic, retain) UIColor *connectingLineColor;
  174. /// The width for node connecting lines.
  175. @property (nonatomic, assign) CGFloat connectingLineWidth;
  176. /// The style for node connecting lines. (See the PSTreeGraphConnectingLineStyle enumeration above.)
  177. @property (nonatomic, assign) PSTreeGraphConnectingLineStyle connectingLineStyle;
  178. /// Defaults to NO. If YES, a stroked outline is shown around each of the TreeGraph's
  179. /// SubtreeViews. This can be helpful for visualizing the TreeGraph's structure and layout.
  180. @property (nonatomic, assign) BOOL showsSubtreeFrames;
  181. #pragma mark - Input and Navigation
  182. /// Custom input view for navigation.
  183. ///
  184. /// By default, this control supports a hardware keyboard unless this property is assigned
  185. /// to another input view.
  186. ///
  187. /// More Info:
  188. ///
  189. /// A placeholder view is created to so the default keyboard is not presented to the user.
  190. /// When a hardware keyboard is attached, touching the TreeGraph makes it first responder
  191. /// and certain keyboard shortcuts become available for navigation. ie. the space bar
  192. /// expands and collapses the current selection. The following keys; w, a, s, d, navigate
  193. /// relative to the graph.
  194. ///
  195. /// Custom navigation can be added by assigning a custom UIView to inputView, and linking
  196. /// it up to some of the actions below.
  197. @property (nonatomic, retain) IBOutlet UIView *inputView;
  198. // Model relative navigation
  199. - (void) moveToSiblingByRelativeIndex:(NSInteger)relativeIndex;
  200. - (IBAction) moveToParent:(id)sender;
  201. - (IBAction) moveToNearestChild:(id)sender;
  202. // Graph relative navigation
  203. - (IBAction) moveUp:(id)sender;
  204. - (IBAction) moveDown:(id)sender;
  205. - (IBAction) moveLeft:(id)sender;
  206. - (IBAction) moveRight:(id)sender;
  207. @end