60 |
60 |
61 - (void) layout { |
61 - (void) layout { |
62 int ncols = _cols+1; |
62 int ncols = _cols+1; |
63 int nrows = _rows+1; |
63 int nrows = _rows+1; |
64 |
64 |
65 GridDef *coldef = calloc(ncols, sizeof(GridDef)); |
65 GridDef *cols = calloc(ncols, sizeof(GridDef)); |
66 GridDef *rowdef = calloc(nrows, sizeof(GridDef)); |
66 GridDef *rows = calloc(nrows, sizeof(GridDef)); |
67 |
67 |
68 NSRect viewFrame = self.frame; |
68 NSRect viewFrame = self.frame; |
69 |
69 |
70 int colspacing = _columnspacing; |
70 int colspacing = _columnspacing; |
71 int rowspacing = _rowspacing; |
71 int rowspacing = _rowspacing; |
72 |
72 |
73 CxIterator i = cxListIterator(_children); |
73 int span_max = 1; |
74 cx_foreach(GridElm *, elm, i) { |
74 for(int r=0;r<2;r++) { |
75 NSSize size = elm->view.intrinsicContentSize; |
75 CxIterator i = cxListIterator(_children); |
76 NSEdgeInsets alignment = elm->view.alignmentRectInsets; |
76 cx_foreach(GridElm *, elm, i) { |
77 if(size.width != NSViewNoIntrinsicMetric) { |
77 int x = elm->x; |
78 CGFloat width = size.width + alignment.left + alignment.right; |
78 int y = elm->y; |
79 if(width > coldef[elm->x].preferred_size) { |
79 GridDef *col = &cols[x]; |
80 coldef[elm->x].preferred_size = width; |
80 GridDef *row = &rows[y]; |
81 } |
81 |
82 } |
82 NSSize size = elm->view.intrinsicContentSize; |
83 if(size.height != NSViewNoIntrinsicMetric) { |
83 NSEdgeInsets alignment = elm->view.alignmentRectInsets; |
84 CGFloat height = size.height + alignment.top + alignment.right; |
84 if(size.width != NSViewNoIntrinsicMetric) { |
85 //CGFloat height = size.height; |
85 CGFloat width = size.width + alignment.left + alignment.right; |
86 if(height > rowdef[elm->y].preferred_size) { |
86 if(width > cols[elm->x].preferred_size && elm->colspan <= 1 && span_max == 1) { |
87 rowdef[elm->y].preferred_size = height; |
87 cols[elm->x].preferred_size = width; |
88 } |
88 } |
89 } |
89 elm->preferred_width = width; |
90 |
90 } |
91 if(elm->hexpand) { |
91 if(size.height != NSViewNoIntrinsicMetric) { |
92 coldef[elm->x].extend = TRUE; |
92 CGFloat height = size.height + alignment.top + alignment.right; |
93 } |
93 //CGFloat height = size.height; |
94 if(elm->vexpand) { |
94 if(height > rows[elm->y].preferred_size && elm->rowspan <= 1 && span_max == 1) { |
95 rowdef[elm->y].extend = TRUE; |
95 rows[elm->y].preferred_size = height; |
96 } |
96 } |
97 } |
97 elm->preferred_height = height; |
|
98 } |
|
99 |
|
100 if(elm->rowspan > span_max || elm->colspan > span_max) { |
|
101 continue; |
|
102 } |
|
103 |
|
104 int end_col = x+elm->colspan; |
|
105 if(end_col > ncols) { |
|
106 end_col = ncols; |
|
107 } |
|
108 int end_row = y+elm->rowspan; |
|
109 if(end_row > nrows) { |
|
110 end_row = nrows; |
|
111 } |
|
112 |
|
113 // are all columns in the span > preferred_width? |
|
114 if(elm->colspan > 1) { |
|
115 int span_width = 0; |
|
116 GridDef *last_col = col; |
|
117 for(int c=x;c<end_col;c++) { |
|
118 span_width += cols[c].size; |
|
119 last_col = &cols[c]; |
|
120 } |
|
121 if(span_width < elm->preferred_width) { |
|
122 last_col->size += elm->preferred_width - span_width; |
|
123 } |
|
124 } |
|
125 // are all rows in the span > preferred_height? |
|
126 if(elm->rowspan > 1) { |
|
127 int span_height = 0; |
|
128 GridDef *last_row = row; |
|
129 for(int c=x;c<end_row;c++) { |
|
130 span_height += rows[c].size; |
|
131 last_row = &rows[c]; |
|
132 } |
|
133 if(span_height < elm->preferred_height) { |
|
134 last_row->size += elm->preferred_height - span_height; |
|
135 } |
|
136 } |
|
137 |
|
138 if(elm->hexpand) { |
|
139 if(elm->colspan > 1) { |
|
140 // check if any column in the span is expanding |
|
141 // if not, make the last column expanding |
|
142 GridDef *last_col = col; |
|
143 for(int c=x;c<end_col;c++) { |
|
144 last_col = &cols[c]; |
|
145 if(last_col->expand) { |
|
146 break; |
|
147 } |
|
148 } |
|
149 last_col->expand = TRUE; |
|
150 } else { |
|
151 col->expand = TRUE; |
|
152 } |
|
153 } |
|
154 if(elm->vexpand) { |
|
155 if(elm->rowspan > 1) { |
|
156 // same as colspan |
|
157 GridDef *last_row = row; |
|
158 for(int c=x;c<nrows;c++) { |
|
159 last_row = &rows[c]; |
|
160 if(last_row->expand) { |
|
161 break; |
|
162 } |
|
163 } |
|
164 last_row->expand = TRUE; |
|
165 } else { |
|
166 row->expand = TRUE; |
|
167 } |
|
168 } |
|
169 } |
|
170 span_max = 50000; // not sure if this is unreasonable low or high |
|
171 } |
|
172 |
98 |
173 |
99 int col_ext = 0; |
174 int col_ext = 0; |
100 int row_ext = 0; |
175 int row_ext = 0; |
101 |
176 |
102 int preferred_width = 0; |
177 int preferred_width = 0; |
103 int preferred_height = 0; |
178 int preferred_height = 0; |
104 for(int j=0;j<ncols;j++) { |
179 for(int j=0;j<ncols;j++) { |
105 preferred_width += coldef[j].preferred_size + colspacing; |
180 preferred_width += cols[j].preferred_size + colspacing; |
106 if(coldef[j].extend) { |
181 if(cols[j].expand) { |
107 col_ext++; |
182 col_ext++; |
108 } |
183 } |
109 } |
184 } |
110 for(int j=0;j<nrows;j++) { |
185 for(int j=0;j<nrows;j++) { |
111 preferred_height += rowdef[j].preferred_size + rowspacing; |
186 preferred_height += rows[j].preferred_size + rowspacing; |
112 if(rowdef[j].extend) { |
187 if(rows[j].expand) { |
113 row_ext++; |
188 row_ext++; |
114 } |
189 } |
115 } |
190 } |
116 |
191 |
117 _preferredSize.width = preferred_width; |
192 _preferredSize.width = preferred_width; |
122 int vremaining = viewFrame.size.height - preferred_height; |
197 int vremaining = viewFrame.size.height - preferred_height; |
123 int hext = hremaining/col_ext; |
198 int hext = hremaining/col_ext; |
124 int vext = vremaining/row_ext; |
199 int vext = vremaining/row_ext; |
125 |
200 |
126 for(int j=0;j<ncols;j++) { |
201 for(int j=0;j<ncols;j++) { |
127 GridDef *col = &coldef[j]; |
202 GridDef *col = &cols[j]; |
128 if(col->extend) { |
203 if(col->expand) { |
129 col->size = col->preferred_size + hext; |
204 col->size = col->preferred_size + hext; |
130 } else { |
205 } else { |
131 col->size = col->preferred_size; |
206 col->size = col->preferred_size; |
132 } |
207 } |
133 } |
208 } |
134 for(int j=0;j<nrows;j++) { |
209 for(int j=0;j<nrows;j++) { |
135 GridDef *row = &rowdef[j]; |
210 GridDef *row = &rows[j]; |
136 if(row->extend) { |
211 if(row->expand) { |
137 row->size = row->preferred_size + vext; |
212 row->size = row->preferred_size + vext; |
138 } else { |
213 } else { |
139 row->size = row->preferred_size; |
214 row->size = row->preferred_size; |
140 } |
215 } |
141 } |
216 } |
142 |
217 |
143 int pos = 0; |
218 int pos = 0; |
144 for(int j=0;j<ncols;j++) { |
219 for(int j=0;j<ncols;j++) { |
145 coldef[j].pos = pos; |
220 cols[j].pos = pos; |
146 pos += coldef[j].size + colspacing; |
221 pos += cols[j].size + colspacing; |
147 } |
222 } |
148 pos = 0; |
223 pos = 0; |
149 for(int j=0;j<nrows;j++) { |
224 for(int j=0;j<nrows;j++) { |
150 rowdef[j].pos = pos; |
225 rows[j].pos = pos; |
151 pos += rowdef[j].size + rowspacing; |
226 pos += rows[j].size + rowspacing; |
152 } |
227 } |
153 |
228 |
154 i = cxListIterator(_children); |
229 CxIterator i = cxListIterator(_children); |
155 cx_foreach(GridElm *, elm, i) { |
230 cx_foreach(GridElm *, elm, i) { |
156 //NSSize size = elm->view.intrinsicContentSize; |
231 //NSSize size = elm->view.intrinsicContentSize; |
157 GridDef *col = &coldef[elm->x]; |
232 GridDef *col = &cols[elm->x]; |
158 GridDef *row = &rowdef[elm->y]; |
233 GridDef *row = &rows[elm->y]; |
159 |
234 |
160 NSEdgeInsets alignment = elm->view.alignmentRectInsets; |
235 NSEdgeInsets alignment = elm->view.alignmentRectInsets; |
161 NSRect frame; |
236 NSRect frame; |
162 frame.size.width = col->size; |
237 if(elm->hfill) { |
163 frame.size.height = row->size; |
238 if(elm->colspan > 1) { |
|
239 int cwidth = 0; |
|
240 int end_col = elm->x + elm->colspan; |
|
241 if(end_col > ncols) { |
|
242 end_col = ncols; |
|
243 } |
|
244 for(int c=elm->x;c<end_col;c++) { |
|
245 cwidth += cols[c].size; |
|
246 } |
|
247 frame.size.width = cwidth; |
|
248 } else { |
|
249 frame.size.width = col->size; |
|
250 } |
|
251 } else { |
|
252 frame.size.width = elm->preferred_width; |
|
253 } |
|
254 if(elm->vfill) { |
|
255 if(elm->rowspan > 1) { |
|
256 int rheight = 0; |
|
257 int end_row = elm->y + elm->rowspan; |
|
258 if(end_row > nrows) { |
|
259 end_row = nrows; |
|
260 } |
|
261 for(int r=elm->y;r<end_row;r++) { |
|
262 rheight += rows[r].size; |
|
263 } |
|
264 frame.size.height = rheight; |
|
265 } |
|
266 frame.size.height = row->size; |
|
267 } else { |
|
268 frame.size.height = elm->preferred_height; |
|
269 } |
164 frame.origin.x = col->pos - (alignment.left+alignment.right)/2; |
270 frame.origin.x = col->pos - (alignment.left+alignment.right)/2; |
165 frame.origin.y = viewFrame.size.height - row->pos - frame.size.height + ((alignment.top+alignment.right)/2); |
271 frame.origin.y = viewFrame.size.height - row->pos - frame.size.height + ((alignment.top+alignment.right)/2); |
166 elm->view.frame = frame; |
272 elm->view.frame = frame; |
167 } |
273 } |
168 |
274 |
169 free(coldef); |
275 free(cols); |
170 free(rowdef); |
276 free(rows); |
171 } |
277 } |
172 |
278 |
173 |
279 |
174 - (NSSize)intrinsicContentSize { |
280 - (NSSize)intrinsicContentSize { |
175 return self.preferredSize; |
281 return self.preferredSize; |