-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBESplitViewConstraintEnforcer.m
More file actions
76 lines (62 loc) · 2.91 KB
/
BESplitViewConstraintEnforcer.m
File metadata and controls
76 lines (62 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//
// BESplitViewConstraintEnforcer.m
//
// Copyright (c) 2013 Incredible Bee Ltd. Licensed under the BSD License.
//
#import "BESplitViewConstraintEnforcer.h"
@implementation BESplitViewConstraintEnforcer
#pragma mark Initializion
- (id)initWithMinimumPaneWidths:(NSArray *)anArray {
self = [super init];
if (self) {
minimumPaneWidths = [anArray retain];
}
return self;
}
- (void)dealloc {
[minimumPaneWidths release];
[super dealloc];
}
#pragma mark Split view delegate methods
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex {
// When the divider is dragged left only the pane immediately to the
// divider's left is resized. So the way this works is that we first
// calculate the width of all panes up to but *not* including that pane.
CGFloat widthUpToSubview = 0;
NSArray *subviews = [splitView subviews];
for (NSUInteger i = 0; i < dividerIndex; i++) {
NSView *pane = [subviews objectAtIndex:i];
CGFloat paneWidth = [pane frame].size.width;
widthUpToSubview += paneWidth;
}
// Now when we add the pane's minimum width we get the, in absolute terms,
// the minimum width for the width constraints to be met.
CGFloat minAllowedWidth = widthUpToSubview + [[minimumPaneWidths objectAtIndex:dividerIndex] floatValue];
// Finally we accept the proposed width only if it doesn't undercut the
// minimum allowed width
return proposedMin < minAllowedWidth ? minAllowedWidth : proposedMin;
}
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex{
// This works similar to how we work out the minimum constrained width. When
// the divider is dragged right, only the pane immediately to the divider's
// right is resized. Thus we first calculate the width consumed by all panes
// after that pane.
CGFloat widthDownToSubview = 0;
NSArray *subviews = [splitView subviews];
for (NSUInteger i = [subviews count] - 1; i > dividerIndex + 1; i--) {
NSView *pane = [subviews objectAtIndex:i];
CGFloat paneWidth = [pane frame].size.width;
widthDownToSubview += paneWidth;
}
// Now when we add the pane's minimum width on top of the consumed width
// after it, we get the maximum width allowed for the constraints to be met.
// But we need a position from the left of the split view, so we translate
// that by deducting it from the split view's total width.
CGFloat splitViewWidth = [splitView frame].size.width;
CGFloat minPaneWidth = [[minimumPaneWidths objectAtIndex:dividerIndex+1] floatValue];
CGFloat maxAllowedWidth = splitViewWidth - (widthDownToSubview + minPaneWidth);
// This is the converse of the minimum constraint method: accept the proposed
// maximum only if it doesn't exced the maximum allowed width
return proposedMax > maxAllowedWidth ? maxAllowedWidth : proposedMax;
}
@end