gwenhywfar  4.3.1
CocoaHLayout.m
Go to the documentation of this file.
00001 //
00002 //  CocoaHLayout.m
00003 //  
00004 //
00005 //  Created by Samuel Strupp on 10.08.10.
00006 //
00007 #ifdef HAVE_CONFIG_H
00008 # include <config.h>
00009 #endif
00010 
00011 
00012 #import "CocoaHLayout.h"
00013 
00014 
00015 @implementation CocoaHLayout
00016 
00017 @synthesize fillX;
00018 @synthesize fillY;
00019 
00020 - (id)initWithFrame:(NSRect)frame {
00021     self = [super initWithFrame:frame];
00022     if (self) {
00023                 fillX = NO;
00024                 fillY = NO;
00025                 subviewsInOrder = [[NSMutableArray alloc] init];
00026                 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(layoutSubviews) name:NSViewFrameDidChangeNotification object:self];
00027     }
00028     return self;
00029 }
00030 
00031 -(void) dealloc {
00032         [[NSNotificationCenter defaultCenter] removeObserver:self];
00033         [subviewsInOrder release];
00034         [super dealloc];
00035 }
00036 
00037 /*- (void)drawRect:(NSRect)dirtyRect {
00038         //debug colors
00039     [[NSColor greenColor] set];
00040         NSRectFill(dirtyRect);
00041 }*/
00042 
00043 #define borderDistance 8.0
00044 #define cellDistance 4.0
00045 
00046 -(void) layoutSubviews {
00047         NSRect bounds = [self bounds];
00048         
00049         NSUInteger numOfSubViews = [subviewsInOrder count];
00050         
00051         if (numOfSubViews > 0) {
00052                 //Prepass to compute the sizes
00053                 
00054                 CGFloat sizesHeight[numOfSubViews];
00055                 CGFloat sizesWidth[numOfSubViews];
00056                 CGFloat exclusiveWidth = 0.0;
00057                 NSUInteger exclusiveChilds = 0;
00058                 
00059                 NSUInteger i;
00060                 for (i=0; i<numOfSubViews; i++) {
00061                         NSView* subview = [subviewsInOrder objectAtIndex:i];
00062                         if ([subview conformsToProtocol:@protocol(CocoaGwenGUIProtocol)]) {
00063                                 if ([(<CocoaGwenGUIProtocol>)subview fillX]) sizesWidth[i] = -1.0;
00064                                 else {
00065                                         CGFloat neededWidth = [(<CocoaGwenGUIProtocol>)subview minSize].width;
00066                                         sizesWidth[i] = neededWidth;
00067                                         exclusiveWidth += neededWidth;
00068                                         exclusiveChilds++;
00069                                 }
00070                                 if ([(<CocoaGwenGUIProtocol>)subview fillY]) sizesHeight[i] = -1.0;
00071                                 else {
00072                                         CGFloat neededHeight = [(<CocoaGwenGUIProtocol>)subview minSize].height;
00073                                         sizesHeight[i] = neededHeight;
00074                                 }
00075                         }
00076                         else {
00077                                 sizesWidth[i] = -1.0;
00078                                 sizesHeight[i] = -1.0;
00079                         }
00080                 }
00081                 
00082                 
00083                 //Compute standard Sizes for Subviews
00084                 
00085                 CGFloat stdWidth = 0.0;
00086                 if (numOfSubViews > exclusiveChilds) {
00087                         CGFloat fillWidth = bounds.size.width-exclusiveWidth;
00088                         stdWidth = (fillWidth-(borderDistance+borderDistance)-((numOfSubViews-1)*cellDistance))/(numOfSubViews-exclusiveChilds);
00089                 }
00090                 else {
00091                         CGFloat fillWidth = bounds.size.width;
00092                         stdWidth = (fillWidth-(borderDistance+borderDistance)-((numOfSubViews-1)*cellDistance))/(numOfSubViews);
00093                 }
00094                 
00095                 CGFloat stdHeight = bounds.size.height-(borderDistance+borderDistance);
00096                 
00097                 //if (numOfSubViews>=4) NSLog(@"view.width = %f", bounds.size.width);
00098                 
00099                 //change Subviews Frame
00100                 NSRect actualFrame = bounds;
00101                 actualFrame.origin.x = borderDistance;
00102                 actualFrame.origin.y += bounds.size.height-borderDistance;
00103                 for (i=0; i<numOfSubViews; i++) {
00104                         
00105                         CGFloat usedHeight = sizesHeight[i];
00106                         if (usedHeight < 0.0) usedHeight = stdHeight;
00107                         actualFrame.origin.y = bounds.size.height-borderDistance-usedHeight;
00108                         actualFrame.size.height = usedHeight;
00109                         
00110                         CGFloat usedWidth = sizesWidth[i];
00111                         if (usedWidth < 0.0) usedWidth = stdWidth;
00112                         actualFrame.size.width = usedWidth;
00113                         
00114                         //if (numOfSubViews>=4) NSLog(@"subview %i width = %f", i, usedWidth);
00115                         
00116                         NSView* subview = [subviewsInOrder objectAtIndex:i];
00117                         [subview setFrame:actualFrame];
00118                         actualFrame.origin.x += usedWidth+cellDistance;
00119                 }
00120         }
00121 }
00122 
00123 -(void) addLayoutSubview:(NSView*)new_subview {
00124         [subviewsInOrder addObject:new_subview];
00125         [self addSubview:new_subview];
00126         [self layoutSubviews];
00127 }
00128 
00129 #pragma mark Protocoll Methods
00130 
00131 - (NSSize) minSize {
00132         NSUInteger numOfSubViews = [subviewsInOrder count];
00133         CGFloat borderWidth = borderDistance+borderDistance;
00134         NSSize size = NSMakeSize(borderWidth, borderWidth);
00135         if (numOfSubViews > 0) {
00136                 NSUInteger i;
00137                 for (i=0; i<numOfSubViews; i++) {
00138                         NSView* subview = [subviewsInOrder objectAtIndex:i];
00139                         if ([subview conformsToProtocol:@protocol(CocoaGwenGUIProtocol)]) {
00140                                 NSSize subViewMinSize = [(<CocoaGwenGUIProtocol>)subview minSize];
00141                                 if (subViewMinSize.height+borderWidth > size.height) {
00142                                         size.height = subViewMinSize.height+borderWidth;
00143                                 }
00144                                 size.width += subViewMinSize.width;
00145                                 if (i>0) size.width += cellDistance;
00146                         }
00147                 }
00148         }
00149         return size;
00150 }
00151 
00152 - (void)setFrame:(NSRect)frameRect {
00153         NSSize minSize = [self minSize];
00154         if (frameRect.size.height < minSize.height) {
00155                 frameRect.size.height = minSize.height;
00156         }
00157         if (frameRect.size.width < minSize.width) {
00158                 frameRect.size.width = minSize.width;
00159         }
00160         [super setFrame:frameRect];
00161 }
00162 
00163 @end