Commits

Anonymous committed 93e08d6

Added brand new split view functionality for 1.1.

  • Participants
  • Parent commits 6fa00e7

Comments (0)

Files changed (26)

File BWSplitView.classdescription

 {
-	Actions = {
-		// Define action descriptions here, for example
-		// "myAction:" = id;
+	Actions = 
+	{
+		"toggleCollapse:" = id;
 	};
-	Outlets = {
-		// Define outlet descriptions here, for example
-		// myOutlet = NSView;
+	Outlets = 
+	{
 	};
     ClassName = BWSplitView; 
     SuperClass = NSSplitView; 

File BWSplitView.h

 //  BWSplitView.h
 //  BWToolkit
 //
-//  Created by Brandon Walkin (www.brandonwalkin.com)
+//  Created by Brandon Walkin (www.brandonwalkin.com) and Fraser Kuyvenhoven.
 //  All code is provided under the New BSD license.
 //
 
 @interface BWSplitView : NSSplitView 
 {
 	NSColor *color;
-	BOOL colorIsEnabled, checkboxIsEnabled;
+	BOOL colorIsEnabled, checkboxIsEnabled, dividerCanCollapse, collapsibleSubviewCollapsed;
+	id secondaryDelegate;
+	NSMutableDictionary *minValues, *maxValues, *minUnits, *maxUnits;
+	NSMutableDictionary *resizableSubviewPreferredProportion, *nonresizableSubviewPreferredSize;
+	NSArray *stateForLastPreferredCalculations;
+	int collapsiblePopupSelection;
+	float uncollapsedSize;
+	
+	// Collapse button
+	NSButton *toggleCollapseButton;
+	BOOL isAnimating;
 }
 
+@property (retain) NSMutableDictionary *minValues, *maxValues, *minUnits, *maxUnits;
+@property (retain) NSMutableDictionary *resizableSubviewPreferredProportion, *nonresizableSubviewPreferredSize;
+@property (retain) NSArray *stateForLastPreferredCalculations;
+@property (retain) NSButton *toggleCollapseButton;
+@property BOOL collapsibleSubviewCollapsed;
+@property int collapsiblePopupSelection;
+@property BOOL dividerCanCollapse;
+
 // The split view divider color
 @property (copy) NSColor *color;
 
 // Flag for whether a custom divider color is enabled. If not, the standard divider color is used.
 @property BOOL colorIsEnabled;
 
+// Call this method to collapse or expand a subview configured as collapsible in the IB inspector.
+- (IBAction)toggleCollapse:(id)sender;
+
 @end

File BWSplitView.m

 //  BWSplitView.m
 //  BWToolkit
 //
-//  Created by Brandon Walkin (www.brandonwalkin.com)
+//  Created by Brandon Walkin (www.brandonwalkin.com) and Fraser Kuyvenhoven.
 //  All code is provided under the New BSD license.
 //
 
 #import "BWSplitView.h"
 #import "NSColor+BWAdditions.h"
+#import "NSEvent+BWAdditions.h"
 
 static NSGradient *gradient;
 static NSImage *dimpleImageBitmap, *dimpleImageVector;
 
 #define dimpleDimension 4.0f
 
+#define RESIZE_DEBUG_LOGS 0
+
 @interface BWSplitView (BWSVPrivate)
+
 - (void)drawDimpleInRect:(NSRect)aRect;
 - (void)drawGradientDividerInRect:(NSRect)aRect;
+- (int)resizableSubviews;
+- (BOOL)subviewIsResizable:(NSView *)subview;
+
+- (BOOL)subviewIsCollapsible:(NSView *)subview;
+- (BOOL)subviewIsCollapsed:(NSView *)subview;
+- (int)collapsibleSubviewIndex;
+- (NSView *)collapsibleSubview;
+- (BOOL)hasCollapsibleSubview;
+- (BOOL)collapsibleSubviewIsCollapsed;
+
+- (CGFloat)subviewMinimumSize:(int)subviewIndex;
+- (CGFloat)subviewMaximumSize:(int)subviewIndex;
+
+- (void)recalculatePreferredProportionsAndSizes;
+- (BOOL)validatePreferredProportionsAndSizes;
+- (void)validateAndCalculatePreferredProportionsAndSizes;
+- (void)clearPreferredProportionsAndSizes;
+
+- (void)resizeAndAdjustSubviews;
+
 @end
 
 @interface BWSplitView ()
 
 @implementation BWSplitView
 
-@synthesize color;
-@synthesize colorIsEnabled;
-@synthesize checkboxIsEnabled;
+@synthesize color, colorIsEnabled, checkboxIsEnabled, minValues, maxValues, minUnits, maxUnits, collapsiblePopupSelection, dividerCanCollapse, collapsibleSubviewCollapsed;
+@synthesize resizableSubviewPreferredProportion, nonresizableSubviewPreferredSize, stateForLastPreferredCalculations;
+@synthesize toggleCollapseButton;
 
 + (void)initialize;
 {
 	{
 		[self setColor:[decoder decodeObjectForKey:@"BWSVColor"]];
 		[self setColorIsEnabled:[decoder decodeBoolForKey:@"BWSVColorIsEnabled"]];
+		[self setMinValues:[decoder decodeObjectForKey:@"BWSVMinValues"]];
+		[self setMaxValues:[decoder decodeObjectForKey:@"BWSVMaxValues"]];
+		[self setMinUnits:[decoder decodeObjectForKey:@"BWSVMinUnits"]];
+		[self setMaxUnits:[decoder decodeObjectForKey:@"BWSVMaxUnits"]];
+		[self setCollapsiblePopupSelection:[decoder decodeIntForKey:@"BWSVCollapsiblePopupSelection"]];
+		[self setDividerCanCollapse:[decoder decodeBoolForKey:@"BWSVDividerCanCollapse"]];
+		
+		// Delegate set in nib has been decoded, but we want that to be the secondary delegate
+		[self setDelegate:[super delegate]];
+		[super setDelegate:self];
 	}
 	return self;
 }
 
 - (void)encodeWithCoder:(NSCoder*)coder
 {
+	// Temporarily change delegate
+	[super setDelegate:secondaryDelegate];
+	
     [super encodeWithCoder:coder];
 	
 	[coder encodeObject:[self color] forKey:@"BWSVColor"];
 	[coder encodeBool:[self colorIsEnabled] forKey:@"BWSVColorIsEnabled"];
+	[coder encodeObject:[self minValues] forKey:@"BWSVMinValues"];
+	[coder encodeObject:[self maxValues] forKey:@"BWSVMaxValues"];
+	[coder encodeObject:[self minUnits] forKey:@"BWSVMinUnits"];
+	[coder encodeObject:[self maxUnits] forKey:@"BWSVMaxUnits"];
+	[coder encodeInt:[self collapsiblePopupSelection] forKey:@"BWSVCollapsiblePopupSelection"];
+	[coder encodeBool:[self dividerCanCollapse] forKey:@"BWSVDividerCanCollapse"];
+	
+	// Set delegate back
+	[self setDelegate:[super delegate]];
+	[super setDelegate:self];
 }
 
 - (void)awakeFromNib
 {	
     if ([self isVertical])
     {
+		aRect.size.width = [self dividerThickness];
+		
 		if (colorIsEnabled && color != nil)
 			[color drawSwatchInRect:aRect];
 		else
     }
 	else
 	{
+		aRect.size.height = [self dividerThickness];
+		
 		if ([self dividerThickness] <= 1.01)
 		{
 			if (colorIsEnabled && color != nil)
 - (void)drawGradientDividerInRect:(NSRect)aRect
 {	
 	aRect = [self centerScanRect:aRect];
-	
+
 	// Draw gradient
 	NSRect gradRect = NSMakeRect(aRect.origin.x,aRect.origin.y + 1 / scaleFactor,aRect.size.width,aRect.size.height - 1 / scaleFactor);
 	[gradient drawInRect:gradRect angle:90];
     return thickness;
 }
 
+- (void)setDelegate:(id)anObj
+{
+	if (secondaryDelegate != self)
+		secondaryDelegate = anObj;
+	else
+		secondaryDelegate = nil;
+}
+
+- (BOOL)subviewIsCollapsible:(NSView *)subview;
+{
+	// check if this is the collapsible subview
+	int subviewIndex = [[self subviews] indexOfObject:subview];
+	
+	BOOL isCollapsibleSubview = (([self collapsiblePopupSelection] == 1 && subviewIndex == 0) || ([self collapsiblePopupSelection] == 2 && subviewIndex == [[self subviews] count] - 1));
+	
+	return isCollapsibleSubview;
+}
+
+- (BOOL)subviewIsCollapsed:(NSView *)subview;
+{
+	BOOL isCollapsibleSubview = [self subviewIsCollapsible:subview];
+	
+	return [super isSubviewCollapsed:subview] || (isCollapsibleSubview && collapsibleSubviewCollapsed);
+}
+
+- (BOOL)collapsibleSubviewIsCollapsed;
+{
+	return [self subviewIsCollapsed:[self collapsibleSubview]];
+}
+
+- (int)collapsibleSubviewIndex;
+{
+	switch ([self collapsiblePopupSelection]) {
+		case 1:
+			return 0;
+			break;
+		case 2:
+			return [[self subviews] count] - 1;
+			break;
+		default:
+			return -1;
+			break;
+	}
+}
+
+- (NSView *)collapsibleSubview;
+{
+	int index = [self collapsibleSubviewIndex];
+	
+	if (index >= 0)
+		return [[self subviews] objectAtIndex:index];
+	else
+		return nil;
+}
+
+- (BOOL)hasCollapsibleSubview;
+{
+	return [self collapsiblePopupSelection] != 0;
+}
+
+// This is done to support the use of Core Animation to collapse subviews
+- (void)adjustSubviews
+{
+	[super adjustSubviews];
+	[[self window] invalidateCursorRectsForView:self];
+}
+
+- (void)setCollapsibleSubviewCollapsedHelper:(NSNumber *)flag
+{
+	[self setCollapsibleSubviewCollapsed:[flag boolValue]];
+}
+
+- (void)animationEnded
+{
+	isAnimating = NO;
+}
+
+- (float)animationDuration
+{
+	if ([NSEvent shiftKeyIsDown])
+		return 2.0;
+	
+	return 0.25;
+}
+
+- (BOOL)hasCollapsibleDivider
+{
+	if ([self hasCollapsibleSubview] && (dividerCanCollapse || [self dividerThickness] < 1.01))
+		return YES;
+	
+	return NO;
+}
+
+- (int)collapsibleDividerIndex
+{
+	if ([self hasCollapsibleDivider])
+	{
+		if ([self collapsiblePopupSelection] == 1)
+			return 0;
+		else if ([self collapsiblePopupSelection] == 2)
+			return [self subviews].count - 2;
+	}
+	
+	return -1;
+}
+
+- (void)setCollapsibleSubviewCollapsed:(BOOL)flag
+{
+	collapsibleSubviewCollapsed = flag;
+
+	if (flag)
+		[[self toggleCollapseButton] setState:0];
+	else
+		[[self toggleCollapseButton] setState:1];	
+}
+
+- (void)setMinSizeForCollapsibleSubview:(NSNumber *)minSize
+{
+	if ([self hasCollapsibleSubview])
+	{
+		NSMutableDictionary *tempMinValues = [[self minValues] mutableCopy];
+		[tempMinValues setObject:minSize forKey:[NSNumber numberWithInt:[[self subviews] indexOfObject:[self collapsibleSubview]]]];
+		[self setMinValues:tempMinValues];
+	}
+}
+
+- (void)removeMinSizeForCollapsibleSubview
+{
+	if ([self hasCollapsibleSubview])
+	{
+		NSMutableDictionary *tempMinValues = [[self minValues] mutableCopy];
+		[tempMinValues removeObjectForKey:[NSNumber numberWithInt:[[self subviews] indexOfObject:[self collapsibleSubview]]]];
+		[self setMinValues:tempMinValues];
+	}
+}
+
+- (IBAction)toggleCollapse:(id)sender
+{
+	if ([self respondsToSelector:@selector(ibDidAddToDesignableDocument:)])
+		return;
+	
+	if ([self hasCollapsibleSubview] == NO || [self collapsibleSubview] == nil)
+		return;
+	
+	if (isAnimating)
+		return;
+	
+	
+	// Check to see if the collapsible subview has a minimum width/height and record it.
+	// We'll later remove the min size temporarily while animating and then restore it.
+	BOOL hasMinSize = NO;
+	NSNumber *minSize = [minValues objectForKey:[NSNumber numberWithInt:[[self subviews] indexOfObject:[self collapsibleSubview]]]];
+	minSize = [[minSize copy] autorelease];
+	
+	if (minSize != nil || [minSize intValue] != 0)
+		hasMinSize = YES;
+	
+	
+	// Get a reference to the button and modify its behavior
+	if ([self toggleCollapseButton] == nil)
+	{
+		[self setToggleCollapseButton:sender];
+
+		[[toggleCollapseButton cell] setHighlightsBy:NSPushInCellMask];
+		[[toggleCollapseButton cell] setShowsStateBy:NSContentsCellMask];
+	}
+	
+	
+	// Temporary: For simplicty, there should only be 1 subview other than the collapsible subview that's resizable for the collapse to happen
+	NSView *resizableSubview = nil;
+	
+	for (NSView *subview in [self subviews])
+	{
+		if ([self subviewIsResizable:subview] && subview != [self collapsibleSubview])
+		{
+			resizableSubview = subview;
+		}
+			
+	}
+	
+	if (resizableSubview == nil)
+		return;
+	
+	
+	// Get the thickness of the collapsible divider. If the divider cannot collapse, we set it to 0 so it doesn't affect our calculations.
+	float collapsibleDividerThickness = [self dividerThickness];
+	
+	if ([self hasCollapsibleDivider] == NO)
+		collapsibleDividerThickness = 0;
+	
+	
+	if ([self isVertical])
+	{
+		float constantHeight = [self collapsibleSubview].frame.size.height;
+		
+		if ([self collapsibleSubviewCollapsed] == NO)
+		{
+			uncollapsedSize = [self collapsibleSubview].frame.size.width;
+			
+			if (hasMinSize)
+				[self removeMinSizeForCollapsibleSubview];
+			
+			[NSAnimationContext beginGrouping];
+			[[NSAnimationContext currentContext] setDuration:([self animationDuration])];			
+			[[[self collapsibleSubview] animator] setFrameSize:NSMakeSize(0.0, constantHeight)];
+			[[resizableSubview animator] setFrameSize:NSMakeSize(resizableSubview.frame.size.width + uncollapsedSize + collapsibleDividerThickness, constantHeight)];
+			[NSAnimationContext endGrouping];
+			
+			if (hasMinSize)
+				[self performSelector:@selector(setMinSizeForCollapsibleSubview:) withObject:minSize afterDelay:[self animationDuration]];
+			
+			[self performSelector:@selector(setCollapsibleSubviewCollapsedHelper:) withObject:[NSNumber numberWithBool:YES] afterDelay:[self animationDuration]];
+		}
+		else
+		{
+			if (hasMinSize)
+				[self removeMinSizeForCollapsibleSubview];
+			
+			[NSAnimationContext beginGrouping];
+			[[NSAnimationContext currentContext] setDuration:([self animationDuration])];
+			[[[self collapsibleSubview] animator] setFrameSize:NSMakeSize(uncollapsedSize, constantHeight)];
+			[[resizableSubview animator] setFrameSize:NSMakeSize(resizableSubview.frame.size.width - uncollapsedSize - collapsibleDividerThickness, constantHeight)];
+			[NSAnimationContext endGrouping];
+	
+			if (hasMinSize)
+				[self performSelector:@selector(setMinSizeForCollapsibleSubview:) withObject:minSize afterDelay:[self animationDuration]];
+			
+			[self setCollapsibleSubviewCollapsed:NO];
+		}
+	}
+	else
+	{
+		float constantWidth = [self collapsibleSubview].frame.size.width;
+		
+		if ([self collapsibleSubviewCollapsed] == NO)
+		{
+			uncollapsedSize = [self collapsibleSubview].frame.size.height;
+			
+			if (hasMinSize)
+				[self removeMinSizeForCollapsibleSubview];
+			
+			[NSAnimationContext beginGrouping];
+			[[NSAnimationContext currentContext] setDuration:([self animationDuration])];			
+			[[[self collapsibleSubview] animator] setFrameSize:NSMakeSize(constantWidth, 0.0)];
+			[[resizableSubview animator] setFrameSize:NSMakeSize(constantWidth, resizableSubview.frame.size.height + uncollapsedSize + collapsibleDividerThickness)];
+			[NSAnimationContext endGrouping];
+			
+			if (hasMinSize)
+				[self performSelector:@selector(setMinSizeForCollapsibleSubview:) withObject:minSize afterDelay:[self animationDuration]];
+			
+			[self performSelector:@selector(setCollapsibleSubviewCollapsedHelper:) withObject:[NSNumber numberWithBool:YES] afterDelay:[self animationDuration]];
+		}
+		else
+		{
+			if (hasMinSize)
+				[self removeMinSizeForCollapsibleSubview];
+			
+			[NSAnimationContext beginGrouping];
+			[[NSAnimationContext currentContext] setDuration:([self animationDuration])];
+			[[[self collapsibleSubview] animator] setFrameSize:NSMakeSize(constantWidth, uncollapsedSize)];
+			[[resizableSubview animator] setFrameSize:NSMakeSize(constantWidth, resizableSubview.frame.size.height - uncollapsedSize - collapsibleDividerThickness)];
+			[NSAnimationContext endGrouping];
+			
+			if (hasMinSize)
+				[self performSelector:@selector(setMinSizeForCollapsibleSubview:) withObject:minSize afterDelay:[self animationDuration]];
+			
+			[self setCollapsibleSubviewCollapsed:NO];
+		}
+	}
+	
+	isAnimating = YES;
+	[self performSelector:@selector(animationEnded) withObject:nil afterDelay:[self animationDuration]];
+	
+	[self performSelector:@selector(resizeAndAdjustSubviews) withObject:nil afterDelay:[self animationDuration]];
+}
+
+#pragma mark NSSplitView Delegate Methods
+
+- (BOOL)splitView:(NSSplitView *)splitView shouldHideDividerAtIndex:(NSInteger)dividerIndex
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:shouldHideDividerAtIndex:)])
+		return [secondaryDelegate splitView:splitView shouldHideDividerAtIndex:dividerIndex];
+	
+	if ([self respondsToSelector:@selector(ibDidAddToDesignableDocument:)] == NO)
+	{
+		if ([self hasCollapsibleDivider] && [self collapsibleDividerIndex] == dividerIndex)
+		{
+			[self setDividerCanCollapse:YES];
+			return YES;
+		}
+	}
+
+	return NO;
+}
+
+- (NSRect)splitView:(NSSplitView *)splitView additionalEffectiveRectOfDividerAtIndex:(NSInteger)dividerIndex
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)])
+		return [secondaryDelegate splitView:splitView additionalEffectiveRectOfDividerAtIndex:dividerIndex];
+	
+	return NSZeroRect;
+}
+
+- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
+		return [secondaryDelegate splitView:sender canCollapseSubview:subview];
+	
+	int subviewIndex = [[self subviews] indexOfObject:subview];
+	
+	if ([self respondsToSelector:@selector(ibDidAddToDesignableDocument:)] == NO)
+	{
+		if ([self collapsiblePopupSelection] == 1 && subviewIndex == 0)
+			return YES;
+		else if ([self collapsiblePopupSelection] == 2 && subviewIndex == [[self subviews] count] - 1)
+			return YES;
+	}
+	
+	return NO;
+}
+
+- (BOOL)splitView:(NSSplitView *)splitView shouldCollapseSubview:(NSView *)subview forDoubleClickOnDividerAtIndex:(NSInteger)dividerIndex
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:shouldCollapseSubview:forDoubleClickOnDividerAtIndex:)])
+		return [secondaryDelegate splitView:splitView shouldCollapseSubview:subview forDoubleClickOnDividerAtIndex:dividerIndex];
+	
+	int subviewIndex = [[self subviews] indexOfObject:subview];
+	
+	if ([self respondsToSelector:@selector(ibDidAddToDesignableDocument:)] == NO)
+	{
+		if (([self collapsiblePopupSelection] == 1 && subviewIndex == 0 && dividerIndex == 0) ||
+			([self collapsiblePopupSelection] == 2 && subviewIndex == [[self subviews] count] - 1 && dividerIndex == [[splitView subviews] count] - 2))
+		{
+			[self setCollapsibleSubviewCollapsed:YES];
+			
+			// Cause the collapse ourselves by calling the resize method
+			[self resizeAndAdjustSubviews];
+			[self setNeedsDisplay:YES];
+			
+			// Since we manually did the resize above, we pretend that we don't want to collapse
+			return NO;
+		}
+	}
+	
+	return NO;
+}
+
+- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:constrainMaxCoordinate:ofSubviewAt:)])
+		return [secondaryDelegate splitView:sender constrainMaxCoordinate:proposedMax ofSubviewAt:offset];
+	
+	// Max coordinate depends on max of subview offset, and the min of subview offset + 1
+	CGFloat newMaxFromThisSubview = proposedMax;
+	CGFloat newMaxFromNextSubview = proposedMax;
+	
+	// Max from this subview
+	CGFloat maxValue = [self subviewMaximumSize:offset];
+	if (maxValue != FLT_MAX)
+	{
+		NSView *subview = [[self subviews] objectAtIndex:offset];
+		CGFloat originCoord = [self isVertical] ? [subview frame].origin.x : [subview frame].origin.y;
+		
+		newMaxFromThisSubview = originCoord + maxValue;
+	}
+	
+	// Max from the next subview
+	int nextOffset = offset + 1;
+	if ([[self subviews] count] > nextOffset)
+	{
+		CGFloat minValue = [self subviewMinimumSize:nextOffset];
+		if (minValue != 0)
+		{
+			NSView *subview = [[self subviews] objectAtIndex:nextOffset];
+			CGFloat endCoord = [self isVertical] ? [subview frame].origin.x + [subview frame].size.width : [subview frame].origin.y + [subview frame].size.height;
+			
+			newMaxFromNextSubview = endCoord - minValue - [self dividerThickness];
+			// This could cause trouble when over constrained (TODO)
+		}
+	}
+	
+	CGFloat newMax = fminf(newMaxFromThisSubview, newMaxFromNextSubview);
+	
+	if (newMax < proposedMax)
+		return newMax;
+	
+	return proposedMax;
+}
+
+- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)offset
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:constrainMinCoordinate:ofSubviewAt:)])
+		return [secondaryDelegate splitView:sender constrainMinCoordinate:proposedMin ofSubviewAt:offset];
+	
+	// Min coordinate depends on min of subview offset and the max of subview offset + 1
+	CGFloat newMinFromThisSubview = proposedMin;
+	CGFloat newMaxFromNextSubview = proposedMin;
+	
+	// Min from this subview
+	CGFloat minValue = [self subviewMinimumSize:offset];
+	if (minValue != 0)
+	{
+		NSView *subview = [[self subviews] objectAtIndex:offset];
+		CGFloat originCoord = [self isVertical] ? [subview frame].origin.x : [subview frame].origin.y;
+		
+		newMinFromThisSubview = originCoord + minValue;
+	}
+	
+	// Min from the next subview
+	int nextOffset = offset + 1;
+	if ([[self subviews] count] > nextOffset)
+	{
+		CGFloat maxValue = [self subviewMaximumSize:nextOffset];
+		if (maxValue != FLT_MAX)
+		{
+			NSView *subview = [[self subviews] objectAtIndex:nextOffset];
+			CGFloat endCoord = [self isVertical] ? [subview frame].origin.x + [subview frame].size.width : [subview frame].origin.y + [subview frame].size.height;
+			
+			newMaxFromNextSubview = endCoord - maxValue - [self dividerThickness];
+			// This could cause trouble when over constrained (TODO)
+		}
+	}
+	
+	CGFloat newMin = fmaxf(newMinFromThisSubview, newMaxFromNextSubview);
+	
+	if (newMin > proposedMin)
+		return newMin;
+	
+	return proposedMin;
+}
+
+- (CGFloat)splitView:(NSSplitView *)sender constrainSplitPosition:(CGFloat)proposedPosition ofSubviewAt:(NSInteger)offset
+{
+	[self clearPreferredProportionsAndSizes];
+	
+	if ([self respondsToSelector:@selector(ibDidAddToDesignableDocument:)])
+		return proposedPosition;	
+	
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
+		return [secondaryDelegate splitView:sender constrainSplitPosition:proposedPosition ofSubviewAt:offset];
+	
+	return proposedPosition;
+}
+
+- (NSRect)splitView:(NSSplitView *)splitView effectiveRect:(NSRect)proposedEffectiveRect forDrawnRect:(NSRect)drawnRect ofDividerAtIndex:(NSInteger)dividerIndex
+{
+	if ([secondaryDelegate respondsToSelector:@selector(splitView:effectiveRect:forDrawnRect:ofDividerAtIndex:)])
+		return [secondaryDelegate splitView:splitView effectiveRect:proposedEffectiveRect forDrawnRect:drawnRect ofDividerAtIndex:dividerIndex];
+	
+	return proposedEffectiveRect;
+}
+
+- (void)splitViewDidResizeSubviews:(NSNotification *)aNotification
+{
+	if (collapsibleSubviewCollapsed && ([self isVertical] ? [[self collapsibleSubview] frame].size.width > 0 : [[self collapsibleSubview] frame].size.height > 0))
+	{
+		[self setCollapsibleSubviewCollapsed:NO];
+
+		[self resizeAndAdjustSubviews];
+	}
+	else if (!collapsibleSubviewCollapsed && ([self isVertical] ? [[self collapsibleSubview] frame].size.width < 0.1 : [[self collapsibleSubview] frame].size.height < 0.1))
+	{
+		[self setCollapsibleSubviewCollapsed:YES];
+
+		[self resizeAndAdjustSubviews];
+	}
+	else if ([self collapsibleSubviewIsCollapsed])
+	{
+		[self resizeAndAdjustSubviews];
+	}
+	
+	[self setNeedsDisplay:YES];
+}
+
+#pragma mark - Resize Subviews Delegate Method and Helper Methods
+
+- (int)resizableSubviews
+{
+	int resizableSubviews = 0;
+	
+	for (NSView *subview in [self subviews])
+	{
+		if ([self subviewIsResizable:subview])
+			resizableSubviews++;
+	}
+	
+	return resizableSubviews;
+}
+
+- (BOOL)subviewIsResizable:(NSView *)subview
+{
+	if ([self isVertical] && [subview autoresizingMask] & NSViewWidthSizable)
+		return YES;
+	
+	if (![self isVertical] && [subview autoresizingMask] & NSViewHeightSizable)
+		return YES;
+	
+	return NO;
+}
+
+- (CGFloat)subviewMinimumSize:(int)subviewIndex;
+{
+	NSNumber *minNum = [minValues objectForKey:[NSNumber numberWithInt:subviewIndex]];
+	if (!minNum)
+		return 0;
+	
+	int units = 0;
+	NSNumber *unitsNum = [minUnits objectForKey:[NSNumber numberWithInt:subviewIndex]];
+	if (unitsNum)
+		units = [unitsNum intValue];
+	
+	CGFloat min = [minNum floatValue];
+	
+	switch (units)
+	{
+		case 1:
+		{
+			// Percent
+			CGFloat dividerThicknessTotal = [self dividerThickness] * ([[self subviews] count] - 1);
+			CGFloat totalSize = [self isVertical] ? [self frame].size.width : [self frame].size.height;
+			totalSize -= dividerThicknessTotal;
+			
+			return roundf((min / 100.0) * totalSize);
+			break;
+		}
+		case 0:
+		default:
+		{
+			// Points
+			return min;
+			break;
+		}
+	}
+}
+
+- (CGFloat)subviewMaximumSize:(int)subviewIndex;
+{
+	NSNumber *maxNum = [maxValues objectForKey:[NSNumber numberWithInt:subviewIndex]];
+	if (!maxNum)
+		return FLT_MAX;
+	
+	int units = 0;
+	NSNumber *unitsNum = [maxUnits objectForKey:[NSNumber numberWithInt:subviewIndex]];
+	if (unitsNum)
+		units = [unitsNum intValue];
+	
+	CGFloat max = [maxNum floatValue];
+	
+	switch (units)
+	{
+		case 1:
+		{
+			// Percent
+			CGFloat dividerThicknessTotal = [self dividerThickness] * ([[self subviews] count] - 1);
+			CGFloat totalSize = [self isVertical] ? [self frame].size.width : [self frame].size.height;
+			totalSize -= dividerThicknessTotal;
+			
+			return roundf((max / 100.0) * totalSize);
+			break;
+		}
+		case 0:
+		default:
+		{
+			// Points
+			return max;
+			break;
+		}
+	}
+}
+
+// PREFERRED PROPORTIONS AND SIZES
+//
+// Preferred proportions (for resizable)
+// Need to store resizable subviews preferred proportions for calculating new sizes
+//
+// Preferred sizes (for non-resizable)
+// If a non-resizable subview is ever forced larger or smaller than it prefers, we need to know it's preferred size
+//
+// Need to recalculate both of the above whenever a divider is moved, or a subview is added/removed or changed between resizable/non-resizable
+
+- (void)recalculatePreferredProportionsAndSizes;
+{
+	NSMutableArray *stateArray = [NSMutableArray arrayWithCapacity:[[self subviews] count]];
+	
+	NSMutableDictionary *preferredProportions = [NSMutableDictionary dictionary];
+	NSMutableDictionary *preferredSizes = [NSMutableDictionary dictionary];
+	
+	// Total is only the sum of resizable subviews
+	CGFloat resizableTotal = 0;
+	
+	// Calculate resizable total
+	for (NSView *subview in [self subviews])
+	{
+		if ([self subviewIsResizable:subview])
+			resizableTotal += [self isVertical] ? [subview frame].size.width : [subview frame].size.height;
+	}
+	
+	// Calculate resizable preferred propotions and set non-resizable preferred sizes
+	for (NSView *subview in [self subviews])
+	{
+		int index = [[self subviews] indexOfObject:subview];
+		
+		if ([self subviewIsResizable:subview])
+		{
+			CGFloat size = [self isVertical] ? [subview frame].size.width : [subview frame].size.height;
+			CGFloat proportion = (resizableTotal > 0) ? (size / resizableTotal) : 0;
+			
+			[preferredProportions setObject:[NSNumber numberWithFloat:proportion]
+									 forKey:[NSNumber numberWithInt:index]];
+			
+			[stateArray addObject:[NSNumber numberWithBool:YES]];
+		}
+		else
+		{
+			CGFloat size = [self isVertical] ? [subview frame].size.width : [subview frame].size.height;
+			
+			[preferredSizes setObject:[NSNumber numberWithFloat:size]
+							   forKey:[NSNumber numberWithInt:index]];
+			
+			[stateArray addObject:[NSNumber numberWithBool:NO]];
+		}
+	}
+	
+	[self setResizableSubviewPreferredProportion:preferredProportions];
+	[self setNonresizableSubviewPreferredSize:preferredSizes];
+	
+	if (RESIZE_DEBUG_LOGS) NSLog(@"resizableSubviewPreferredProportion: %@", resizableSubviewPreferredProportion);
+	if (RESIZE_DEBUG_LOGS) NSLog(@"nonresizableSubviewPreferredSize: %@", nonresizableSubviewPreferredSize);
+	
+	// Remember state to know when to recalculate	
+	[self setStateForLastPreferredCalculations:stateArray];
+	if (RESIZE_DEBUG_LOGS) NSLog(@"stateForLastPreferredCalculations: %@", stateForLastPreferredCalculations);
+}
+
+// Checks if the number or type of subviews has changed since we last recalculated
+- (BOOL)validatePreferredProportionsAndSizes;
+{
+	if (RESIZE_DEBUG_LOGS) NSLog(@"validating preferred proportions and sizes");
+	
+	// Check if we even have saved proportions and sizes
+	if (![self resizableSubviewPreferredProportion] || ![self nonresizableSubviewPreferredSize])
+		return NO;
+	
+	// Check if number of items has changed
+	if ([[self subviews] count] != [[self stateForLastPreferredCalculations] count])
+		return NO;
+	
+	// Check if any of the subviews have changed between resizable and non-resizable
+	for (NSView *subview in [self subviews])
+	{
+		int index = [[self subviews] indexOfObject:subview];
+		
+		if ([self subviewIsResizable:subview] != [[[self stateForLastPreferredCalculations] objectAtIndex:index] boolValue])
+			return NO;
+	}
+	
+	return YES;
+}
+
+- (void)correctCollapsiblePreferredProportionOrSize;
+{
+	// TODO: Assuming that the collapsible subview does not change between resizable and non-resizable while collapsed
+	
+	if (![self hasCollapsibleSubview])
+		return;
+	
+	NSMutableDictionary *preferredProportions = [[self resizableSubviewPreferredProportion] mutableCopy];
+	NSMutableDictionary *preferredSizes = [[self nonresizableSubviewPreferredSize] mutableCopy];
+	
+	NSNumber *key = [NSNumber numberWithInt:[self collapsibleSubviewIndex]];
+	NSView *subview = [self collapsibleSubview];
+	
+	// If the collapsible subview is collapsed, we put aside its preferred propotion/size
+	if ([self subviewIsCollapsed:subview])
+	{
+		BOOL resizable = [self subviewIsResizable:subview];
+		
+		if (!resizable)
+		{
+			NSNumber *sizeNum = [preferredSizes objectForKey:key];
+			if (sizeNum)
+			{
+				if (RESIZE_DEBUG_LOGS) NSLog(@"removing collapsible view from preferred sizes");
+				
+				// TODO: Save the size for later
+				
+				// Remove from preferred sizes
+				[preferredSizes removeObjectForKey:key];
+			}
+		}
+		else
+		{
+			NSNumber *proportionNum = [preferredProportions objectForKey:key];
+			if (proportionNum)
+			{
+				if (RESIZE_DEBUG_LOGS) NSLog(@"removing collapsible view from preferred proportions");
+				
+				CGFloat proportion = [proportionNum floatValue];
+				
+				// TODO: Save the proportion for later
+				
+				// Remove from preferred proportions
+				[preferredProportions removeObjectForKey:key];
+				
+				// Recalculate other proportions
+				CGFloat proportionTotal = 1.0 - proportion;
+				if (proportionTotal > 0)
+				{
+					for (NSNumber *pkey in [preferredProportions allKeys])
+					{
+						CGFloat oldProportion = [[preferredProportions objectForKey:pkey] floatValue];
+						CGFloat newPropotion = oldProportion / proportionTotal;
+						
+						[preferredProportions setObject:[NSNumber numberWithFloat:newPropotion] forKey:pkey];
+					}
+				}
+			}
+		}
+		
+		[self setResizableSubviewPreferredProportion:preferredProportions];
+		[self setNonresizableSubviewPreferredSize:preferredSizes];
+	}
+	else // Otherwise, we reintegrate its preferred proportion/size
+	{
+		[self clearPreferredProportionsAndSizes];
+		[self recalculatePreferredProportionsAndSizes];
+	}
+}
+
+- (void)validateAndCalculatePreferredProportionsAndSizes;
+{
+	if (![self validatePreferredProportionsAndSizes])
+		[self recalculatePreferredProportionsAndSizes];		
+	
+	// Need to make sure the collapsed subviews preferred size/proportion is in the right place
+	[self correctCollapsiblePreferredProportionOrSize];
+}
+
+
+- (void)clearPreferredProportionsAndSizes;
+{
+	if (RESIZE_DEBUG_LOGS) NSLog(@"clearing preferred proportions and sizes");
+	
+	[self setResizableSubviewPreferredProportion:nil];
+	[self setNonresizableSubviewPreferredSize:nil];
+}
+
+// RESIZING ALGORITHM
+
+// non-resizable subviews are given preferred size
+// overall remaining size is calculated
+// resizable subviews are calculated based on remaining size and preferred proportions
+// resizable subviews are checked for min/max constraint violations
+//    if violating constraint, set to valid size and remove from resizable subviews
+//    recalculate other resizable subviews and repeat
+// if all resizable subviews reached constraints without meeting target size, need to resize non-resizable views
+// non-resizable subviews are adjusted proportionally to meet target size
+// non-resizable subviews are checked for min/max constraint violations
+//    if violating constraint, set to valid size and remove from non-resizable subviews
+//    recalculate other non-resizable subviews and repeat
+// if all subviews reached constraints without meeting target size, need to adjust all views to fit
+// proportionally resize all subviews to fit in target size, ignoring min/max constraints
+
+- (void)resizeAndAdjustSubviews;
+{
+	// Temporary: for now, we will just remember the proportions the first time subviews are resized
+	// we should be remember them in the user defaults so they save across quits (TODO)
+	
+	[self validateAndCalculatePreferredProportionsAndSizes];
+	
+	if (RESIZE_DEBUG_LOGS) NSLog(@"resizeSubviews begins -----------------------------------------------------");
+	
+	NSMutableDictionary *newSubviewSizes = [NSMutableDictionary dictionaryWithCapacity:[[self subviews] count]];
+	
+	// Get new total size
+	CGFloat totalAvailableSize = [self isVertical] ? [self frame].size.width : [self frame].size.height;
+	if (RESIZE_DEBUG_LOGS) NSLog(@"totalAvailableSize: %f", totalAvailableSize);
+	
+	// Calculate non-resizable subviews total
+	CGFloat nonresizableSubviewsTotalPreferredSize = 0;
+	for (NSNumber *size in [nonresizableSubviewPreferredSize allValues])
+		nonresizableSubviewsTotalPreferredSize += [size floatValue];
+	if (RESIZE_DEBUG_LOGS) NSLog(@"nonresizableSubviewsTotalPreferredSize: %f", nonresizableSubviewsTotalPreferredSize);
+	
+	// Calculate divider thickness total
+	int dividerCount = [[self subviews] count] - 1;
+	if ([self collapsibleSubviewIsCollapsed] && dividerCanCollapse) dividerCount--;
+	CGFloat dividerThicknessTotal = [self dividerThickness] * dividerCount;		
+	if (RESIZE_DEBUG_LOGS) NSLog(@"dividerThicknessTotal: %f", dividerThicknessTotal);
+	
+	// Calculate overall remaining size (could be negative)
+	CGFloat resizableSubviewsTotalAvailableSize = totalAvailableSize - nonresizableSubviewsTotalPreferredSize - dividerThicknessTotal;
+	if (RESIZE_DEBUG_LOGS) NSLog(@"resizableSubviewsTotalAvailableSize: %f", resizableSubviewsTotalAvailableSize);
+	
+	// Special case for the collapsible subview
+	if ([self collapsibleSubviewIsCollapsed])
+	{
+		[newSubviewSizes setObject:[NSNumber numberWithFloat:0.0]
+							forKey:[NSNumber numberWithInt:[self collapsibleSubviewIndex]]];
+	}
+	
+	// Set non-resizable subviews to preferred size
+	[newSubviewSizes addEntriesFromDictionary:nonresizableSubviewPreferredSize];
+	
+	// Set sizes of resizable views based on proportions (could be negative)
+	CGFloat resizableSubviewAvailableSizeUsed = 0;
+	int resizableSubviewCounter = 0;
+	int resizableSubviewCount = [resizableSubviewPreferredProportion count];
+	for (NSNumber *key in [resizableSubviewPreferredProportion allKeys])
+	{
+		resizableSubviewCounter++;
+		
+		CGFloat proportion = [[resizableSubviewPreferredProportion objectForKey:key] floatValue];
+		CGFloat size = roundf(proportion * resizableSubviewsTotalAvailableSize);
+		resizableSubviewAvailableSizeUsed += size;
+		
+		if (resizableSubviewCounter == resizableSubviewCount)
+		{
+			// Make adjustment if necessary
+			size += (resizableSubviewsTotalAvailableSize - resizableSubviewAvailableSizeUsed);
+		}
+		
+		[newSubviewSizes setObject:[NSNumber numberWithFloat:size] forKey:key];
+	}
+	if (RESIZE_DEBUG_LOGS) NSLog(@"newSubviewSizes after resizable proportional resizing: %@", newSubviewSizes);
+	
+	// TODO: Could add a special case for resizableSubviewsTotalAvailableSize <= 0 : just set all resizable subviews to minimum size 
+	
+	// Make array of all the resizable subviews indexes
+	NSMutableArray *resizableSubviewIndexes = [[resizableSubviewPreferredProportion allKeys] mutableCopy];
+	[resizableSubviewIndexes sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES] autorelease]]];
+	
+	// Loop until none of the resizable subviews' constraints are violated
+	CGFloat proportionTotal = 1;
+	CGFloat resizableSubviewsRemainingAvailableSize = resizableSubviewsTotalAvailableSize;
+	int i;
+	for (i = 0; i < [resizableSubviewIndexes count]; i++)
+	{
+		NSNumber *key = [resizableSubviewIndexes objectAtIndex:i];
+		CGFloat size = [[newSubviewSizes objectForKey:key] floatValue];
+		CGFloat minSize = [self subviewMinimumSize:[key intValue]];
+		CGFloat maxSize = [self subviewMaximumSize:[key intValue]];
+		
+		BOOL overMax = size > maxSize;
+		BOOL underMin = size < minSize;
+		
+		// Check if current item in array violates constraints
+		if (underMin || overMax)
+		{
+			CGFloat constrainedSize = underMin ? minSize : maxSize;
+			
+			if (RESIZE_DEBUG_LOGS) NSLog(@"resizable subview %@ was %@, set to %f", key, (underMin ? @"under min" : @"over max"), constrainedSize);
+			
+			// Give subview constrained size and remove from array
+			[newSubviewSizes setObject:[NSNumber numberWithFloat:constrainedSize] forKey:key];
+			[resizableSubviewIndexes removeObject:key];
+			
+			// Adjust total proportion and remaining available size
+			proportionTotal -= [[resizableSubviewPreferredProportion objectForKey:key] floatValue];
+			resizableSubviewsRemainingAvailableSize -= underMin ? minSize : maxSize;
+			
+			// Recalculate remaining subview sizes
+			CGFloat resizableSubviewRemainingSizeUsed = 0;
+			int j;
+			for (j = 0; j < [resizableSubviewIndexes count]; j++)
+			{
+				NSNumber *jKey = [resizableSubviewIndexes objectAtIndex:j];
+				
+				CGFloat proportion = 0;
+				if (proportionTotal > 0)
+					proportion = [[resizableSubviewPreferredProportion objectForKey:jKey] floatValue] / proportionTotal;
+				else
+					proportion = 1.0 / [resizableSubviewIndexes count];
+				
+				CGFloat size = roundf(proportion * resizableSubviewsRemainingAvailableSize);
+				resizableSubviewRemainingSizeUsed += size;
+				
+				if (j == [resizableSubviewIndexes count] - 1)
+				{
+					// Make adjustment if necessary
+					size += (resizableSubviewsRemainingAvailableSize - resizableSubviewRemainingSizeUsed);
+				}
+				
+				[newSubviewSizes setObject:[NSNumber numberWithFloat:size] forKey:jKey];
+				
+				// Reset outer loop to start from beginning
+				i = -1;
+			}
+		}
+	}
+	if (RESIZE_DEBUG_LOGS) NSLog(@"newSubviewSizes after resizable constraint fulfilling: %@", newSubviewSizes);		
+	
+	if ([resizableSubviewIndexes count] == 0 && resizableSubviewsRemainingAvailableSize != 0)
+	{
+		if (RESIZE_DEBUG_LOGS) NSLog(@"entering nonresizable adjustment stage");
+		
+		// All resizable subviews have reached constraints without reaching the target size
+		
+		// First try to adjust non-resizable subviews, with resizableSubviewsRemainingAvailableSize being the amount of adjustment needed
+		
+		// Make array of non-resizable preferred proportions (normally go by preferred sizes)
+		NSMutableDictionary *nonresizableSubviewPreferredProportion = [NSMutableDictionary dictionary];
+		for (NSNumber *key in [nonresizableSubviewPreferredSize allKeys])
+		{
+			CGFloat proportion = [[nonresizableSubviewPreferredSize objectForKey:key] floatValue] / nonresizableSubviewsTotalPreferredSize;
+			
+			[nonresizableSubviewPreferredProportion setObject:[NSNumber numberWithFloat:proportion] forKey:key];
+		}
+		
+		// ResizableSubviewsRemainingAvailableSize is the amount of adjustment needed
+		CGFloat nonresizableSubviewsRemainingAvailableSize = nonresizableSubviewsTotalPreferredSize + resizableSubviewsRemainingAvailableSize;
+		
+		// Set sizes of nonresizable views based on proportions (could be negative)
+		CGFloat nonresizableSubviewAvailableSizeUsed = 0;
+		int nonresizableSubviewCounter = 0;
+		int nonresizableSubviewCount = [nonresizableSubviewPreferredProportion count];
+		for (NSNumber *key in [nonresizableSubviewPreferredProportion allKeys])
+		{
+			nonresizableSubviewCounter++;
+			
+			CGFloat proportion = [[nonresizableSubviewPreferredProportion objectForKey:key] floatValue];
+			CGFloat size = roundf(proportion * nonresizableSubviewsRemainingAvailableSize);
+			nonresizableSubviewAvailableSizeUsed += size;
+			
+			if (nonresizableSubviewCounter == nonresizableSubviewCount)
+			{
+				// Make adjustment if necessary
+				size += (nonresizableSubviewsRemainingAvailableSize - nonresizableSubviewAvailableSizeUsed);
+			}
+			
+			[newSubviewSizes setObject:[NSNumber numberWithFloat:size] forKey:key];
+		}
+		if (RESIZE_DEBUG_LOGS) NSLog(@"newSubviewSizes after nonresizable proportional resizing: %@", newSubviewSizes);
+		
+		// Make array of all the non-resizable subviews indexes
+		NSMutableArray *nonresizableSubviewIndexes = [[nonresizableSubviewPreferredSize allKeys] mutableCopy];
+		[nonresizableSubviewIndexes sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES] autorelease]]];
+		
+		// Loop until none of the non-resizable subviews' constraints are violated
+		CGFloat proportionTotal = 1;
+		int i;
+		for (i = 0; i < [nonresizableSubviewIndexes count]; i++)
+		{
+			NSNumber *key = [nonresizableSubviewIndexes objectAtIndex:i];
+			CGFloat size = [[newSubviewSizes objectForKey:key] floatValue];
+			CGFloat minSize = [self subviewMinimumSize:[key intValue]];
+			CGFloat maxSize = [self subviewMaximumSize:[key intValue]];
+			
+			BOOL overMax = size > maxSize;
+			BOOL underMin = size < minSize;
+			
+			// Check if current item in array violates constraints
+			if (underMin || overMax)
+			{
+				CGFloat constrainedSize = underMin ? minSize : maxSize;
+				
+				if (RESIZE_DEBUG_LOGS) NSLog(@"nonresizable subview %@ was %@, set to %f", key, (underMin ? @"under min" : @"over max"), constrainedSize);
+				
+				// Give subview constrained size and remove from array
+				[newSubviewSizes setObject:[NSNumber numberWithFloat:constrainedSize] forKey:key];
+				[nonresizableSubviewIndexes removeObject:key];
+				
+				// Adjust total proportion and remaining available size
+				proportionTotal -= [[nonresizableSubviewPreferredProportion objectForKey:key] floatValue];
+				nonresizableSubviewsRemainingAvailableSize -= underMin ? minSize : maxSize;
+				
+				// Recalculate remaining subview sizes
+				CGFloat nonresizableSubviewRemainingSizeUsed = 0;
+				int j;
+				for (j = 0; j < [nonresizableSubviewIndexes count]; j++)
+				{
+					NSNumber *jKey = [nonresizableSubviewIndexes objectAtIndex:j];
+					
+					CGFloat proportion = 0;
+					if (proportionTotal > 0)
+						proportion = [[nonresizableSubviewPreferredProportion objectForKey:jKey] floatValue] / proportionTotal;
+					else
+						proportion = 1.0 / [nonresizableSubviewIndexes count];
+					
+					CGFloat size = roundf(proportion * nonresizableSubviewsRemainingAvailableSize);
+					nonresizableSubviewRemainingSizeUsed += size;
+					
+					if (j == [nonresizableSubviewIndexes count] - 1)
+					{
+						// Make adjustment if necessary
+						size += (nonresizableSubviewsRemainingAvailableSize - nonresizableSubviewRemainingSizeUsed);
+					}
+					
+					[newSubviewSizes setObject:[NSNumber numberWithFloat:size] forKey:jKey];
+					
+					// Reset outer loop to start from beginning
+					i = -1;
+				}
+			}
+		}
+		if (RESIZE_DEBUG_LOGS) NSLog(@"newSubviewSizes after nonresizable constraint fulfilling: %@", newSubviewSizes);
+		
+		// If there is still overall violation, resize everything proportionally to make up the difference
+		
+		if ([resizableSubviewIndexes count] == 0 && nonresizableSubviewsRemainingAvailableSize != 0)
+		{
+			if (RESIZE_DEBUG_LOGS) NSLog(@"entering all subviews forced adjustment stage");
+			
+			// Calculate current proportions and use to calculate new size
+			
+			CGFloat allSubviewTotalCurrentSize = 0;
+			for (NSNumber *size in [newSubviewSizes allValues])
+				allSubviewTotalCurrentSize += [size floatValue];
+			
+			CGFloat allSubviewRemainingSizeUsed = 0;
+			CGFloat allSubviewTotalSize = totalAvailableSize - dividerThicknessTotal;
+			// TODO: What to do if even the dividers don't fit?				
+			
+			int k;
+			for (k = 0; k < [newSubviewSizes count]; k++)
+			{
+				NSNumber *key = [NSNumber numberWithInt:k];
+				
+				CGFloat currentSize = [[newSubviewSizes objectForKey:key] floatValue];
+				
+				CGFloat proportion = currentSize / allSubviewTotalCurrentSize;
+				CGFloat size = roundf(proportion * allSubviewTotalSize);
+				allSubviewRemainingSizeUsed += size;
+				
+				if (k == [newSubviewSizes count] - 1)
+				{
+					// Make adjustment if necessary
+					size += allSubviewTotalSize - allSubviewRemainingSizeUsed;
+				}
+				
+				[newSubviewSizes setObject:[NSNumber numberWithFloat:size] forKey:key];	
+			}
+			if (RESIZE_DEBUG_LOGS) NSLog(@"newSubviewSizes after all subviews forced adjustment: %@", newSubviewSizes);
+		}
+		
+		// Otherwise there is still flexibiliy in the non-resizable views, so we are done
+	}
+	
+	// Otherwise there is still flexibility in the resizable views, so we are done
+	
+	// Set subview frames
+	CGFloat position = 0;
+	for (i = 0; i < [[self subviews] count]; i++)
+	{
+		NSView *subview = [[self subviews] objectAtIndex:i];
+		CGFloat size = [[newSubviewSizes objectForKey:[NSNumber numberWithInt:i]] floatValue];
+		
+		NSRect subviewFrame = NSZeroRect;
+		
+		if ([self isVertical])
+		{
+			subviewFrame.size.height = [self frame].size.height;
+			subviewFrame.size.width = size;
+			subviewFrame.origin.y = [subview frame].origin.y;
+			subviewFrame.origin.x = position;
+		}
+		else
+		{
+			subviewFrame.size.height = size;
+			subviewFrame.size.width =  [self frame].size.width;
+			subviewFrame.origin.y = position;
+			subviewFrame.origin.x =  [subview frame].origin.x;
+		}
+		
+		[subview setFrame:subviewFrame];
+		
+		position += size;
+		
+		if (dividerCanCollapse && [self subviewIsCollapsed:subview])
+		{
+			// Do nothing
+		}
+		else
+		{
+			position += [self dividerThickness];
+		}
+	}
+}
+
+- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize
+{
+	if ([secondaryDelegate isKindOfClass:NSClassFromString(@"BWAnchoredButtonBar")])
+	{
+		[self resizeAndAdjustSubviews];
+	}
+	else if ([secondaryDelegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
+	{
+		[secondaryDelegate splitView:sender resizeSubviewsWithOldSize:oldSize];
+	}
+	else if (sender == self)
+	{
+		[self resizeAndAdjustSubviews];
+	}
+	else
+	{
+		[sender adjustSubviews];
+	}
+}
+
 #pragma mark Force Vertical Splitters to Thin Appearance
 
-// This class doesn't have an appearance for wide vertical splitters, so we force all vertical splitters to thin by overriding a private method and a public one
+// This class doesn't have an appearance for wide vertical splitters, so we force all vertical splitters to thin.
+// We also post notifications that are used by the inspector to show & hide controls.
+
 - (void)setDividerStyle:(int)aStyle
 {
+	BOOL styleChanged = NO;
+	
+	if (aStyle != [self dividerStyle])
+		styleChanged = YES;
+	
 	if ([self isVertical])
-		[super setDividerStyle:2];
+		[super setDividerStyle:NSSplitViewDividerStyleThin];
 	else
 		[super setDividerStyle:aStyle];
+	
+	// There can be sizing issues during design-time if we don't call this
+	[self adjustSubviews];
+	
+	if (styleChanged)
+		[[NSNotificationCenter defaultCenter] postNotificationName:@"BWSplitViewDividerThicknessChanged" object:self];
 }
 
 - (void)setVertical:(BOOL)flag
 {
+	BOOL orientationChanged = NO;
+	
+	if (flag != [self isVertical])
+		orientationChanged = YES;
+		
 	if (flag)
-		[super setDividerStyle:2];
+		[super setDividerStyle:NSSplitViewDividerStyleThin];
 	
 	[super setVertical:flag];
+	
+	if (orientationChanged)
+		[[NSNotificationCenter defaultCenter] postNotificationName:@"BWSplitViewOrientationChanged" object:self];		
 }
 
 #pragma mark IB Inspector Support Methods
 	[self setNeedsDisplay:YES];
 }
 
+- (NSColor *)color
+{
+	if (color == nil)
+		color = [[NSColor blackColor] retain];
+	
+    return [[color retain] autorelease]; 
+}
+
+- (NSMutableDictionary *)minValues
+{
+	if (minValues == nil)
+		minValues = [NSMutableDictionary new];
+	
+    return [[minValues retain] autorelease]; 
+}
+
+- (NSMutableDictionary *)maxValues
+{
+	if (maxValues == nil)
+		maxValues = [NSMutableDictionary new];
+	
+    return [[maxValues retain] autorelease]; 
+}
+
+- (NSMutableDictionary *)minUnits
+{
+	if (minUnits == nil)
+		minUnits = [NSMutableDictionary new];
+	
+    return [[minUnits retain] autorelease]; 
+}
+
+- (NSMutableDictionary *)maxUnits
+{
+	if (maxUnits == nil)
+		maxUnits = [NSMutableDictionary new];
+	
+    return [[maxUnits retain] autorelease]; 
+}
+
 - (void)dealloc
 {
 	[color release];
+	[minValues release];
+	[maxValues release];
+	[minUnits release];
+	[maxUnits release];
+	[resizableSubviewPreferredProportion release];
+	[nonresizableSubviewPreferredSize release];
+	[toggleCollapseButton release];
+	[stateForLastPreferredCalculations release];
+		
 	[super dealloc];
 }
 

File BWSplitViewInspector.h

 //
 
 #import <InterfaceBuilderKit/InterfaceBuilderKit.h>
+#import "BWSplitView.h"
+#import "BWSplitViewInspectorAutosizingView.h"
 
-@interface BWSplitViewInspector : IBInspector {
+@interface BWSplitViewInspector : IBInspector 
+{
+	IBOutlet NSTextField *maxField, *minField, *maxLabel, *minLabel;
+	IBOutlet NSButton *dividerCheckbox;
+	IBOutlet BWSplitViewInspectorAutosizingView *autosizingView;
+	
+	int subviewPopupSelection, collapsiblePopupSelection, minUnitPopupSelection, maxUnitPopupSelection;
+	NSMutableArray *subviewPopupContent, *collapsiblePopupContent;
+	
+	BWSplitView *splitView;
+	BOOL dividerCheckboxCollapsed;
 }
+
+@property int subviewPopupSelection, collapsiblePopupSelection, minUnitPopupSelection, maxUnitPopupSelection;
+@property (copy) NSMutableArray *subviewPopupContent, *collapsiblePopupContent;
+@property (retain) BWSplitView *splitView;
+@property BOOL dividerCheckboxCollapsed;
+
 @end

File BWSplitViewInspector.m

 //
 
 #import "BWSplitViewInspector.h"
+#import "NSView+BWAdditions.h"
+
+@interface BWSplitViewInspector (BWSVIPrivate)
+- (void)updateControls;
+- (BOOL)toggleDividerCheckboxVisibilityWithAnimation:(BOOL)shouldAnimate;
+- (void)updateSizeLabels;
+@end
 
 @implementation BWSplitViewInspector
 
-- (NSString *)viewNibName {
+@synthesize subviewPopupSelection, subviewPopupContent, collapsiblePopupSelection, collapsiblePopupContent, minUnitPopupSelection, maxUnitPopupSelection, splitView, dividerCheckboxCollapsed;
+
+- (NSString *)viewNibName 
+{
     return @"BWSplitViewInspector";
 }
 
-- (void)refresh {
-	// Synchronize your inspector's content view with the currently selected objects
+- (void)awakeFromNib
+{
+	[minField setDelegate:self];
+	[maxField setDelegate:self];
+	
+	[[NSNotificationCenter defaultCenter] addObserver:self 
+											 selector:@selector(dividerThicknessChanged:)
+												 name:@"BWSplitViewDividerThicknessChanged"
+											   object:splitView];
+	
+	[[NSNotificationCenter defaultCenter] addObserver:self 
+											 selector:@selector(orientationChanged:)
+												 name:@"BWSplitViewOrientationChanged"
+											   object:splitView];
+}
+
+- (void)dividerThicknessChanged:(NSNotification *)notification
+{
+	[self toggleDividerCheckboxVisibilityWithAnimation:YES];
+}
+
+- (void)updateSizeLabels
+{
+	if ([splitView isVertical])
+	{
+		[maxLabel setStringValue:@"Max Width"];
+		[minLabel setStringValue:@"Min Width"];
+	}
+	else
+	{
+		[maxLabel setStringValue:@"Max Height"];
+		[minLabel setStringValue:@"Min Height"];
+	}
+}
+
+- (void)orientationChanged:(NSNotification *)notification
+{
+	[self updateSizeLabels];
+	[self toggleDividerCheckboxVisibilityWithAnimation:YES];
+}
+
+- (void)setCollapsiblePopupSelection:(int)index
+{
+	collapsiblePopupSelection = index;
+	
+	[splitView setCollapsiblePopupSelection:index];
+	[self toggleDividerCheckboxVisibilityWithAnimation:YES];
+}
+
+- (void)setSplitView:(BWSplitView *)aSplitView
+{
+    if (splitView != aSplitView) 
+	{
+        [splitView release];
+        splitView = [aSplitView retain];
+		
+		[self toggleDividerCheckboxVisibilityWithAnimation:NO];
+    }
+}
+
+- (void)setDividerCheckboxWantsLayer:(NSString *)flag
+{
+	if ([flag isEqualToString:@"YES"])
+		[dividerCheckbox setWantsLayer:YES];
+	else
+		[dividerCheckbox setWantsLayer:NO];
+}
+
+- (BOOL)toggleDividerCheckboxVisibilityWithAnimation:(BOOL)shouldAnimate
+{
+	// Conditions that must be met for a visibility switch to take place. If any of them fail, we return early.
+	if (dividerCheckboxCollapsed && [splitView dividerThickness] > 1.01 && [splitView collapsiblePopupSelection] != 0) {
+	}
+	else if (!dividerCheckboxCollapsed && ([splitView dividerThickness] < 1.01 || [splitView collapsiblePopupSelection] == 0)) {
+	}
+	else
+		return NO;
+	
+	float duration = 0.1, alpha;
+	NSRect targetFrame = NSZeroRect;
+	
+	if (dividerCheckboxCollapsed)
+	{
+		targetFrame = NSMakeRect([[self view] frame].origin.x, [[self view] frame].origin.y, [[self view] frame].size.width, [[self view] frame].size.height + 20);
+		alpha = 1.0;
+	}
+	else
+	{
+		targetFrame = NSMakeRect([[self view] frame].origin.x, [[self view] frame].origin.y, [[self view] frame].size.width, [[self view] frame].size.height - 20);
+		alpha = 0.0;
+	}
+		
+	[self performSelector:@selector(setDividerCheckboxWantsLayer:) withObject:@"YES" afterDelay:0];
+	
+	if (shouldAnimate)
+	{
+		[NSAnimationContext beginGrouping];
+		[[NSAnimationContext currentContext] setDuration:duration];
+		[[dividerCheckbox animator] setAlphaValue:alpha];
+		[[[self view] animator] setFrame:targetFrame];
+		[NSAnimationContext endGrouping];
+		
+		if (dividerCheckboxCollapsed)
+			[self performSelector:@selector(setDividerCheckboxWantsLayer:) withObject:@"NO" afterDelay:duration];
+	}
+	else
+	{
+		[dividerCheckbox setAlphaValue:alpha];
+		[[self view] setFrame:targetFrame];
+		
+		if (dividerCheckboxCollapsed)
+			[self performSelector:@selector(setDividerCheckboxWantsLayer:) withObject:@"NO" afterDelay:0];
+	}
+	
+	dividerCheckboxCollapsed = !dividerCheckboxCollapsed;
+
+	return YES;
+}
+
+- (void)refresh 
+{
 	[super refresh];
+
+	if ([[self inspectedObjects] count] > 0)
+	{
+		[self setSplitView:[[self inspectedObjects] objectAtIndex:0]];
+		
+		// Populate the subview popup button
+		NSMutableArray *content = [[NSMutableArray alloc] init];
+		
+		for (NSView *subview in [splitView subviews])
+		{
+			int index = [[splitView subviews] indexOfObject:subview];
+			NSString *label = [NSString stringWithFormat:@"Subview %d",index];
+			
+			if (![[subview className] isEqualToString:@"NSView"])
+				label = [label stringByAppendingString:[NSString stringWithFormat:@" - %@",[subview className]]];
+			
+			[content addObject:label];
+		}
+		
+		[self setSubviewPopupContent:content];
+		
+		// Populate the collapsible popup button
+		if ([splitView isVertical])
+			[self setCollapsiblePopupContent:[NSMutableArray arrayWithObjects:@"None", @"Left Pane", @"Right Pane",nil]];
+		else
+			[self setCollapsiblePopupContent:[NSMutableArray arrayWithObjects:@"None", @"Top Pane", @"Bottom Pane",nil]];
+	}
+	
+	// Refresh autosizing view
+	[autosizingView setSplitView:splitView];
+	[autosizingView layoutButtons];
+	
+	[self updateSizeLabels];
+	[self updateControls];
+}
+
++ (BOOL)supportsMultipleObjectInspection
+{
+	return NO;
+}
+
+- (void)setMinUnitPopupSelection:(int)index
+{
+	minUnitPopupSelection = index;
+	
+	NSNumber *minUnit = [NSNumber numberWithInt:index];
+	
+	NSMutableDictionary *tempMinUnits = [[splitView minUnits] mutableCopy];
+	[tempMinUnits setObject:minUnit forKey:[NSNumber numberWithInt:[self subviewPopupSelection]]];
+	[splitView setMinUnits:tempMinUnits];
+}
+
+- (void)setMaxUnitPopupSelection:(int)index
+{
+	maxUnitPopupSelection = index;
+
+	NSNumber *maxUnit = [NSNumber numberWithInt:index];
+	
+	NSMutableDictionary *tempMaxUnits = [[splitView maxUnits] mutableCopy];
+	[tempMaxUnits setObject:maxUnit forKey:[NSNumber numberWithInt:[self subviewPopupSelection]]];
+	[splitView setMaxUnits:tempMaxUnits];
+}
+
+- (void)controlTextDidChange:(NSNotification *)aNotification
+{
+	if ([aNotification object] == minField)
+	{
+		if ([minField stringValue] != nil && [[minField stringValue] isEqualToString:@""] == NO && [[minField stringValue] isEqualToString:@" "] == NO)
+		{
+			NSNumber *minValue = [NSNumber numberWithInt:[minField intValue]];
+			NSMutableDictionary *tempMinValues = [[splitView minValues] mutableCopy];
+			[tempMinValues setObject:minValue forKey:[NSNumber numberWithInt:[self subviewPopupSelection]]];
+			[splitView setMinValues:tempMinValues];
+		}
+		else
+		{
+			NSMutableDictionary *tempMinValues = [[splitView minValues] mutableCopy];
+			[tempMinValues removeObjectForKey:[NSNumber numberWithInt:[self subviewPopupSelection]]];
+			[splitView setMinValues:tempMinValues];
+		}
+	}
+	else if ([aNotification object] == maxField)
+	{
+		if ([maxField stringValue] != nil && [[maxField stringValue] isEqualToString:@""] == NO && [[maxField stringValue] isEqualToString:@" "] == NO)
+		{
+			NSNumber *maxValue = [NSNumber numberWithInt:[maxField intValue]];
+			NSMutableDictionary *tempMaxValues = [[splitView maxValues] mutableCopy];
+			[tempMaxValues setObject:maxValue forKey:[NSNumber numberWithInt:[self subviewPopupSelection]]];
+			[splitView setMaxValues:tempMaxValues];
+		}
+		else
+		{
+			NSMutableDictionary *tempMaxValues = [[splitView maxValues] mutableCopy];
+			[tempMaxValues removeObjectForKey:[NSNumber numberWithInt:[self subviewPopupSelection]]];
+			[splitView setMaxValues:tempMaxValues];
+		}
+	}
+}
+
+- (int)collapsiblePopupSelection
+{
+	return [splitView collapsiblePopupSelection];
+}
+
+- (void)setSubviewPopupSelection:(int)index
+{
+	subviewPopupSelection = index;
+	
+	[self updateControls];
+}
+
+- (void)updateControls
+{
+	[minField setObjectValue:[[splitView minValues] objectForKey:[NSNumber numberWithInt:[self subviewPopupSelection]]]];
+	[maxField setObjectValue:[[splitView maxValues] objectForKey:[NSNumber numberWithInt:[self subviewPopupSelection]]]];
+	
+	[self setMinUnitPopupSelection:[[[splitView minUnits] objectForKey:[NSNumber numberWithInt:[self subviewPopupSelection]]] intValue]];
+	[self setMaxUnitPopupSelection:[[[splitView maxUnits] objectForKey:[NSNumber numberWithInt:[self subviewPopupSelection]]] intValue]];
 }
 
 @end

File BWSplitViewInspector.xib

 <?xml version="1.0" encoding="UTF-8"?>
-<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.02">
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03">
 	<data>
 		<int key="IBDocument.SystemTarget">1050</int>
-		<string key="IBDocument.SystemVersion">9E17</string>
-		<string key="IBDocument.InterfaceBuilderVersion">670</string>
-		<string key="IBDocument.AppKitVersion">949.33</string>
+		<string key="IBDocument.SystemVersion">9F33</string>
+		<string key="IBDocument.InterfaceBuilderVersion">677</string>
+		<string key="IBDocument.AppKitVersion">949.34</string>
 		<string key="IBDocument.HIToolboxVersion">352.00</string>
 		<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
 			<bool key="EncodedWithXMLCoder">YES</bool>
 			<string>com.apple.InterfaceBuilderKit</string>
 			<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
 		</object>
+		<object class="NSMutableDictionary" key="IBDocument.Metadata">
+			<bool key="EncodedWithXMLCoder">YES</bool>
+			<object class="NSArray" key="dict.sortedKeys">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+			<object class="NSMutableArray" key="dict.values">
+				<bool key="EncodedWithXMLCoder">YES</bool>
+			</object>
+		</object>
 		<object class="NSMutableArray" key="IBDocument.RootObjects" id="110858478">
 			<bool key="EncodedWithXMLCoder">YES</bool>
 			<object class="NSCustomObject" id="762632889">
 				<int key="NSvFlags">268</int>
 				<object class="NSMutableArray" key="NSSubviews">
 					<bool key="EncodedWithXMLCoder">YES</bool>
+					<object class="NSCustomView" id="1015487935">
+						<reference key="NSNextResponder" ref="537708911"/>
+						<int key="NSvFlags">288</int>
+						<string key="NSFrame">{{98, 18}, {154, 81}}</string>
+						<reference key="NSSuperview" ref="537708911"/>
+						<string key="NSClassName">BWSplitViewInspectorAutosizingView</string>
+					</object>
+					<object class="NSButton" id="226392868">
+						<reference key="NSNextResponder" ref="537708911"/>
+						<int key="NSvFlags">268</int>
+						<string key="NSFrame">{{81, 119}, {148, 18}}</string>
+						<reference key="NSSuperview" ref="537708911"/>
+						<bool key="NSEnabled">YES</bool>
+						<object class="NSButtonCell" key="NSCell" id="531675295">
+							<int key="NSCellFlags">-2080244224</int>
+							<int key="NSCellFlags2">131072</int>
+							<string key="NSContents">Divider Can Collapse</string>
+							<object class="NSFont" key="NSSupport" id="520692967">
+								<string key="NSName">LucidaGrande</string>
+								<double key="NSSize">1.100000e+01</double>
+								<int key="NSfFlags">16</int>
+							</object>
+							<reference key="NSControlView" ref="226392868"/>
+							<int key="NSButtonFlags">1211912703</int>
+							<int key="NSButtonFlags2">130</int>
+							<object class="NSCustomResource" key="NSNormalImage" id="1070637413">
+								<string key="NSClassName">NSImage</string>
+								<string key="NSResourceName">NSSwitch</string>
+							</object>
+							<object class="NSButtonImageSource" key="NSAlternateImage" id="989656584">
+								<string key="NSImageName">NSSwitch</string>
+							</object>
+							<string key="NSAlternateContents"/>
+							<string key="NSKeyEquivalent"/>
+							<int key="NSPeriodicDelay">200</int>
+							<int key="NSPeriodicInterval">25</int>
+						</object>
+					</object>
+					<object class="NSPopUpButton" id="549706135">
+						<reference key="NSNextResponder" ref="537708911"/>
+						<int key="NSvFlags">268</int>
+						<string key="NSFrame">{{20, 262}, {153, 22}}</string>
+						<reference key="NSSuperview" ref="537708911"/>
+						<bool key="NSEnabled">YES</bool>
+						<object class="NSPopUpButtonCell" key="NSCell" id="279914589">
+							<int key="NSCellFlags">-2076049856</int>
+							<int key="NSCellFlags2">133120</int>
+							<object class="NSFont" key="NSSupport" id="26">
+								<string key="NSName">LucidaGrande</string>
+								<double key="NSSize">1.100000e+01</double>
+								<int key="NSfFlags">3100</int>
+							</object>
+							<reference key="NSControlView" ref="549706135"/>
+							<int key="NSButtonFlags">109199615</int>
+							<int key="NSButtonFlags2">129</int>
+							<string key="NSAlternateContents"/>
+							<string key="NSKeyEquivalent"/>
+							<int key="NSPeriodicDelay">400</int>
+							<int key="NSPeriodicInterval">75</int>
+							<object class="NSMenuItem" key="NSMenuItem" id="418532397">
+								<reference key="NSMenu" ref="182588881"/>
+								<string key="NSTitle">Subview 0</string>
+								<string key="NSKeyEquiv"/>
+								<int key="NSKeyEquivModMask">1048576</int>
+								<int key="NSMnemonicLoc">2147483647</int>
+								<int key="NSState">1</int>
+								<object class="NSCustomResource" key="NSOnImage" id="126837135">
+									<string key="NSClassName">NSImage</string>
+									<string key="NSResourceName">NSMenuCheckmark</string>
+								</object>
+								<object class="NSCustomResource" key="NSMixedImage" id="124542338">
+									<string key="NSClassName">NSImage</string>
+									<string key="NSResourceName">NSMenuMixedState</string>
+								</object>
+								<string key="NSAction">_popUpItemAction:</string>
+								<reference key="NSTarget" ref="279914589"/>
+							</object>
+							<bool key="NSMenuItemRespectAlignment">YES</bool>
+							<object class="NSMenu" key="NSMenu" id="182588881">
+								<string key="NSTitle">OtherViews</string>
+								<object class="NSMutableArray" key="NSMenuItems">
+									<bool key="EncodedWithXMLCoder">YES</bool>
+									<reference ref="418532397"/>
+									<object class="NSMenuItem" id="935331416">
+										<reference key="NSMenu" ref="182588881"/>
+										<string type="base64-UTF8" key="NSTitle">WW91IHNob3VsZG4ndCBzZWUgdGhpcw</string>
+										<string key="NSKeyEquiv"/>
+										<int key="NSKeyEquivModMask">1048576</int>
+										<int key="NSMnemonicLoc">2147483647</int>
+										<reference key="NSOnImage" ref="126837135"/>
+										<reference key="NSMixedImage" ref="124542338"/>
+										<string key="NSAction">_popUpItemAction:</string>
+										<reference key="NSTarget" ref="279914589"/>
+									</object>
+								</object>
+							</object>
+							<int key="NSPreferredEdge">1</int>
+							<bool key="NSUsesItemFromMenu">YES</bool>
+							<bool key="NSAltersState">YES</bool>
+							<int key="NSArrowPosition">2</int>
+						</object>
+					</object>
 					<object class="NSButton" id="481169877">
 						<reference key="NSNextResponder" ref="537708911"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{81, 8}, {21, 18}}</string>
+						<string key="NSFrame">{{81, 296}, {21, 18}}</string>
 						<reference key="NSSuperview" ref="537708911"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSButtonCell" key="NSCell" id="614984562">
 							<int key="NSCellFlags">67239424</int>
 							<int key="NSCellFlags2">131072</int>
 							<string key="NSContents">Switch</string>
-							<object class="NSFont" key="NSSupport">
-								<string key="NSName">LucidaGrande</string>
-								<double key="NSSize">1.100000e+01</double>
-								<int key="NSfFlags">3100</int>
-							</object>
+							<reference key="NSSupport" ref="26"/>
 							<reference key="NSControlView" ref="481169877"/>
 							<int key="NSButtonFlags">1211912703</int>
 							<int key="NSButtonFlags2">2</int>
-							<object class="NSCustomResource" key="NSNormalImage">
-								<string key="NSClassName">NSImage</string>
-								<string key="NSResourceName">NSSwitch</string>
-							</object>
-							<object class="NSButtonImageSource" key="NSAlternateImage">
-								<string key="NSImageName">NSSwitch</string>
-							</object>
+							<reference key="NSNormalImage" ref="1070637413"/>
+							<reference key="NSAlternateImage" ref="989656584"/>
 							<string key="NSAlternateContents"/>
 							<string key="NSKeyEquivalent"/>
 							<int key="NSPeriodicDelay">200</int>
 					<object class="NSTextField" id="184291607">
 						<reference key="NSNextResponder" ref="537708911"/>
 						<int key="NSvFlags">268</int>
-						<string key="NSFrame">{{8, 10}, {70, 14}}</string>
+						<string key="NSFrame">{{8, 298}, {70, 14}}</string>
 						<reference key="NSSuperview" ref="537708911"/>
 						<bool key="NSEnabled">YES</bool>
 						<object class="NSTextFieldCell" key="NSCell" id="1056778467">
 							<int key="NSCellFlags">67239488</int>
 							<int key="NSCellFlags2">4326400</int>
 							<string key="NSContents">Color</string>
-							<object class="NSFont" key="NSSupport">
+							<object class="NSFont" key="NSSupport" id="14915156">
 								<string key="NSName">LucidaGrande-Bold</string>
 								<double key="NSSize">1.100000e+01</double>
 								<int key="NSfFlags">16</int>
 							</object>
 							<reference key="NSControlView" ref="184291607"/>
-							<object class="NSColor" key="NSBackgroundColor">
+							<object class="NSColor" key="NSBackgroundColor" id="1063946981">
 								<int key="NSColorSpace">6</int>
 								<string key="NSCatalogName">System</string>
 								<string key="NSColorName">controlColor</string>
 									<bytes key="NSWhite">MC42NjY2NjY2OQA</bytes>
 								</object>
 							</object>
-							<object class="NSColor" key="NSTextColor">
+							<object class="NSColor" key="NSTextColor" id="796081620">
 								<int key="NSColorSpace">6</int>
 								<string key="NSCatalogName">System</string>
 								<string key="NSColorName">controlTextColor</string>
-								<object class="NSColor" key="NSColor">
+								<object class="NSColor" key="NSColor" id="410847485">
 									<int key="NSColorSpace">3</int>
 									<bytes key="NSWhite">MAA</bytes>
 								</object>
 								<string>NSColor pasteboard type</string>
 							</object>
 						</object>
-						<string key="NSFrame">{{104, 5}, {50, 24}}</string>
+						<string key="NSFrame">{{104, 293}, {66, 24}}</string>
 						<reference key="NSSuperview" ref="537708911"/>
 						<bool key="NSEnabled">YES</bool>
 						<bool key="NSIsBordered">YES</bool>
 							<bytes key="NSRGB">MC4wNTgxMzA0OTkgMC4wNTU1NDE4OTkgMQA</bytes>
 						</object>
 					</object>
+					<object class="NSTextField" id="942568087">
+						<reference key="NSNextResponder" ref="537708911"/>
+						<int key="NSvFlags">268</int>
+						<string key="NSFrame">{{8, 144}, {70, 14}}</string>
+						<reference key="NSSuperview" ref="537708911"/>
+						<bool key="NSEnabled">YES</bool>
+						<object class="NSTextFieldCell" key="NSCell" id="818165239">
+							<int key="NSCellFlags">67239488</int>
+							<int key="NSCellFlags2">4326400</int>
+							<string key="NSContents">Collapsible</string>
+							<reference key="NSSupport" ref="14915156"/>
+							<reference key="NSControlView" ref="942568087"/>
+							<reference key="NSBackgroundColor" ref="1063946981"/>
+							<reference key="NSTextColor" ref="796081620"/>
+						</object>
+					</object>
+					<object class="NSPopUpButton" id="1021968833">
+						<reference key="NSNextResponder" ref="537708911"/>
+						<int key="NSvFlags">268</int>
+						<string key="NSFrame">{{81, 139}, {186, 22}}</string>
+						<reference key="NSSuperview" ref="537708911"/>
+						<bool key="NSEnabled">YES</bool>
+						<object class="NSPopUpButtonCell" key="NSCell" id="815913852">
+							<int key="NSCellFlags">-2076049856</int>
+							<int key="NSCellFlags2">133120</int>
+							<reference key="NSSupport" ref="26"/>
+							<reference key="NSControlView" ref="1021968833"/>
+							<int key="NSButtonFlags">109199615</int>
+							<int key="NSButtonFlags2">129</int>
+							<string key="NSAlternateContents"/>
+							<string key="NSKeyEquivalent"/>
+							<int key="NSPeriodicDelay">400</int>
+							<int key="NSPeriodicInterval">75</int>
+							<object class="NSMenuItem" key="NSMenuItem" id="967869275">
+								<reference key="NSMenu" ref="496972556"/>
+								<string key="NSTitle">Right Pane</string>
+								<string key="NSKeyEquiv"/>
+								<int key="NSKeyEquivModMask">1048576</int>
+								<int key="NSMnemonicLoc">2147483647</int>
+								<int key="NSState">1</int>
+								<reference key="NSOnImage" ref="126837135"/>
+								<reference key="NSMixedImage" ref="124542338"/>
+								<string key="NSAction">_popUpItemAction:</string>
+								<reference key="NSTarget" ref="815913852"/>
+							</object>
+							<bool key="NSMenuItemRespectAlignment">YES</bool>
+							<object class="NSMenu" key="NSMenu" id="496972556">
+								<string key="NSTitle">OtherViews</string>
+								<object class="NSMutableArray" key="NSMenuItems">
+									<bool key="EncodedWithXMLCoder">YES</bool>
+									<object class="NSMenuItem" id="402624541">
+										<reference key="NSMenu" ref="496972556"/>
+										<string key="NSTitle">Left Pane</string>
+										<string key="NSKeyEquiv"/>
+										<int key="NSKeyEquivModMask">1048576</int>
+										<int key="NSMnemonicLoc">2147483647</int>
+										<reference key="NSOnImage" ref="126837135"/>
+										<reference key="NSMixedImage" ref="124542338"/>
+										<string key="NSAction">_popUpItemAction:</string>
+										<reference key="NSTarget" ref="815913852"/>
+									</object>
+									<reference ref="967869275"/>
+								</object>
+							</object>
+							<int key="NSSelectedIndex">1</int>
+							<int key="NSPreferredEdge">1</int>
+							<bool key="NSUsesItemFromMenu">YES</bool>
+							<bool key="NSAltersState">YES</bool>
+							<int key="NSArrowPosition">2</int>
+						</object>
+					</object>
+					<object class="NSBox" id="179870474">
+						<reference key="NSNextResponder" ref="537708911"/>
+						<int key="NSvFlags">12</int>
+						<object class="NSMutableArray" key="NSSubviews">
+							<bool key="EncodedWithXMLCoder">YES</bool>
+							<object class="NSView" id="618087799">
+								<reference key="NSNextResponder" ref="179870474"/>
+								<int key="NSvFlags">256</int>
+								<object class="NSMutableArray" key="NSSubviews">
+									<bool key="EncodedWithXMLCoder">YES</bool>
+									<object class="NSTextField" id="957717307">
+										<reference key="NSNextResponder" ref="618087799"/>
+										<int key="NSvFlags">268</int>
+										<string key="NSFrame">{{8, 67}, {70, 14}}</string>
+										<reference key="NSSuperview" ref="618087799"/>
+										<bool key="NSEnabled">YES</bool>
+										<object class="NSTextFieldCell" key="NSCell" id="712290691">
+											<int key="NSCellFlags">67239488</int>
+											<int key="NSCellFlags2">4326400</int>
+											<string key="NSContents">View Size</string>
+											<reference key="NSSupport" ref="14915156"/>
+											<reference key="NSControlView" ref="957717307"/>
+											<reference key="NSBackgroundColor" ref="1063946981"/>
+											<reference key="NSTextColor" ref="796081620"/>
+										</object>
+									</object>
+									<object class="NSTextField" id="826786521">
+										<reference key="NSNextResponder" ref="618087799"/>
+										<int key="NSvFlags">268</int>
+										<string key="NSFrame">{{81, 49}, {88, 14}}</string>
+										<reference key="NSSuperview" ref="618087799"/>
+										<bool key="NSEnabled">YES</bool>
+										<object class="NSTextFieldCell" key="NSCell" id="582494015">
+											<int key="NSCellFlags">67239488</int>
+											<int key="NSCellFlags2">4326400</int>
+											<string key="NSContents">Min Width</string>
+											<reference key="NSSupport" ref="520692967"/>
+											<reference key="NSControlView" ref="826786521"/>
+											<reference key="NSBackgroundColor" ref="1063946981"/>
+											<reference key="NSTextColor" ref="796081620"/>
+										</object>
+									</object>
+									<object class="NSTextField" id="30881512">
+										<reference key="NSNextResponder" ref="618087799"/>
+										<int key="NSvFlags">268</int>
+										<string key="NSFrame">{{84, 65}, {86, 19}}</string>
+										<reference key="NSSuperview" ref="618087799"/>
+										<bool key="NSEnabled">YES</bool>
+										<object class="NSTextFieldCell" key="NSCell" id="479675392">
+											<int key="NSCellFlags">-1804468671</int>
+											<int key="NSCellFlags2">71435264</int>
+											<string key="NSContents"/>
+											<reference key="NSSupport" ref="26"/>
+											<reference key="NSControlView" ref="30881512"/>
+											<bool key="NSDrawsBackground">YES</bool>
+											<object class="NSColor" key="NSBackgroundColor" id="313150461">
+												<int key="NSColorSpace">6</int>
+												<string key="NSCatalogName">System</string>
+												<string key="NSColorName">textBackgroundColor</string>
+												<object class="NSColor" key="NSColor">
+													<int key="NSColorSpace">3</int>
+													<bytes key="NSWhite">MQA</bytes>
+												</object>
+											</object>
+											<object class="NSColor" key="NSTextColor" id="872515192">
+												<int key="NSColorSpace">6</int>
+												<string key="NSCatalogName">System</string>
+												<string key="NSColorName">textColor</string>
+												<reference key="NSColor" ref="410847485"/>
+											</object>
+										</object>
+									</object>
+									<object class="NSPopUpButton" id="871690315">
+										<reference key="NSNextResponder" ref="618087799"/>
+										<int key="NSvFlags">268</int>
+										<string key="NSFrame">{{175, 62}, {92, 22}}</string>
+										<reference key="NSSuperview" ref="618087799"/>
+										<bool key="NSEnabled">YES</bool>
+										<object class="NSPopUpButtonCell" key="NSCell" id="307193598">
+											<int key="NSCellFlags">-2076049856</int>
+											<int key="NSCellFlags2">133120</int>
+											<reference key="NSSupport" ref="26"/>
+											<reference key="NSControlView" ref="871690315"/>
+											<int key="NSButtonFlags">109199615</int>
+											<int key="NSButtonFlags2">129</int>
+											<reference key="NSAlternateImage" ref="26"/>
+											<string key="NSAlternateContents"/>
+											<string key="NSKeyEquivalent"/>
+											<int key="NSPeriodicDelay">400</int>
+											<int key="NSPeriodicInterval">75</int>
+											<object class="NSMenuItem" key="NSMenuItem" id="638706878">
+												<reference key="NSMenu" ref="562040593"/>
+												<string key="NSTitle">points</string>
+												<string key="NSKeyEquiv"/>
+												<int key="NSKeyEquivModMask">1048576</int>
+												<int key="NSMnemonicLoc">2147483647</int>
+												<int key="NSState">1</int>
+												<reference key="NSOnImage" ref="126837135"/>
+												<reference key="NSMixedImage" ref="124542338"/>
+												<string key="NSAction">_popUpItemAction:</string>
+												<reference key="NSTarget" ref="307193598"/>
+											</object>
+											<bool key="NSMenuItemRespectAlignment">YES</bool>
+											<object class="NSMenu" key="NSMenu" id="562040593">
+												<string key="NSTitle">OtherViews</string>
+												<object class="NSMutableArray" key="NSMenuItems">
+													<bool key="EncodedWithXMLCoder">YES</bool>
+													<reference ref="638706878"/>
+													<object class="NSMenuItem" id="596264175">
+														<reference key="NSMenu" ref="562040593"/>
+														<string key="NSTitle">%</string>
+														<string key="NSKeyEquiv"/>
+														<int key="NSKeyEquivModMask">1048576</int>
+														<int key="NSMnemonicLoc">2147483647</int>
+														<reference key="NSOnImage" ref="126837135"/>
+														<reference key="NSMixedImage" ref="124542338"/>
+														<string key="NSAction">_popUpItemAction:</string>
+														<reference key="NSTarget" ref="307193598"/>
+													</object>
+												</object>
+											</object>
+											<int key="NSPreferredEdge">1</int>
+											<bool key="NSUsesItemFromMenu">YES</bool>
+											<bool key="NSAltersState">YES</bool>
+											<int key="NSArrowPosition">2</int>
+										</object>
+									</object>
+									<object class="NSTextField" id="901872831">
+										<reference key="NSNextResponder" ref="618087799"/>
+										<int key="NSvFlags">268</int>
+										<string key="NSFrame">{{81, 6}, {91, 14}}</string>
+										<reference key="NSSuperview" ref="618087799"/>
+										<bool key="NSEnabled">YES</bool>
+										<object class="NSTextFieldCell" key="NSCell" id="335536713">
+											<int key="NSCellFlags">67239488</int>
+											<int key="NSCellFlags2">4326400</int>
+											<string key="NSContents">Max Width</string>