gwenhywfar  4.3.3
CocoaVLayout.m
Go to the documentation of this file.
1 //
2 // CocoaVLayout.m
3 //
4 //
5 // Created by Samuel Strupp on 10.08.10.
6 // Copyright 2010 Synium Software GmbH. All rights reserved.
7 //
8 
9 #ifdef HAVE_CONFIG_H
10 # include <config.h>
11 #endif
12 
13 
14 
15 #import "CocoaVLayout.h"
16 #import "CocoaGwenGUIProtocol.h"
17 
18 
19 @implementation CocoaVLayout
20 
21 @synthesize fillX;
22 @synthesize fillY;
23 
24 - (id)initWithFrame:(NSRect)frame {
25  self = [super initWithFrame:frame];
26  if (self) {
27  fillX = NO;
28  fillY = NO;
29  subviewsInOrder = [[NSMutableArray alloc] init];
30  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(layoutSubviews) name:NSViewFrameDidChangeNotification object:self];
31  }
32  return self;
33 }
34 
35 -(void) dealloc {
36  [[NSNotificationCenter defaultCenter] removeObserver:self];
37  [subviewsInOrder release];
38  [super dealloc];
39 }
40 
41 /*- (void)drawRect:(NSRect)dirtyRect {
42  //debug colors
43  [[NSColor redColor] set];
44  NSRectFill(dirtyRect);
45 }*/
46 
47 #define borderDistance 8.0
48 #define cellDistance 4.0
49 
50 -(void) layoutSubviews {
51  NSRect bounds = [self bounds];
52 
53  NSUInteger numOfSubViews = [subviewsInOrder count];
54 
55  if (numOfSubViews > 0) {
56  //Prepass to compute the sizes
57 
58  CGFloat sizesHeight[numOfSubViews];
59  CGFloat sizesWidth[numOfSubViews];
60  CGFloat exclusiveHeight = 0.0;
61  NSUInteger exclusiveChilds = 0;
62 
63  NSUInteger i;
64  for (i=0; i<numOfSubViews; i++) {
65  NSView* subview = [subviewsInOrder objectAtIndex:i];
66  if ([subview conformsToProtocol:@protocol(CocoaGwenGUIProtocol)]) {
67  if ([(<CocoaGwenGUIProtocol>)subview fillX]) sizesWidth[i] = -1.0;
68  else {
69  CGFloat neededWidth = [(<CocoaGwenGUIProtocol>)subview minSize].width;
70  sizesWidth[i] = neededWidth;
71  }
72  if ([(<CocoaGwenGUIProtocol>)subview fillY]) sizesHeight[i] = -1.0;
73  else {
74  CGFloat neededHeight = [(<CocoaGwenGUIProtocol>)subview minSize].height;
75  sizesHeight[i] = neededHeight;
76  exclusiveHeight += neededHeight;
77  exclusiveChilds++;
78  }
79  }
80  else {
81  sizesWidth[i] = -1.0;
82  sizesHeight[i] = -1.0;
83  }
84  }
85 
86 
87  //Compute standard Sizes for Subviews
88 
89  CGFloat stdHeight = 0.0;
90  if (numOfSubViews > exclusiveChilds) {
91  CGFloat fillHeight = bounds.size.height-exclusiveHeight;
92  stdHeight = (fillHeight-(borderDistance+borderDistance)-((numOfSubViews-1)*cellDistance))/(numOfSubViews-exclusiveChilds);
93  }
94  else {
95  CGFloat fillHeight = bounds.size.height;
96  stdHeight = (fillHeight-(borderDistance+borderDistance)-((numOfSubViews-1)*cellDistance))/(numOfSubViews);
97  }
98 
99  CGFloat stdWidth = bounds.size.width-(borderDistance+borderDistance);
100 
101  //if (numOfSubViews>=4) NSLog(@"view.height = %f", bounds.size.height);
102 
103 
104  //change Subviews Frame
105  NSRect actualFrame = bounds;
106  actualFrame.origin.x = borderDistance;
107  actualFrame.origin.y += bounds.size.height-borderDistance;
108  for (i=0; i<numOfSubViews; i++) {
109 
110  CGFloat usedHeight = sizesHeight[i];
111  if (usedHeight < 0.0) usedHeight = stdHeight;
112  actualFrame.origin.y -= usedHeight;
113  actualFrame.size.height = usedHeight;
114 
115  //if (numOfSubViews>=4) NSLog(@"subview %i height = %f", i, usedHeight);
116 
117  CGFloat usedWidth = sizesWidth[i];
118  if (usedWidth < 0.0) usedWidth = stdWidth;
119  NSView* subview = [subviewsInOrder objectAtIndex:i];
120  actualFrame.size.width = usedWidth;
121 
122  [subview setFrame:actualFrame];
123  actualFrame.origin.y -= cellDistance;
124  }
125  }
126 
127 }
128 
129 -(void) addLayoutSubview:(NSView*)new_subview {
130  [subviewsInOrder addObject:new_subview];
131  [self addSubview:new_subview];
132  [self layoutSubviews];
133 }
134 
135 #pragma mark Protocoll Methods
136 
137 - (NSSize) minSize {
138  NSUInteger numOfSubViews = [subviewsInOrder count];
139  CGFloat borderWidth = borderDistance+borderDistance;
140  NSSize size = NSMakeSize(borderWidth, borderWidth);
141  if (numOfSubViews > 0) {
142  NSUInteger i;
143  for (i=0; i<numOfSubViews; i++) {
144  NSView* subview = [subviewsInOrder objectAtIndex:i];
145  if ([subview conformsToProtocol:@protocol(CocoaGwenGUIProtocol)]) {
146  NSSize subViewMinSize = [(<CocoaGwenGUIProtocol>)subview minSize];
147  if (subViewMinSize.width+borderWidth > size.width) {
148  size.width = subViewMinSize.width+borderWidth;
149  }
150  size.height += subViewMinSize.height;
151  if (i>0) size.height += cellDistance;
152  }
153  }
154  }
155  return size;
156 }
157 
158 - (void)setFrame:(NSRect)frameRect {
159  NSSize minSize = [self minSize];
160  if (frameRect.size.height < minSize.height) {
161  frameRect.size.height = minSize.height;
162  }
163  if (frameRect.size.width < minSize.width) {
164  frameRect.size.width = minSize.width;
165  }
166  [super setFrame:frameRect];
167 }
168 
169 @end