ui/cocoa/GridLayout.m

changeset 102
64ded9f6a6c6
parent 101
7b3a3130be44
equal deleted inserted replaced
101:7b3a3130be44 102:64ded9f6a6c6
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;

mercurial