Created
September 23, 2011 23:18
-
-
Save panupan/1238699 to your computer and use it in GitHub Desktop.
Cocoa VBox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// VBox.h | |
// VBox | |
// | |
// Created by Panupan Sriautharawong on 9/23/11. | |
// Copyright 2011 Panupan.com. All rights reserved. | |
// | |
@interface WILLVBox : NSView { | |
NSColor *backgroundColor; | |
int spacing; | |
int padding; | |
BOOL mouseEnabled; | |
BOOL repositionOrigin; | |
NSTrackingArea* trackingArea; | |
} | |
@property (nonatomic, strong) NSColor *backgroundColor; | |
@property (nonatomic, assign) int spacing; | |
@property (nonatomic, assign) int padding; | |
@property (nonatomic, assign) BOOL mouseEnabled; | |
@property (nonatomic, assign) BOOL repositionOrigin; | |
- (void)updateDisplayList; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// VBox.m | |
// VBox | |
// | |
// Created by Panupan Sriautharawong on 9/23/11. | |
// Copyright 2011 Panupan.com. All rights reserved. | |
// | |
#import "WILLVBox.h" | |
@implementation WILLVBox | |
@synthesize backgroundColor; | |
@synthesize spacing, padding, mouseEnabled, repositionOrigin; | |
- (void)setSpacing:(int)o { | |
spacing = o; | |
[self updateDisplayList]; | |
} | |
- (void)setPadding:(int)o { | |
padding = o; | |
[self updateDisplayList]; | |
} | |
- (BOOL)isFlipped { return YES; } | |
#pragma mark - Overrides | |
- (id)initWithFrame:(NSRect)frameRect | |
{ | |
self = [super initWithFrame:frameRect]; | |
if (self) { | |
spacing = 8; | |
padding = 20; | |
mouseEnabled = false; | |
repositionOrigin = true; | |
[self setAutoresizingMask: NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin]; | |
} | |
return self; | |
} | |
- (void)didAddSubview:(NSView *)subview | |
{ | |
[subview addObserver:self | |
forKeyPath:@"frame" | |
options:NSKeyValueObservingOptionNew | |
context:nil]; | |
[subview addObserver:self | |
forKeyPath:@"hidden" | |
options:NSKeyValueObservingOptionNew | |
context:nil]; | |
[self updateDisplayList]; | |
} | |
- (void)willRemoveSubview:(NSView *)subview | |
{ | |
[subview removeObserver:self | |
forKeyPath:@"frame"]; | |
[subview removeObserver:self | |
forKeyPath:@"hidden"]; | |
[self updateDisplayList]; | |
} | |
- (void)updateDisplayList | |
{ | |
//NSLog(@"updateDisplayList managedViews:%d", (int)[managedViews count]); | |
int newHeight = padding * 2; | |
int currY = 0; | |
NSView *subview; | |
// Get new height | |
for (subview in self.subviews) { | |
if (!subview.isHidden) { | |
newHeight += subview.frame.size.height + spacing; | |
} | |
} | |
// Resize and reposition VBox | |
[self setFrame:NSMakeRect(self.frame.origin.x, | |
repositionOrigin ? self.frame.origin.y + (self.frame.size.height-newHeight) : self.frame.origin.y, | |
self.frame.size.width, | |
newHeight)]; | |
// Rearrange subviews | |
currY = padding; | |
for (subview in self.subviews) { | |
if (subview.isHidden) continue; | |
[subview setFrameOrigin:NSMakePoint(subview.frame.origin.x, currY)]; | |
currY += subview.frame.size.height + (subview != [self.subviews lastObject] ? spacing : 0); | |
} | |
if (mouseEnabled) { | |
[self removeTrackingArea:trackingArea]; | |
trackingArea = [[NSTrackingArea alloc] initWithRect:self.frame options: (NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil]; | |
[self addTrackingArea:trackingArea]; | |
} | |
} | |
// Prevents retain cycle caused by observers | |
- (void)viewDidMoveToSuperview | |
{ | |
for (NSView *subview in self.subviews) | |
{ | |
if (self.superview) { | |
[subview addObserver:self | |
forKeyPath:@"frame" | |
options:NSKeyValueObservingOptionNew | |
context:nil]; | |
} | |
else { | |
[subview removeObserver:self | |
forKeyPath:@"frame"]; | |
} | |
} | |
} | |
- (void)drawRect:(NSRect)dirtyRect | |
{ | |
// Drawing code here. | |
if ([self backgroundColor]) | |
{ | |
[backgroundColor setFill]; | |
NSRectFill(dirtyRect); | |
} | |
} | |
#pragma mark - NSKeyValueObserving | |
- (void)observeValueForKeyPath:(NSString *)keyPath | |
ofObject:(id)object | |
change:(NSDictionary *)change | |
context:(void *)context | |
{ | |
[self updateDisplayList]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment