Cocoa: Horizontal Box
November 8, 2008 Matteo Bertozzi | Filed Under Cocoa | No CommentsIt’s a couple of days that I’m searching for something like QHBoxLayout (Qt Horizonal Box Layout) in Cocoa. There’s NSMatrix that do something like this… but it uses NSCell and it sets the same size for all the cells, so this is not what I want. My solution is a simple NSView subclass…
This is the HBox Source…
@interface HBox : NSView {
NSUInteger hspace;
}
@property (readwrite, assign) NSUInteger space;
- (id)initWithFrame:(NSRect)frameRect;
- (void)clearItems;
- (void)addItem:(NSControl *)itemView;
- (void)removeItemAtIndex:(NSUInteger)index;
- (void)moveItem:(NSView *)view space:(NSInteger)space;
- (void)moveItems:(NSInteger) space fromIndex:(NSUInteger)index;
@end
@implementation HBox
@synthesize space = hspace;
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect])) {
hspace = 4;
}
return self;
}
- (void)dealloc {
[super dealloc];
}
- (void)clearItems {
NSArray *subviewArray = [self subviews];
NSUInteger subviewCount = [subviewArray count];
while (subviewCount-- > 0) {
NSView *view = [subviewArray objectAtIndex:0];
[view removeFromSuperview];
[view release];
}
[self setNeedsDisplay:YES];
}
- (void)removeItemAtIndex:(NSUInteger)index {
NSView *view = [[self subviews] objectAtIndex:index];
int viewWidth = -1 * [view frame].size.width - hspace;
[view removeFromSuperview];
[view release];
[self moveItems:viewWidth fromIndex:index];
[self setNeedsDisplay:YES];
}
- (void)moveItem:(NSView *)view space:(NSInteger)space {
NSRect rect = [view frame];
rect.origin.x += space;
[view setFrame:rect];
}
- (void)moveItems:(NSInteger) space fromIndex:(NSUInteger)index {
NSArray *subviewArray = [self subviews];
NSUInteger subviewCount = [subviewArray count];
for (; index < subviewCount; ++index)
[self moveItem:[subviewArray objectAtIndex:index] space:space];
}
- (void)addItem:(NSControl *)itemView {
[itemView sizeToFit];
NSRect itemFrame = [itemView frame];
NSView *lastView = [[self subviews] lastObject];
if (lastView != nil) {
itemFrame.origin.x = [lastView frame].origin.x +
[lastView frame].size.width +
hspace;
} else {
itemFrame.origin.x = [self bounds].origin.x + hspace;
}
itemFrame.origin.y = [self bounds].origin.y;
[itemView setFrame:itemFrame];
[self addSubview:itemView];
[self setNeedsDisplay:YES];
}
@end
And This is a simple “Main” to test the HBox.
- (NSTextField *)createTextField:(NSString *)text {
NSTextField *field = [[NSTextField alloc] init];
[field setStringValue:text];
return [field retain];
}
- (NSButton *)createButton:(NSString *)caption {
NSButton *button = [[NSButton alloc] init];
[button setBezelStyle:NSRecessedBezelStyle];
[button setButtonType:NSPushOnPushOffButton];
[[button cell] setHighlightsBy:(NSCellIsBordered | NSCellIsInsetButton)];
[button setShowsBorderOnlyWhileMouseInside:YES];
[button setButtonType:NSOnOffButton];
[button setTitle:caption];
return [button retain];
}
- (void)awakeFromNib {
[box addItem:[self createTextField:@"Label 1"]];
[box addItem:[self createButton:@"Button 1"]];
[box removeItemAtIndex:0];
[box addItem:[self createTextField:@"Label 2"]];
[box addItem:[self createButton:@"Say"]];
}
Download Here the Test Cocoa HBox Source.
