Skip to content

Instantly share code, notes, and snippets.

@panupan
Created September 23, 2011 23:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save panupan/1238699 to your computer and use it in GitHub Desktop.
Save panupan/1238699 to your computer and use it in GitHub Desktop.
Cocoa VBox
//
// 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
//
// 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