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