// // RBSplitSubview.h version 1.0.4 // RBSplitView // // Created by Rainer Brockerhoff on 19/11/2004. // Copyright 2004,2005 Rainer Brockerhoff. All rights reserved. // #import // RBSplitView is the main class. It's forward-declared here. See details below. Basically, it works // like NSSplitView with some important differences. // The subviews (or "splits") are separated by equal-sized divider rectangles, which you can drag // perpendicularly to their axis or double-click. In the center of each divider is a thumb or divider image. // Subviews can be "collapsed" to zero dimension with the mouse or programmatically; when collapsing, // automatic resizing of their own subviews is turned off, so those subviews never get squashed out of // shape. You can rely on the "apparent" subview size never getting smaller than the minimum, or larger // than the maximum. @class RBSplitView; // RBSplitSubview is the container view for each "split" of the RBSplitView. RBSplitView works only with // RBSplitSubviews as direct subviews, and you never should see or try to generate RBSplitSubviews // outside a RBSplitView. // RBSplitView itself is a subclass of RBSplitSubview, so you can nest RBSplitViews directly. Such // nested split views can automatically create "two-axis" thumbs where their dividers meet, and these can // be dragged both horizontally and vertically at the same time. // Ordinarily you'd set up size limits and other attributes for each RBSplitSubview in Interface Builder // and never touch it inside the program. // RBSplitSubviews are different from normal views in that they don't have height or width but just // a "dimension", measured along the RBSplitView's divider's orientation (horizontal or vertical). The // "other" dimension is always set to cover the entire RBSplitView in that direction, so there's no // way to get or set it directly. // You can limit the allowable minimum and maximum dimensions, but be careful to limit your window sizes // to such values that always allow a valid combination of subviews dimensions. If the adjustSubviews // method fails to find such a combination of dimensions, even after collapsing or expanding subviews // that allow it, one of the subviews (usually the last) will be resized to an invalid size! // RBSplitSubviews are non-flipped. // These values are used to inquire about the status of a subview. typedef enum { RBSSubviewExpanding=-2, RBSSubviewCollapsing=-1, RBSSubviewNormal=0, RBSSubviewCollapsed=1 } RBSSubviewStatus; @interface RBSplitSubview : NSView { // Subclasses normally should use setter methods instead of changing instance variables by assignment. // Most getter methods simply return the corresponding instance variable, so with some care, subclasses // could reference them directly. NSString* identifier; // An identifier string for the subview, default is @"". int tag; // A tag integer for the subview, default is 0. float minDimension; // The minimum dimension. Must be 1.0 or any larger integer. float maxDimension; // The maximum dimension. Must be at least equal to the minDimension. // Set to a large number if there's no maximum. double fraction; // A fractional part of the dimension, used for proportional resizing. // Normally varies between -0.999... and 0.999... // When collapsed, holds the proportion of the RBSplitView's dimension // the view was occupying before collapsing. NSSize savedSize; // This holds the size the subview had before it was resized beyond // its minimum or maximum limits. Valid if notInLimits is YES. BOOL canCollapse; // YES if the subview can be collapsed. BOOL notInLimits; // YES if the subview's dimensions are outside the set limits. } // This class method returns YES if some RBSplitSubview is being animated. + (BOOL)animating; // This is the designated initializer for creating extra subviews programmatically. - (id)initWithFrame:(NSRect)frame; // Returns the immediately containing RBSplitView, or nil if there is none. // couplingSplitView returns nil if we're a non-coupled RBSplitView. // outermostSplitView returns the outermost RBSplitView. - (RBSplitView*)splitView; - (RBSplitView*)couplingSplitView; - (RBSplitView*)outermostSplitView; // Returns self if we're a RBSplitView, nil otherwise. Convenient for testing or calling methods. // coupledSplitView returns nil if we're a non-coupled RBSplitView. - (RBSplitView*)asSplitView; - (RBSplitView*)coupledSplitView; // Sets and gets the coupling between the view and its containing RBSplitView (if any). Coupled // RBSplitViews take some parameters, such as divider images, from the containing view. The default // for RBSplitView is YES. However, calling setCoupled: on a RBSplitSubview will have no effect, // and isCoupled will always return false. - (void)setCoupled:(BOOL)flag; - (BOOL)isCoupled; // Returns YES if the containing RBSplitView is horizontal. - (BOOL)splitViewIsHorizontal; // Returns the number of subviews. Just a convenience method. - (unsigned)numberOfSubviews; // Sets and gets the tag. - (void)setTag:(int)theTag; - (int)tag; // Sets and gets the identifier string. Will never be nil. - (void)setIdentifier:(NSString*)aString; - (NSString*)identifier; // Position means the subview's position within the RBSplitView - counts from zero left to right // or top to bottom. Setting it will move the subview to another position without changing its size, // status or attributes. Set position to 0 to move it to the start, or to some large number to move it // to the end of the RBSplitView. - (unsigned)position; - (void)setPosition:(unsigned)newPosition; // Returns YES if the subview is collapsed. Collapsed subviews are squashed down to zero but never // made smaller than the minimum dimension as far as their own subviews are concerned. If the // subview is being animated this will return NO. - (BOOL)isCollapsed; // This will return the current status of the subview. Negative values mean the subview is // being animated. - (RBSSubviewStatus)status; // Sets and gets the ability to collapse the subview. However, this can be overridden by the delegate. - (BOOL)canCollapse; - (void)setCanCollapse:(BOOL)flag; // Sets and gets the minimum and maximum dimensions. They're set at the same time to make sure values // are consistent. Despite being floats, they'll always have integer values. The minimum value for the // minimum is 1.0. Pass 0.0 for the maximum to set it to some huge number. - (float)minDimension; - (float)maxDimension; - (void)setMinDimension:(float)newMinDimension andMaxDimension:(float)newMaxDimension; // Call this to expand a subview programmatically. It will return the subview's dimension after // expansion. - (float)expand; // Call this to collapse a subview programmatically. It will return the negative // of the subview's dimension _before_ collapsing, or 0.0 if the view can't be collapsed. - (float)collapse; // These calls collapse and expand subviews with animation. They return YES if animation // startup was successful. - (BOOL)collapseWithAnimation; - (BOOL)expandWithAnimation; // Returns the current dimension of the subview. - (float)dimension; // Sets the current dimension of the subview, subject to the current maximum and minimum. // If the subview is collapsed, this has no immediate effect. - (void)setDimension:(float)value; // This method is used internally when a divider is dragged. It tries to change the subview's dimension // and returns the actual change, collapsing or expanding whenever possible. You usually won't need // to call this directly. - (float)changeDimensionBy:(float)increment mayCollapse:(BOOL)mayCollapse; @end