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