Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
RBSplitView.h
Go to the documentation of this file.
1//
2// RBSplitView.h version 1.2
3// RBSplitView
4//
5// Created by Rainer Brockerhoff on 24/09/2004.
6// Copyright 2004-2009 Rainer Brockerhoff.
7// Some Rights Reserved under the Creative Commons Attribution License, version 2.5, and/or the MIT License.
8//
9
10#import "RBSplitSubview.h"
11
12// These values are used to handle the various cursor types.
13typedef 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
20
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 CGFloat 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.
39}
40
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;
45
46// This class method clears the saved state for a given autosave name from the defaults.
47+ (void)removeStateUsingName:(NSString*)name;
48
49// This class method returns the actual key used to store autosave data in the defaults.
50+ (NSString*)defaultsKeyForName:(NSString*)name isHorizontal:(BOOL)orientation;
51
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;
57
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;
61
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;
66
67// Returns a string encoding the current state of all direct subviews. Does not check for nesting.
68- (NSString*)stringWithSavedState;
69
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;
73
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;
78
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;
84
85// This is the designated initializer for creating RBSplitViews programmatically.
86- (id)initWithFrame:(NSRect)frame;
87
88// This convenience initializer adds any number of subviews and adjusts them proportionally.
89- (id)initWithFrame:(NSRect)frame andSubviews:(NSUInteger)count;
90
91// Sets and gets the delegate. (Delegates aren't retained.) See further down for delegate methods.
92- (void)setDelegate:(id)anObject;
93- (id)delegate;
94
95// Returns a subview which has a certain identifier string, or nil if there's none
96- (RBSplitSubview*)subviewWithIdentifier:(NSString*)anIdentifier;
97
98// Returns the subview at a certain position. Returns nil if the position is invalid.
99- (RBSplitSubview*)subviewAtPosition:(NSUInteger)position;
100
101// Adds a subview at a certain position.
102- (void)addSubview:(NSView*)aView atPosition:(NSUInteger)position;
103
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:(CGFloat)thickness;
109- (CGFloat)dividerThickness;
110
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;
116
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;
121
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- (void)setHorizontal:(BOOL)flag;
127- (BOOL)isHorizontal;
128
129// Call this to force adjusting the subviews before display. Called automatically if anything
130// relevant is changed.
131- (void)setMustAdjust;
132
133// Returns YES if there's a pending adjustment.
134- (BOOL)mustAdjust;
135- (BOOL)isAdjusting;
136
137// Returns YES if we're in a dragging loop.
138- (BOOL)isDragging;
139
140// Returns YES if the view is directly contained in an NSScrollView.
141- (BOOL)isInScrollView;
142
143// Call this to recalculate all subview dimensions. Normally this is done automatically whenever
144// something relevant is changed, so you rarely will need to call this explicitly.
145- (void)adjustSubviews;
146
147// This method should be called only from within the splitView:wasResizedFrom:to: delegate method
148// to keep some specific subview the same size.
149- (void)adjustSubviewsExcepting:(RBSplitSubview*)excepting;
150
151// This method draws dividers. You should never call it directly but you can override it when
152// subclassing, if you need custom dividers.
153- (void)drawDivider:(NSImage*)anImage inRect:(NSRect)rect betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing;
154
155@end
156
157// The following methods are optionally implemented by the delegate.
158
159@protocol RBSplitViewDelegate<NSObject>
160@optional
161
162// The delegate can override a subview's ability to collapse by implementing this method.
163// Return YES to allow collapsing. If this is implemented, the subviews' built-in
164// 'collapsed' flags are ignored.
165- (BOOL)splitView:(RBSplitView*)sender canCollapse:(RBSplitSubview*)subview;
166
167// The delegate can alter the divider's appearance by implementing this method.
168// Before calling this, the divider is filled with the background, and afterwards
169// the divider image is drawn into the returned rect. If imageRect is empty, no
170// divider image will be drawn, because there are nested RBSplitViews. Return
171// NSZeroRect to suppress the divider image. Return imageRect to use the default
172// location for the image, or change its origin to place the image elsewhere.
173// You could also draw the divider yourself at this point and return NSZeroRect.
174- (NSRect)splitView:(RBSplitView*)sender willDrawDividerInRect:(NSRect)dividerRect betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing withProposedRect:(NSRect)imageRect;
175
176// These methods are called after a subview is completely collapsed or expanded. adjustSubviews may or may not
177// have been called, however.
178- (void)splitView:(RBSplitView*)sender didCollapse:(RBSplitSubview*)subview;
179- (void)splitView:(RBSplitView*)sender didExpand:(RBSplitSubview*)subview;
180
181// These methods are called just before and after adjusting subviews.
182- (void)willAdjustSubviews:(RBSplitView*)sender;
183- (void)didAdjustSubviews:(RBSplitView*)sender;
184
185// This method will be called after a RBSplitView is resized with setFrameSize: but before
186// adjustSubviews is called on it.
187- (void)splitView:(RBSplitView*)sender wasResizedFrom:(CGFloat)oldDimension to:(CGFloat)newDimension;
188
189// This method will be called when a divider is double-clicked and both leading and trailing
190// subviews can be collapsed. Return either of the parameters to collapse that subview, or nil
191// to collapse neither. If not implemented, the smaller subview will be collapsed.
192- (RBSplitSubview*)splitView:(RBSplitView*)sender collapseLeading:(RBSplitSubview*)leading orTrailing:(RBSplitSubview*)trailing;
193
194// This method will be called when a cursor rect is being set (inside resetCursorRects). The
195// proposed rect is passed in. Return the actual rect, or NSZeroRect to suppress cursor setting
196// for this divider. This won't be called for two-axis thumbs, however. The rects are in
197// sender's local coordinates.
198- (NSRect)splitView:(RBSplitView*)sender cursorRect:(NSRect)rect forDivider:(NSUInteger)divider;
199
200// This method will be called whenever a mouse-down event is received in a divider. Return YES to have
201// the event handled by the split view, NO if you wish to ignore it or handle it in the delegate.
202- (BOOL)splitView:(RBSplitView*)sender shouldHandleEvent:(NSEvent*)theEvent inDivider:(NSUInteger)divider betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing;
203
204// This method will be called just before a subview will be collapsed or expanded with animation.
205// Return the approximate time the animation should take, or 0.0 to disallow animation.
206// If not implemented, it will use the default of 0.2 seconds per 150 pixels.
207- (NSTimeInterval)splitView:(RBSplitView*)sender willAnimateSubview:(RBSplitSubview*)subview withDimension:(CGFloat)dimension;
208
209// This method will be called whenever a subview's frame is changed, usually from inside adjustSubviews' final loop.
210// You'd normally use this to move some auxiliary view to keep it aligned with the subview.
211- (void)splitView:(RBSplitView*)sender changedFrameOfSubview:(RBSplitSubview*)subview from:(NSRect)fromRect to:(NSRect)toRect;
212
213// This method is called whenever the event handlers want to check if some point within the RBSplitSubview
214// should act as an alternate drag view. Usually, the delegate will check the point (which is in sender's
215// local coordinates) against the frame of one or several auxiliary views, and return a valid divider number.
216// Returning NSNotFound means the point is not valid.
217- (NSUInteger)splitView:(RBSplitView*)sender dividerForPoint:(NSPoint)point inSubview:(RBSplitSubview*)subview;
218
219// This method is called continuously while a divider is dragged, just before the leading subview is resized.
220// Return NO to resize the trailing view by the same amount, YES to resize the containing window by the same amount.
221- (BOOL)splitView:(RBSplitView*)sender shouldResizeWindowForDivider:(NSUInteger)divider betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing willGrow:(BOOL)grow;
222
223// This method is called by each subview's drawRect: method, just after filling it with the background color but
224// before the contained subviews are drawn. Usually you would use this to draw a frame inside the subview.
225- (void)splitView:(RBSplitView*)sender willDrawSubview:(RBSplitSubview*)subview inRect:(NSRect)rect;
226
227@end
228
RBSVCursorType
Definition RBSplitView.h:13
@ RBSVHorizontalCursor
Definition RBSplitView.h:14
@ RBSVDragCursor
Definition RBSplitView.h:17
@ RBSVVerticalCursor
Definition RBSplitView.h:15
@ RBSVCursorTypeCount
Definition RBSplitView.h:18
@ RBSV2WayCursor
Definition RBSplitView.h:16
NSRect * dividers
Definition RBSplitView.h:29
BOOL canSaveState
Definition RBSplitView.h:34
IBOutlet id delegate
Definition RBSplitView.h:25
NSString * autosaveName
Definition RBSplitView.h:26
NSColor * background
Definition RBSplitView.h:27
BOOL mustAdjust
Definition RBSplitView.h:31
BOOL isAdjusting
Definition RBSplitView.h:36
CGFloat dividerThickness
Definition RBSplitView.h:30
NSImage * divider
Definition RBSplitView.h:28
BOOL isInScrollView
Definition RBSplitView.h:38
BOOL mustClearFractions
Definition RBSplitView.h:32
BOOL isDragging
Definition RBSplitView.h:37
BOOL isHorizontal
Definition RBSplitView.h:33