-
Notifications
You must be signed in to change notification settings - Fork 68
/
PrioritySplitViewDelegate.m
185 lines (157 loc) · 4.62 KB
/
PrioritySplitViewDelegate.m
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//
// PrioritySplitViewDelegate.m
// ColumnSplitView
//
// Created by Matt Gallagher on 2009/09/01.
// Copyright 2009 Matt Gallagher. All rights reserved.
//
#import "PrioritySplitViewDelegate.h"
@implementation PrioritySplitViewDelegate
- (void)setMinimumLength:(CGFloat)minLength forViewAtIndex:(NSInteger)viewIndex
{
if (!lengthsByViewIndex)
{
lengthsByViewIndex = [[NSMutableDictionary alloc] initWithCapacity:0];
}
[lengthsByViewIndex
setObject:[NSNumber numberWithDouble:minLength]
forKey:[NSNumber numberWithInteger:viewIndex]];
}
- (void)setPriority:(NSInteger)priorityIndex forViewAtIndex:(NSInteger)viewIndex
{
if (!viewIndicesByPriority)
{
viewIndicesByPriority = [[NSMutableDictionary alloc] initWithCapacity:0];
}
[viewIndicesByPriority
setObject:[NSNumber numberWithInteger:viewIndex]
forKey:[NSNumber numberWithInteger:priorityIndex]];
}
- (CGFloat)splitView:(NSSplitView *)sender
constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)offset
{
NSView *subview = [[sender subviews] objectAtIndex:offset];
NSRect subviewFrame = subview.frame;
CGFloat frameOrigin;
if ([sender isVertical])
{
frameOrigin = subviewFrame.origin.x;
}
else
{
frameOrigin = subviewFrame.origin.y;
}
CGFloat minimumSize =
[[lengthsByViewIndex objectForKey:[NSNumber numberWithInteger:offset]]
doubleValue];
return frameOrigin + minimumSize;
}
- (CGFloat)splitView:(NSSplitView *)sender
constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset
{
NSView *growingSubview = [[sender subviews] objectAtIndex:offset];
NSView *shrinkingSubview = [[sender subviews] objectAtIndex:offset + 1];
NSRect growingSubviewFrame = growingSubview.frame;
NSRect shrinkingSubviewFrame = shrinkingSubview.frame;
CGFloat shrinkingSize;
CGFloat currentCoordinate;
if ([sender isVertical])
{
currentCoordinate =
growingSubviewFrame.origin.x + growingSubviewFrame.size.width;
shrinkingSize = shrinkingSubviewFrame.size.width;
}
else
{
currentCoordinate =
growingSubviewFrame.origin.y + growingSubviewFrame.size.height;
shrinkingSize = shrinkingSubviewFrame.size.height;
}
CGFloat minimumSize =
[[lengthsByViewIndex objectForKey:[NSNumber numberWithInteger:offset + 1]]
doubleValue];
return currentCoordinate + (shrinkingSize - minimumSize);
}
- (void)splitView:(NSSplitView *)sender
resizeSubviewsWithOldSize:(NSSize)oldSize
{
NSArray *subviews = [sender subviews];
NSInteger subviewsCount = [subviews count];
BOOL isVertical = [sender isVertical];
CGFloat delta = [sender isVertical] ?
(sender.bounds.size.width - oldSize.width) :
(sender.bounds.size.height - oldSize.height);
NSInteger viewCountCheck = 0;
for (NSNumber *priorityIndex in
[[viewIndicesByPriority allKeys] sortedArrayUsingSelector:@selector(compare:)])
{
NSNumber *viewIndex = [viewIndicesByPriority objectForKey:priorityIndex];
NSInteger viewIndexValue = [viewIndex integerValue];
if (viewIndexValue >= subviewsCount)
{
continue;
}
NSView *view = [subviews objectAtIndex:viewIndexValue];
NSSize frameSize = [view frame].size;
NSNumber *minLength = [lengthsByViewIndex objectForKey:viewIndex];
CGFloat minLengthValue = [minLength doubleValue];
if (isVertical)
{
frameSize.height = sender.bounds.size.height;
if (delta > 0 ||
frameSize.width + delta >= minLengthValue)
{
frameSize.width += delta;
delta = 0;
}
else if (delta < 0)
{
delta += frameSize.width - minLengthValue;
frameSize.width = minLengthValue;
}
}
else
{
frameSize.width = sender.bounds.size.width;
if (delta > 0 ||
frameSize.height + delta >= minLengthValue)
{
frameSize.height += delta;
delta = 0;
}
else if (delta < 0)
{
delta += frameSize.height - minLengthValue;
frameSize.height = minLengthValue;
}
}
[view setFrameSize:frameSize];
viewCountCheck++;
}
NSAssert1(viewCountCheck == [subviews count],
@"Number of valid views in priority list is less than the subview count"
@" of split view %p.",
sender);
NSAssert3(fabs(delta) < 0.5,
@"Split view %p resized smaller than minimum %@ of %f",
sender,
isVertical ? @"width" : @"height",
sender.frame.size.width - delta);
CGFloat offset = 0;
CGFloat dividerThickness = [sender dividerThickness];
for (NSView *subview in subviews)
{
NSRect viewFrame = [subview frame];
NSPoint viewOrigin = viewFrame.origin;
if([sender isVertical]) {
viewOrigin.x = offset;
offset += viewFrame.size.width + dividerThickness;
}
else {
viewOrigin.y = offset;
offset += viewFrame.size.height + dividerThickness;
}
[subview setFrameOrigin:viewOrigin];
}
}
@end