bwalkin / BWToolkit (http://brandonwalkin.com/bwtoolkit/)
BWToolkit is an Interface Builder plugin that contains commonly used UI elements and other objects designed to simplify development for the Mac.
Clone this repository (size: 1.5 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/bwalkin/bwtoolkit/
| commit 104: | df308f70abee |
| parent 103: | f164b18c9667 |
| branch: | default |
Anchored button bar - Added support for multiple resizable bars in a split view and bars can now move any divider
5 months ago
Changed (Δ1.8 KB):
raw changeset »
BWAnchoredButtonBar.m (72 lines added, 13 lines removed)
BWSplitView.h (1 lines added, 0 lines removed)
BWSplitView.m (1 lines added, 1 lines removed)
Up to file-list BWAnchoredButtonBar.m:
10 |
10 |
#import "NSColor+BWAdditions.h" |
11 |
11 |
#import "NSView+BWAdditions.h" |
12 |
12 |
#import "BWAnchoredButton.h" |
13 |
#import "BWSplitView.h" |
|
13 |
14 |
|
14 |
15 |
static NSColor *topLineColor, *bottomLineColor; |
15 |
16 |
static NSColor *topColor, *middleTopColor, *middleBottomColor, *bottomColor; |
| … | … | @@ -24,6 +25,7 @@ static float scaleFactor = 0.0f; |
24 |
25 |
- (void)drawLastButtonInsetInRect:(NSRect)rect; |
25 |
26 |
- (BOOL)isInLastSubview; |
26 |
27 |
- (NSSplitView *)splitView; |
28 |
- (NSInteger)dividerIndexNearestToHandle; |
|
27 |
29 |
@end |
28 |
30 |
|
29 |
31 |
@implementation BWAnchoredButtonBar |
| … | … | @@ -94,7 +96,37 @@ static float scaleFactor = 0.0f; |
94 |
96 |
NSSplitView *splitView = [self splitView]; |
95 |
97 |
|
96 |
98 |
if (splitView != nil && [splitView isVertical] && [self isResizable]) |
97 |
|
|
99 |
{ |
|
100 |
if ([splitView delegate] != nil && ([[splitView delegate] isKindOfClass:[BWAnchoredButtonBar class]] || |
|
101 |
[splitView isKindOfClass:[BWSplitView class]] && [[(BWSplitView *)splitView secondaryDelegate] isKindOfClass:[BWAnchoredButtonBar class]])) |
|
102 |
{ |
|
103 |
// There's already an Anchored Button Bar set as the delegate so we need to set ourself as the split view delegate on |
|
104 |
// the button bar. But since there can be multiple button bars, we need to set ourself as the delegate on the last |
|
105 |
// button bar of the delegate chain. |
|
106 |
||
107 |
BWAnchoredButtonBar *currentDelegate = [splitView isKindOfClass:[BWSplitView class]] ? [(BWSplitView *)splitView secondaryDelegate] : [splitView delegate]; |
|
108 |
BWAnchoredButtonBar *lastDelegate = currentDelegate; |
|
109 |
||
110 |
while (currentDelegate != nil) |
|
111 |
{ |
|
112 |
if ([currentDelegate splitViewDelegate] != nil && [[currentDelegate splitViewDelegate] isKindOfClass:[BWAnchoredButtonBar class]]) |
|
113 |
{ |
|
114 |
currentDelegate = [currentDelegate splitViewDelegate]; |
|
115 |
lastDelegate = currentDelegate; |
|
116 |
} |
|
117 |
else |
|
118 |
{ |
|
119 |
currentDelegate = nil; |
|
120 |
} |
|
121 |
} |
|
122 |
||
123 |
[lastDelegate setSplitViewDelegate:self]; |
|
124 |
} |
|
125 |
else |
|
126 |
{ |
|
127 |
[splitView setDelegate:self]; |
|
128 |
} |
|
129 |
} |
|
98 |
130 |
|
99 |
131 |
[self bwBringToFront]; |
100 |
132 |
} |
| … | … | @@ -200,6 +232,14 @@ static float scaleFactor = 0.0f; |
200 |
232 |
return NO; |
201 |
233 |
} |
202 |
234 |
|
235 |
- (NSInteger)dividerIndexNearestToHandle |
|
236 |
{ |
|
237 |
if ([self isInLastSubview]) |
|
238 |
return self.splitView.subviews.count - 2; |
|
239 |
||
240 |
return [[[self splitView] subviews] indexOfObject:[self superview]]; |
|
241 |
} |
|
242 |
||
203 |
243 |
- (NSSplitView *)splitView |
204 |
244 |
{ |
205 |
245 |
NSSplitView *splitView = nil; |
| … | … | @@ -260,25 +300,44 @@ static float scaleFactor = 0.0f; |
260 |
300 |
return wasBorderedBar; |
261 |
301 |
} |
262 |
302 |
|
303 |
- (void)dealloc |
|
304 |
{ |
|
305 |
NSSplitView *splitView = [self splitView]; |
|
306 |
||
307 |
if ([splitView delegate] == self) |
|
308 |
[splitView setDelegate:nil]; |
|
309 |
||
310 |
[super dealloc]; |
|
311 |
} |
|
312 |
||
263 |
313 |
#pragma mark NSSplitView Delegate Methods |
264 |
314 |
|
265 |
315 |
// Add the resize handle rect to the split view hot zone |
266 |
316 |
- (NSRect)splitView:(NSSplitView *)aSplitView additionalEffectiveRectOfDividerAtIndex:(NSInteger)dividerIndex |
267 |
{ |
|
268 |
if ([splitViewDelegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)]) |
|
269 |
return [splitViewDelegate splitView:aSplitView additionalEffectiveRectOfDividerAtIndex:dividerIndex]; |
|
317 |
{ |
|
318 |
if (dividerIndex == [self dividerIndexNearestToHandle]) |
|
319 |
{ |
|
320 |
NSRect paddedHandleRect; |
|
321 |
paddedHandleRect.origin.y = [aSplitView frame].size.height - [self frame].origin.y - [self bounds].size.height; |
|
322 |
||
323 |
// Note: Assumes button bar is nested directly in a split view subview |
|
324 |
if (self.handleIsRightAligned) |
|
325 |
paddedHandleRect.origin.x = NSMinX([[self superview] frame]); |
|
326 |
else |
|
327 |
paddedHandleRect.origin.x = NSMaxX([[self superview] frame]) - 15; |
|
270 |
328 |
|
271 |
NSRect paddedHandleRect; |
|
272 |
paddedHandleRect.origin.y = [aSplitView frame].size.height - [self frame].origin.y - [self bounds].size.height; |
|
273 |
|
|
329 |
paddedHandleRect.size.width = 15; |
|
330 |
paddedHandleRect.size.height = [self bounds].size.height; |
|
274 |
331 |
|
275 |
if (self.handleIsRightAligned) |
|
276 |
paddedHandleRect.origin.x = [aSplitView frame].size.width - [self bounds].size.width; |
|
332 |
return paddedHandleRect; |
|
333 |
} |
|
334 |
else |
|
335 |
{ |
|
336 |
if ([splitViewDelegate respondsToSelector:@selector(splitView:additionalEffectiveRectOfDividerAtIndex:)]) |
|
337 |
return [splitViewDelegate splitView:aSplitView additionalEffectiveRectOfDividerAtIndex:dividerIndex]; |
|
338 |
} |
|
277 |
339 |
|
278 |
paddedHandleRect.size.width = 15; |
|
279 |
paddedHandleRect.size.height = [self bounds].size.height; |
|
280 |
||
281 |
return paddedHandleRect; |
|
340 |
return NSZeroRect; |
|
282 |
341 |
} |
283 |
342 |
|
284 |
343 |
// Remaining delegate methods. They test for an implementation by the splitViewDelegate (otherwise perform default behavior) |
Up to file-list BWSplitView.h:
28 |
28 |
@property (retain) NSMutableDictionary *resizableSubviewPreferredProportion, *nonresizableSubviewPreferredSize; |
29 |
29 |
@property (retain) NSArray *stateForLastPreferredCalculations; |
30 |
30 |
@property (retain) NSButton *toggleCollapseButton; |
31 |
@property (assign) id secondaryDelegate; |
|
31 |
32 |
@property BOOL collapsibleSubviewCollapsed; |
32 |
33 |
@property int collapsiblePopupSelection; |
33 |
34 |
@property BOOL dividerCanCollapse; |
Up to file-list BWSplitView.m:
| … | … | @@ -54,7 +54,7 @@ static float scaleFactor = 1.0f; |
54 |
54 |
|
55 |
55 |
@synthesize color, colorIsEnabled, checkboxIsEnabled, minValues, maxValues, minUnits, maxUnits, collapsiblePopupSelection, dividerCanCollapse, collapsibleSubviewCollapsed; |
56 |
56 |
@synthesize resizableSubviewPreferredProportion, nonresizableSubviewPreferredSize, stateForLastPreferredCalculations; |
57 |
@synthesize toggleCollapseButton |
|
57 |
@synthesize toggleCollapseButton, secondaryDelegate; |
|
58 |
58 |
|
59 |
59 |
+ (void)initialize; |
60 |
60 |
{ |
