Snapshot 39
[MacVim.git] / src / MacVim / RBSplitView.h
blob0c786c2b09a699d26fed2cf5b1492137d9ec06ee
1 //
2 // RBSplitView.h version 1.1.4
3 // RBSplitView
4 //
5 // Created by Rainer Brockerhoff on 24/09/2004.
6 // Copyright 2004-2006 Rainer Brockerhoff.
7 // Some Rights Reserved under the Creative Commons Attribution License, version 2.5, and/or the MIT License.
8 //
10 #import "RBSplitSubview.h"
12 // These values are used to handle the various cursor types.
13 typedef enum {
14 RBSVHorizontalCursor=0, // appears over horizontal dividers
15 RBSVVerticalCursor, // appears over vertical dividers
16 RBSV2WayCursor, // appears over two-way thumbs
17 RBSVDragCursor, // appears while dragging
18 RBSVCursorTypeCount
19 } RBSVCursorType;
21 @interface RBSplitView : RBSplitSubview {
22 // Subclasses normally should use setter methods instead of changing instance variables by assignment.
23 // Most getter methods simply return the corresponding instance variable, so with some care, subclasses
24 // could reference them directly.
25 IBOutlet id delegate; // The delegate (may be nil).
26 NSString* autosaveName; // This name is used for storing subview proportions in user defaults.
27 NSColor* background; // The color used to paint the view's background (may be nil).
28 NSImage* divider; // The image used for the divider "dimple".
29 NSRect* dividers; // A C array of NSRects, one for each divider.
30 float dividerThickness; // Actual divider width; should be an integer and at least 1.0.
31 BOOL mustAdjust; // Set internally if the subviews need to be adjusted.
32 BOOL mustClearFractions; // Set internally if fractions should be cleared before adjusting.
33 BOOL isHorizontal; // The divider's orientation; default is vertical.
34 BOOL canSaveState; // Set internally to allow saving subview state.
35 BOOL isCoupled; // If YES, take some parameters from the containing RBSplitView, if any.
36 BOOL isAdjusting; // Set internally while the subviews are being adjusted.
37 BOOL isDragging; // Set internally while in a drag loop.
38 BOOL isInScrollView; // Set internally if directly contained in an NSScrollView.
41 // These class methods get and set the cursor used for each type.
42 // Pass in nil to reset to the default cursor for that type.
43 + (NSCursor*)cursor:(RBSVCursorType)type;
44 + (void)setCursor:(RBSVCursorType)type toCursor:(NSCursor*)cursor;
46 // This class method clears the saved state for a given autosave name from the defaults.
47 + (void)removeStateUsingName:(NSString*)name;
49 // This class method returns the actual key used to store autosave data in the defaults.
50 + (NSString*)defaultsKeyForName:(NSString*)name isHorizontal:(BOOL)orientation;
52 // Sets and gets the autosaveName; this will be the key used to store the subviews' proportions
53 // in the user defaults. Default is @"", which doesn't save anything. Set flag to YES to set
54 // unique names for nested subviews. You are responsible for avoiding duplicates.
55 - (void)setAutosaveName:(NSString*)aString recursively:(BOOL)flag;
56 - (NSString*)autosaveName;
58 // Saves the current state of the subviews if there's a valid autosave name set. If the argument
59 // is YES, it's then also called recursively for nested RBSplitViews. Returns YES if successful.
60 - (BOOL)saveState:(BOOL)recurse;
62 // Restores the saved state of the subviews if there's a valid autosave name set. If the argument
63 // is YES, it's first called recursively for nested RBSplitViews. Returns YES if successful.
64 // You need to call adjustSubviews after calling this.
65 - (BOOL)restoreState:(BOOL)recurse;
67 // Returns a string encoding the current state of all direct subviews. Does not check for nesting.
68 - (NSString*)stringWithSavedState;
70 // Readjusts all direct subviews according to the encoded string parameter. The number of subviews
71 // must match. Returns YES if successful. Does not check for nesting.
72 - (BOOL)setStateFromString:(NSString*)aString;
74 // Returns an array with complete state information for the receiver and all subviews, taking
75 // nesting into account. Don't store this array in a file, as its format might change in the
76 // future; this is for taking a state snapshot and later restoring it with setStatesFromArray.
77 - (NSArray*)arrayWithStates;
79 // Restores the state of the receiver and all subviews. The array must have been produced by a
80 // previous call to arrayWithStates. Returns YES if successful. This will fail if you have
81 // added or removed subviews in the meantime!
82 // You need to call adjustSubviews after calling this.
83 - (BOOL)setStatesFromArray:(NSArray*)array;
85 // This is the designated initializer for creating RBSplitViews programmatically.
86 - (id)initWithFrame:(NSRect)frame;
88 // This convenience initializer adds any number of subviews and adjusts them proportionally.
89 - (id)initWithFrame:(NSRect)frame andSubviews:(unsigned)count;
91 // Sets and gets the delegate. (Delegates aren't retained.) See further down for delegate methods.
92 - (void)setDelegate:(id)anObject;
93 - (id)delegate;
95 // Returns a subview which has a certain identifier string, or nil if there's none
96 - (RBSplitSubview*)subviewWithIdentifier:(NSString*)anIdentifier;
98 // Returns the subview at a certain position. Returns nil if the position is invalid.
99 - (RBSplitSubview*)subviewAtPosition:(unsigned)position;
101 // Adds a subview at a certain position.
102 - (void)addSubview:(NSView*)aView atPosition:(unsigned)position;
104 // Sets and gets the divider thickness, which should be a positive integer or zero.
105 // Setting the divider image also resets this automatically, so you would call this
106 // only if you want the divider to be larger or smaller than the image. Zero means that
107 // the image dimensions will be used.
108 - (void)setDividerThickness:(float)thickness;
109 - (float)dividerThickness;
111 // Sets and gets the divider image. The default image can also be set in Interface Builder, so usually
112 // there's no need to call this. Passing in nil means that the default divider thickness will be zero,
113 // and no mouse events will be processed, so that the dividers can be moved only programmatically.
114 - (void)setDivider:(NSImage*)image;
115 - (NSImage*)divider;
117 // Sets and gets the view background. The default is nil, meaning no background is
118 // drawn and the view and its subviews are considered transparent.
119 - (void)setBackground:(NSColor*)color;
120 - (NSColor*)background;
122 // Sets and gets the orientation. This uses the same convention as NSSplitView: vertical means the
123 // dividers are vertical, but the subviews are in a horizontal row. Sort of counter-intuitive, yes.
124 - (void)setVertical:(BOOL)flag;
125 - (BOOL)isVertical;
126 - (BOOL)isHorizontal;
128 // Call this to force adjusting the subviews before display. Called automatically if anything
129 // relevant is changed.
130 - (void)setMustAdjust;
132 // Returns YES if there's a pending adjustment.
133 - (BOOL)mustAdjust;
135 // Returns YES if we're in a dragging loop.
136 - (BOOL)isDragging;
138 // Returns YES if the view is directly contained in an NSScrollView.
139 - (BOOL)isInScrollView;
141 // Call this to recalculate all subview dimensions. Normally this is done automatically whenever
142 // something relevant is changed, so you rarely will need to call this explicitly.
143 - (void)adjustSubviews;
145 // This method should be called only from within the splitView:wasResizedFrom:to: delegate method
146 // to keep some specific subview the same size.
147 - (void)adjustSubviewsExcepting:(RBSplitSubview*)excepting;
149 // This method draws dividers. You should never call it directly but you can override it when
150 // subclassing, if you need custom dividers.
151 - (void)drawDivider:(NSImage*)anImage inRect:(NSRect)rect betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing;
153 @end
155 // The following methods are optionally implemented by the delegate.
157 @interface NSObject(RBSplitViewDelegate)
159 // The delegate can override a subview's ability to collapse by implementing this method.
160 // Return YES to allow collapsing. If this is implemented, the subviews' built-in
161 // 'collapsed' flags are ignored.
162 - (BOOL)splitView:(RBSplitView*)sender canCollapse:(RBSplitSubview*)subview;
164 // The delegate can alter the divider's appearance by implementing this method.
165 // Before calling this, the divider is filled with the background, and afterwards
166 // the divider image is drawn into the returned rect. If imageRect is empty, no
167 // divider image will be drawn, because there are nested RBSplitViews. Return
168 // NSZeroRect to suppress the divider image. Return imageRect to use the default
169 // location for the image, or change its origin to place the image elsewhere.
170 // You could also draw the divider yourself at this point and return NSZeroRect.
171 - (NSRect)splitView:(RBSplitView*)sender willDrawDividerInRect:(NSRect)dividerRect betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing withProposedRect:(NSRect)imageRect;
173 // These methods are called after a subview is completely collapsed or expanded. adjustSubviews may or may not
174 // have been called, however.
175 - (void)splitView:(RBSplitView*)sender didCollapse:(RBSplitSubview*)subview;
176 - (void)splitView:(RBSplitView*)sender didExpand:(RBSplitSubview*)subview;
178 // These methods are called just before and after adjusting subviews.
179 - (void)willAdjustSubviews:(RBSplitView*)sender;
180 - (void)didAdjustSubviews:(RBSplitView*)sender;
182 // This method will be called after a RBSplitView is resized with setFrameSize: but before
183 // adjustSubviews is called on it.
184 - (void)splitView:(RBSplitView*)sender wasResizedFrom:(float)oldDimension to:(float)newDimension;
186 // This method will be called when a divider is double-clicked and both leading and trailing
187 // subviews can be collapsed. Return either of the parameters to collapse that subview, or nil
188 // to collapse neither. If not implemented, the smaller subview will be collapsed.
189 - (RBSplitSubview*)splitView:(RBSplitView*)sender collapseLeading:(RBSplitSubview*)leading orTrailing:(RBSplitSubview*)trailing;
191 // This method will be called when a cursor rect is being set (inside resetCursorRects). The
192 // proposed rect is passed in. Return the actual rect, or NSZeroRect to suppress cursor setting
193 // for this divider. This won't be called for two-axis thumbs, however. The rects are in
194 // sender's local coordinates.
195 - (NSRect)splitView:(RBSplitView*)sender cursorRect:(NSRect)rect forDivider:(unsigned int)divider;
197 // This method will be called whenever a mouse-down event is received in a divider. Return YES to have
198 // the event handled by the split view, NO if you wish to ignore it or handle it in the delegate.
199 - (BOOL)splitView:(RBSplitView*)sender shouldHandleEvent:(NSEvent*)theEvent inDivider:(unsigned int)divider betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing;
201 // This method will be called just before a subview will be collapsed or expanded with animation.
202 // Return the approximate time the animation should take, or 0.0 to disallow animation.
203 // If not implemented, it will use the default of 0.2 seconds per 150 pixels.
204 - (NSTimeInterval)splitView:(RBSplitView*)sender willAnimateSubview:(RBSplitSubview*)subview withDimension:(float)dimension;
206 // This method will be called whenever a subview's frame is changed, usually from inside adjustSubviews' final loop.
207 // You'd normally use this to move some auxiliary view to keep it aligned with the subview.
208 - (void)splitView:(RBSplitView*)sender changedFrameOfSubview:(RBSplitSubview*)subview from:(NSRect)fromRect to:(NSRect)toRect;
210 // This method is called whenever the event handlers want to check if some point within the RBSplitSubview
211 // should act as an alternate drag view. Usually, the delegate will check the point (which is in sender's
212 // local coordinates) against the frame of one or several auxiliary views, and return a valid divider number.
213 // Returning NSNotFound means the point is not valid.
214 - (unsigned int)splitView:(RBSplitView*)sender dividerForPoint:(NSPoint)point inSubview:(RBSplitSubview*)subview;
216 // This method is called continuously while a divider is dragged, just before the leading subview is resized.
217 // Return NO to resize the trailing view by the same amount, YES to resize the containing window by the same amount.
218 - (BOOL)splitView:(RBSplitView*)sender shouldResizeWindowForDivider:(unsigned int)divider betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing willGrow:(BOOL)grow;
220 // This method is called by each subview's drawRect: method, just after filling it with the background color but
221 // before the contained subviews are drawn. Usually you would use this to draw a frame inside the subview.
222 - (void)splitView:(RBSplitView*)sender willDrawSubview:(RBSplitSubview*)subview inRect:(NSRect)rect;
224 @end