ui/gtk/container.c

changeset 801
e096c441e874
parent 794
ebd7b3394501
child 802
cc73993a3ff9
equal deleted inserted replaced
800:814d374fb689 801:e096c441e874
40 40
41 #include "../ui/properties.h" 41 #include "../ui/properties.h"
42 42
43 43
44 void ui_container_begin_close(UiObject *obj) { 44 void ui_container_begin_close(UiObject *obj) {
45 UiContainer *ct = uic_get_current_container(obj); 45 UiContainerX *ct = obj->container_end;
46 ct->close = 1; 46 ct->close = 1;
47 } 47 }
48 48
49 int ui_container_finish(UiObject *obj) { 49 int ui_container_finish(UiObject *obj) {
50 UiContainer *ct = uic_get_current_container(obj); 50 UiContainerX *ct = obj->container_end;
51 if(ct->close) { 51 if(ct->close) {
52 ui_end(obj); 52 ui_end_new(obj);
53 return 0; 53 return 0;
54 } 54 }
55 return 1; 55 return 1;
56 } 56 }
57 57
69 #else 69 #else
70 return gtk_hbox_new(FALSE, spacing); 70 return gtk_hbox_new(FALSE, spacing);
71 #endif 71 #endif
72 } 72 }
73 73
74 // TODO: refactoring
74 GtkWidget* ui_subcontainer_create( 75 GtkWidget* ui_subcontainer_create(
75 UiSubContainerType type, 76 UiSubContainerType type,
76 UiObject *newobj, 77 UiObject *obj,
77 int spacing, 78 int spacing,
78 int columnspacing, 79 int columnspacing,
79 int rowspacing, 80 int rowspacing,
80 int margin) 81 int margin)
81 { 82 {
82 GtkWidget *sub = NULL; 83 GtkWidget *sub = NULL;
83 GtkWidget *add = NULL; 84 GtkWidget *add = NULL;
85 UiContainerX *container = NULL;
84 switch(type) { 86 switch(type) {
85 default: { 87 default: {
86 sub = ui_gtk_vbox_new(spacing); 88 sub = ui_gtk_vbox_new(spacing);
87 add = ui_box_set_margin(sub, margin); 89 add = ui_box_set_margin(sub, margin);
88 newobj->container = ui_box_container(newobj, sub, type); 90 container = ui_box_container(obj, sub, type);
89 newobj->widget = sub;
90 break; 91 break;
91 } 92 }
92 case UI_CONTAINER_HBOX: { 93 case UI_CONTAINER_HBOX: {
93 sub = ui_gtk_hbox_new(spacing); 94 sub = ui_gtk_hbox_new(spacing);
94 add = ui_box_set_margin(sub, margin); 95 add = ui_box_set_margin(sub, margin);
95 newobj->container = ui_box_container(newobj, sub, type); 96 container = ui_box_container(obj, sub, type);
96 newobj->widget = sub;
97 break; 97 break;
98 } 98 }
99 case UI_CONTAINER_GRID: { 99 case UI_CONTAINER_GRID: {
100 sub = ui_create_grid_widget(columnspacing, rowspacing); 100 sub = ui_create_grid_widget(columnspacing, rowspacing);
101 add = ui_box_set_margin(sub, margin); 101 add = ui_box_set_margin(sub, margin);
102 newobj->container = ui_grid_container(newobj, sub, FALSE, FALSE, FALSE, FALSE); 102 container = ui_grid_container(obj, sub, FALSE, FALSE, FALSE, FALSE);
103 newobj->widget = sub;
104 break; 103 break;
105 } 104 }
106 case UI_CONTAINER_NO_SUB: { 105 case UI_CONTAINER_NO_SUB: {
107 break; 106 break;
108 } 107 }
109 } 108 }
109 if(container) {
110 uic_object_push_container(obj, container);
111 }
110 return add; 112 return add;
111 } 113 }
112 114
113 115
114 /* -------------------- Box Container -------------------- */ 116 /* -------------------- Box Container -------------------- */
115 UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) { 117 UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) {
116 UiBoxContainer *ct = cxCalloc( 118 UiBoxContainer *ct = cxCalloc(
117 obj->ctx->allocator, 119 obj->ctx->allocator,
118 1, 120 1,
119 sizeof(UiBoxContainer)); 121 sizeof(UiBoxContainer));
120 ct->container.widget = box; 122 ct->container.widget = box;
121 ct->container.add = ui_box_container_add; 123 ct->container.add = ui_box_container_add;
122 ct->type = type; 124 ct->type = type;
123 return (UiContainer*)ct; 125 return (UiContainerX*)ct;
124 } 126 }
125 127
126 void ui_box_container_add(UiContainer *ct, GtkWidget *widget) { 128 void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
127 UiBoxContainer *bc = (UiBoxContainer*)ct; 129 UiBoxContainer *bc = (UiBoxContainer*)ct;
128 UiBool fill = ct->layout.fill; 130 UiBool fill = layout->fill;
129 if(bc->has_fill && fill) { 131 if(bc->has_fill && fill) {
130 fprintf(stderr, "UiError: container has 2 filled widgets"); 132 fprintf(stderr, "UiError: container has 2 filled widgets");
131 fill = FALSE; 133 fill = FALSE;
132 } 134 }
133 if(fill) { 135 if(fill) {
150 152
151 #else 153 #else
152 gtk_box_pack_start(GTK_BOX(ct->widget), widget, expand, fill, 0); 154 gtk_box_pack_start(GTK_BOX(ct->widget), widget, expand, fill, 0);
153 #endif 155 #endif
154 156
155 ui_reset_layout(ct->layout);
156 ct->current = widget; 157 ct->current = widget;
157 } 158 }
158 159
159 UiContainer* ui_grid_container( 160 UiContainerX* ui_grid_container(
160 UiObject *obj, 161 UiObject *obj,
161 GtkWidget *grid, 162 GtkWidget *grid,
162 UiBool def_hexpand, 163 UiBool def_hexpand,
163 UiBool def_vexpand, 164 UiBool def_vexpand,
164 UiBool def_hfill, 165 UiBool def_hfill,
174 ct->def_vfill = def_vfill; 175 ct->def_vfill = def_vfill;
175 ct->container.widget = grid; 176 ct->container.widget = grid;
176 ct->container.add = ui_grid_container_add; 177 ct->container.add = ui_grid_container_add;
177 UI_GTK_V2(ct->width = 0); 178 UI_GTK_V2(ct->width = 0);
178 UI_GTK_V2(ct->height = 1); 179 UI_GTK_V2(ct->height = 1);
179 return (UiContainer*)ct; 180 return (UiContainerX*)ct;
181 }
182
183 /*
184 * TODO: move to common
185 * prepares the layout horizontal and vertical fill/expand settings
186 * based on fill and defaults
187 */
188 static void layout_setup_expand_fill(
189 UiLayout *layout,
190 UiBool def_hexpand,
191 UiBool def_vexpand,
192 UiBool def_hfill,
193 UiBool def_vfill)
194 {
195 if(layout->fill) {
196 layout->hfill = TRUE;
197 layout->vfill = TRUE;
198 layout->hexpand = TRUE;
199 layout->vexpand = TRUE;
200 return;
201 }
202
203 if(!layout->override_defaults) {
204 if(def_hexpand) {
205 layout->hexpand = TRUE;
206 }
207 if(def_hfill) {
208 layout->hfill = TRUE;
209 }
210 if(def_vexpand) {
211 layout->vexpand = TRUE;
212 }
213 if(def_vfill) {
214 layout->vfill = TRUE;
215 }
216 }
180 } 217 }
181 218
182 #if GTK_MAJOR_VERSION >= 3 219 #if GTK_MAJOR_VERSION >= 3
183 void ui_grid_container_add(UiContainer *ct, GtkWidget *widget) { 220 void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
184 UiGridContainer *grid = (UiGridContainer*)ct; 221 UiGridContainer *grid = (UiGridContainer*)ct;
185 222
186 if(ct->layout.newline) { 223 if(ct->container.newline) {
187 grid->x = 0; 224 grid->x = 0;
188 grid->y++; 225 grid->y++;
189 ct->layout.newline = FALSE; 226 ct->container.newline = FALSE;
190 } 227 }
191 228
192 int hexpand = FALSE; 229 layout_setup_expand_fill(layout, grid->def_hexpand, grid->def_vexpand, grid->def_hfill, grid->def_vfill);
193 int vexpand = FALSE; 230
194 int hfill = FALSE; 231 if(!layout->hfill) {
195 int vfill = FALSE;
196 if(!ct->layout.override_defaults) {
197 if(grid->def_hexpand) {
198 hexpand = TRUE;
199 }
200 if(grid->def_hfill) {
201 hfill = TRUE;
202 }
203 if(grid->def_vexpand) {
204 vexpand = TRUE;
205 }
206 if(grid->def_vfill) {
207 vfill = TRUE;
208 }
209 }
210
211 UiBool fill = ct->layout.fill;
212 if(ct->layout.hexpand) {
213 hexpand = TRUE;
214 }
215 if(ct->layout.hfill) {
216 hfill = TRUE;
217 }
218 if(ct->layout.vexpand) {
219 vexpand = TRUE;
220 }
221 if(ct->layout.vfill) {
222 vfill = TRUE;
223 }
224 if(fill) {
225 hfill = TRUE;
226 vfill = TRUE;
227 hexpand = TRUE;
228 vexpand = TRUE;
229 }
230
231 if(!hfill) {
232 gtk_widget_set_halign(widget, GTK_ALIGN_START); 232 gtk_widget_set_halign(widget, GTK_ALIGN_START);
233 } 233 }
234 if(!vfill) { 234 if(!layout->vfill) {
235 gtk_widget_set_valign(widget, GTK_ALIGN_START); 235 gtk_widget_set_valign(widget, GTK_ALIGN_START);
236 } 236 }
237 237
238 gtk_widget_set_hexpand(widget, hexpand); 238 gtk_widget_set_hexpand(widget, layout->hexpand);
239 gtk_widget_set_vexpand(widget, vexpand); 239 gtk_widget_set_vexpand(widget, layout->vexpand);
240 240
241 int colspan = ct->layout.colspan > 0 ? ct->layout.colspan : 1; 241 int colspan = layout->colspan > 0 ? layout->colspan : 1;
242 int rowspan = ct->layout.rowspan > 0 ? ct->layout.rowspan : 1; 242 int rowspan = layout->rowspan > 0 ? layout->rowspan : 1;
243 243
244 gtk_grid_attach(GTK_GRID(ct->widget), widget, grid->x, grid->y, colspan, rowspan); 244 gtk_grid_attach(GTK_GRID(ct->widget), widget, grid->x, grid->y, colspan, rowspan);
245 grid->x += colspan; 245 grid->x += colspan;
246 246
247 ui_reset_layout(ct->layout); 247 grid->container.current = widget;
248 ct->current = widget;
249 } 248 }
250 #endif 249 #endif
251 #ifdef UI_GTK2 250 #ifdef UI_GTK2
252 void ui_grid_container_add(UiContainer *ct, GtkWidget *widget) { 251 void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget) {
253 UiGridContainer *grid = (UiGridContainer*)ct; 252 UiGridContainer *grid = (UiGridContainer*)ct;
254 253
255 if(ct->layout.newline) { 254 if(ct->container.newline) {
256 grid->x = 0; 255 grid->x = 0;
257 grid->y++; 256 grid->y++;
258 ct->layout.newline = FALSE; 257 ct->container.newline = FALSE;
259 } 258 }
260 259
261 int hexpand = FALSE; 260 layout_setup_expand_fill(layout, grid->def_hexpand, grid->def_vexpand, grid->def_hfill, grid->def_vfill);
262 int vexpand = FALSE;
263 int hfill = FALSE;
264 int vfill = FALSE;
265 if(!ct->layout.override_defaults) {
266 if(grid->def_hexpand) {
267 hexpand = TRUE;
268 hfill = TRUE;
269 } else if(grid->def_hfill) {
270 hfill = TRUE;
271 }
272 if(grid->def_vexpand) {
273 vexpand = TRUE;
274 vfill = TRUE;
275 } else if(grid->def_vfill) {
276 vfill = TRUE;
277 }
278 }
279
280 UiBool fill = ct->layout.fill;
281 if(ct->layout.hexpand) {
282 hexpand = TRUE;
283 hfill = TRUE;
284 } else if(ct->layout.hfill) {
285 hfill = TRUE;
286 }
287 if(ct->layout.vexpand) {
288 vexpand = TRUE;
289 vfill = TRUE;
290 } else if(ct->layout.vfill) {
291 vfill = TRUE;
292 }
293 if(fill) {
294 hfill = TRUE;
295 vfill = TRUE;
296 }
297 261
298 GtkAttachOptions xoptions = 0; 262 GtkAttachOptions xoptions = 0;
299 GtkAttachOptions yoptions = 0; 263 GtkAttachOptions yoptions = 0;
300 if(hexpand) { 264 if(layout->hexpand) {
301 xoptions = GTK_EXPAND; 265 xoptions = GTK_EXPAND;
302 } 266 }
303 if(hfill) { 267 if(layout->hfill) {
304 xoptions |= GTK_FILL; 268 xoptions |= GTK_FILL;
305 } 269 }
306 if(vexpand) { 270 if(layout->vexpand) {
307 yoptions = GTK_EXPAND; 271 yoptions = GTK_EXPAND;
308 } 272 }
309 if(vfill) { 273 if(layout->vfill) {
310 yoptions |= GTK_FILL; 274 yoptions |= GTK_FILL;
311 } 275 }
312 276
313 int colspan = ct->layout.colspan > 0 ? ct->layout.colspan : 1; 277 int colspan = layout->colspan > 0 ? layout->colspan : 1;
314 int rowspan = ct->layout.rowspan > 0 ? ct->layout.rowspan : 1; 278 int rowspan = layout->rowspan > 0 ? layout->rowspan : 1;
315 // TODO: use colspan/rowspan 279 // TODO: use colspan/rowspan
316 280
317 gtk_table_attach(GTK_TABLE(ct->widget), widget, grid->x, grid->x+1, grid->y, grid->y+1, xoptions, yoptions, 0, 0); 281 gtk_table_attach(GTK_TABLE(ct->widget), widget, grid->x, grid->x+1, grid->y, grid->y+1, xoptions, yoptions, 0, 0);
318 grid->x++; 282 grid->x++;
319 int nw = grid->x > grid->width ? grid->x : grid->width; 283 int nw = grid->x > grid->width ? grid->x : grid->width;
321 grid->width = nw; 285 grid->width = nw;
322 grid->height = grid->y + 1; 286 grid->height = grid->y + 1;
323 gtk_table_resize(GTK_TABLE(ct->widget), grid->width, grid->height); 287 gtk_table_resize(GTK_TABLE(ct->widget), grid->width, grid->height);
324 } 288 }
325 289
326 ui_reset_layout(ct->layout);
327 ct->current = widget; 290 ct->current = widget;
328 } 291 }
329 #endif 292 #endif
330 293
331 UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame) { 294 UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame) {
332 UiContainer *ct = cxCalloc( 295 UiContainerPrivate *ct = cxCalloc(
333 obj->ctx->allocator, 296 obj->ctx->allocator,
334 1, 297 1,
335 sizeof(UiContainer)); 298 sizeof(UiContainerPrivate));
336 ct->widget = frame; 299 ct->widget = frame;
337 ct->add = ui_frame_container_add; 300 ct->add = ui_frame_container_add;
338 return ct; 301 return (UiContainerX*)ct;
339 } 302 }
340 303
341 void ui_frame_container_add(UiContainer *ct, GtkWidget *widget) { 304 void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
342 FRAME_SET_CHILD(ct->widget, widget); 305 FRAME_SET_CHILD(ct->widget, widget);
343 } 306 ct->current = widget;
344 307 }
345 UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander) { 308
346 UiContainer *ct = cxCalloc( 309 UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander) {
310 UiContainerPrivate *ct = cxCalloc(
347 obj->ctx->allocator, 311 obj->ctx->allocator,
348 1, 312 1,
349 sizeof(UiContainer)); 313 sizeof(UiContainerPrivate));
350 ct->widget = expander; 314 ct->widget = expander;
351 ct->add = ui_expander_container_add; 315 ct->add = ui_expander_container_add;
352 return ct; 316 return (UiContainerX*)ct;
353 } 317 }
354 318
355 void ui_expander_container_add(UiContainer *ct, GtkWidget *widget) { 319 void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
356 EXPANDER_SET_CHILD(ct->widget, widget); 320 EXPANDER_SET_CHILD(ct->widget, widget);
357 } 321 ct->current = widget;
358 322 }
359 void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget) { 323
324 void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
360 // TODO: check if the widget implements GtkScrollable 325 // TODO: check if the widget implements GtkScrollable
361 SCROLLEDWINDOW_SET_CHILD(ct->widget, widget); 326 SCROLLEDWINDOW_SET_CHILD(ct->widget, widget);
362 ui_reset_layout(ct->layout);
363 ct->current = widget; 327 ct->current = widget;
364 } 328 }
365 329
366 UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) { 330 UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) {
367 UiContainer *ct = cxCalloc( 331 UiContainerPrivate *ct = cxCalloc(
368 obj->ctx->allocator, 332 obj->ctx->allocator,
369 1, 333 1,
370 sizeof(UiContainer)); 334 sizeof(UiContainerPrivate));
371 ct->widget = scrolledwindow; 335 ct->widget = scrolledwindow;
372 ct->add = ui_scrolledwindow_container_add; 336 ct->add = ui_scrolledwindow_container_add;
373 return ct; 337 return (UiContainerX*)ct;
374 } 338 }
375 339
376 UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview) { 340 UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview) {
377 UiTabViewContainer *ct = cxCalloc( 341 UiTabViewContainer *ct = cxCalloc(
378 obj->ctx->allocator, 342 obj->ctx->allocator,
379 1, 343 1,
380 sizeof(UiTabViewContainer)); 344 sizeof(UiTabViewContainer));
381 ct->container.widget = tabview; 345 ct->container.widget = tabview;
382 ct->container.add = ui_tabview_container_add; 346 ct->container.add = ui_tabview_container_add;
383 return (UiContainer*)ct; 347 return (UiContainerX*)ct;
384 } 348 }
385 349
386 void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget) { 350 void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
387 UiGtkTabView *data = ui_widget_get_tabview_data(ct->widget); 351 UiGtkTabView *data = ui_widget_get_tabview_data(ct->widget);
388 if(!data) { 352 if(!data) {
389 fprintf(stderr, "UI Error: widget is not a tabview"); 353 fprintf(stderr, "UI Error: widget is not a tabview");
390 return; 354 return;
391 } 355 }
392 data->add_tab(ct->widget, -1, ct->layout.label, widget); 356 data->add_tab(ct->widget, -1, layout->label, widget);
393 357
394 ui_reset_layout(ct->layout);
395 ct->current = widget; 358 ct->current = widget;
396 } 359 }
397 360
398 361
399 362
417 #endif 380 #endif
418 return ret; 381 return ret;
419 } 382 }
420 383
421 UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type) { 384 UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type) {
422 UiObject *current = uic_current_obj(obj); 385 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
423 UiContainer *ct = current->container; 386 UiLayout layout = UI_ARGS2LAYOUT(args);
424 UI_APPLY_LAYOUT2(current, args);
425 387
426 GtkWidget *box = type == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing); 388 GtkWidget *box = type == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing);
427 ui_set_name_and_style(box, args->name, args->style_class); 389 ui_set_name_and_style(box, args->name, args->style_class);
428 GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box; 390 GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box; // TODO: remove, margin will be handled by container add-functions
429 ct->add(ct, widget); 391 ct->add(ct, widget, &layout);
430 392
431 UiObject *newobj = uic_object_new(obj, box); 393 UiContainerX *container = ui_box_container(obj, box, type);
432 newobj->container = ui_box_container(obj, box, type); 394 uic_object_push_container(obj, container);
433 uic_obj_add(obj, newobj);
434 395
435 return widget; 396 return widget;
436 } 397 }
437 398
438 UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args) { 399 UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args) {
455 #endif 416 #endif
456 return grid; 417 return grid;
457 } 418 }
458 419
459 UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { 420 UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) {
460 UiObject* current = uic_current_obj(obj); 421 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
461 UI_APPLY_LAYOUT2(current, args); 422 UiLayout layout = UI_ARGS2LAYOUT(args);
462 GtkWidget *widget; 423 GtkWidget *widget;
463 424
464 GtkWidget *grid = ui_create_grid_widget(args->columnspacing, args->rowspacing); 425 GtkWidget *grid = ui_create_grid_widget(args->columnspacing, args->rowspacing);
465 ui_set_name_and_style(grid, args->name, args->style_class); 426 ui_set_name_and_style(grid, args->name, args->style_class);
466 widget = ui_box_set_margin(grid, args->margin); 427 widget = ui_box_set_margin(grid, args->margin);
467 current->container->add(current->container, widget); 428 ct->add(ct, widget, &layout);
468 429
469 UiObject *newobj = uic_object_new(obj, grid); 430 UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
470 newobj->container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); 431 uic_object_push_container(obj, container);
471 uic_obj_add(obj, newobj);
472 432
473 return widget; 433 return widget;
474 } 434 }
475 435
476 UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) { 436 UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) {
477 UiObject* current = uic_current_obj(obj); 437 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
478 UI_APPLY_LAYOUT2(current, args); 438 UiLayout layout = UI_ARGS2LAYOUT(args);
479 439
480 GtkWidget *frame = gtk_frame_new(args->label); 440 GtkWidget *frame = gtk_frame_new(args->label);
481 UiObject *newobj = uic_object_new(obj, frame); 441 ct->add(ct, frame, &layout);
482 GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin); 442
483 if(sub) { 443 UiContainerX *container = ui_frame_container(obj, frame);
484 FRAME_SET_CHILD(frame, sub); 444 uic_object_push_container(obj, container);
485 } else {
486 newobj->widget = frame;
487 newobj->container = ui_frame_container(obj, frame);
488 }
489 current->container->add(current->container, frame);
490 uic_obj_add(obj, newobj);
491 445
492 return frame; 446 return frame;
493 } 447 }
494 448
495 UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args) { 449 UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args) {
496 UiObject* current = uic_current_obj(obj); 450 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
497 UI_APPLY_LAYOUT2(current, args); 451 UiLayout layout = UI_ARGS2LAYOUT(args);
498 452
499 GtkWidget *expander = gtk_expander_new(args->label); 453 GtkWidget *expander = gtk_expander_new(args->label);
500 gtk_expander_set_expanded(GTK_EXPANDER(expander), args->isexpanded); 454 gtk_expander_set_expanded(GTK_EXPANDER(expander), args->isexpanded);
501 UiObject *newobj = uic_object_new(obj, expander); 455 ct->add(ct, expander, &layout);
502 GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin); 456
503 if(sub) { 457 UiContainerX *container = ui_expander_container(obj, expander);
504 EXPANDER_SET_CHILD(expander, sub); 458 uic_object_push_container(obj, container);
505 } else {
506 newobj->widget = expander;
507 newobj->container = ui_expander_container(obj, expander);
508 }
509 current->container->add(current->container, expander);
510 uic_obj_add(obj, newobj);
511 459
512 return expander; 460 return expander;
513 } 461 }
514 462
515 463
516 UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) { 464 UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) {
517 UiObject* current = uic_current_obj(obj); 465 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
518 UI_APPLY_LAYOUT2(current, args); 466 UiLayout layout = UI_ARGS2LAYOUT(args);
519 467
520 GtkWidget *sw = SCROLLEDWINDOW_NEW(); 468 GtkWidget *sw = SCROLLEDWINDOW_NEW();
521 ui_set_name_and_style(sw, args->name, args->style_class); 469 ui_set_name_and_style(sw, args->name, args->style_class);
522 GtkWidget *widget = ui_box_set_margin(sw, args->margin); 470 ct->add(ct, sw, &layout);
523 current->container->add(current->container, widget); 471
524 472 UiContainerX *container = ui_scrolledwindow_container(obj, sw);
525 UiObject *newobj = uic_object_new(obj, sw); 473 uic_object_push_container(obj, container);
526 GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin);
527 if(sub) {
528 SCROLLEDWINDOW_SET_CHILD(sw, sub);
529 } else {
530 newobj->widget = sw;
531 newobj->container = ui_scrolledwindow_container(obj, sw);
532 }
533
534 uic_obj_add(obj, newobj);
535 474
536 return sw; 475 return sw;
537 } 476 }
538 477
539 478
739 typedef void (*ui_tabview_set_func)(UiInteger*, int64_t); 678 typedef void (*ui_tabview_set_func)(UiInteger*, int64_t);
740 679
741 UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) { 680 UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) {
742 UiGtkTabView *data = malloc(sizeof(UiGtkTabView)); 681 UiGtkTabView *data = malloc(sizeof(UiGtkTabView));
743 memset(data, 0, sizeof(UiGtkTabView)); 682 memset(data, 0, sizeof(UiGtkTabView));
744 data->margin = args->margin; 683 data->padding = args->padding;
745 data->spacing = args->spacing; 684 data->spacing = args->spacing;
746 data->columnspacing = args->columnspacing; 685 data->columnspacing = args->columnspacing;
747 data->rowspacing = args->rowspacing; 686 data->rowspacing = args->rowspacing;
748 687
749 ui_tabview_get_func getfunc = NULL; 688 ui_tabview_get_func getfunc = NULL;
799 } 738 }
800 break; 739 break;
801 } 740 }
802 } 741 }
803 742
804 UiObject* current = uic_current_obj(obj);
805 if(args->value || args->varname) { 743 if(args->value || args->varname) {
806 UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); 744 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER);
807 UiInteger *i = var->value; 745 UiInteger *i = var->value;
808 i->get = getfunc; 746 i->get = getfunc;
809 i->set = setfunc; 747 i->set = setfunc;
810 i->obj = data_widget; 748 i->obj = data_widget;
811 } 749 }
812 750
813 g_object_set_data(G_OBJECT(widget), "ui_tabview", data); 751 g_object_set_data(G_OBJECT(widget), "ui_tabview", data);
814 data->widget = data_widget; 752 data->widget = data_widget;
815 data->subcontainer = args->subcontainer; 753
816 754 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
817 UI_APPLY_LAYOUT2(current, args); 755 UiLayout layout = UI_ARGS2LAYOUT(args);
818 current->container->add(current->container, widget); 756 ct->add(ct, widget, &layout);
819 757
820 UiObject *newobj = uic_object_new(obj, widget); 758 UiContainerX *container = ui_tabview_container(obj, widget);
821 newobj->container = ui_tabview_container(obj, widget); 759 uic_object_push_container(obj, container);
822 uic_obj_add(obj, newobj);
823 data->obj = newobj;
824 760
825 return widget; 761 return widget;
826 } 762 }
827 763
764 static GtkWidget* create_tab(UiObject *obj, UiGtkTabView *tabview, const char *title, int tab) {
765 UiContainerX *container;
766 GtkWidget *sub;
767 switch(tabview->subcontainer) {
768 default: {
769 sub = ui_gtk_vbox_new(tabview->spacing);
770 container = ui_box_container(obj, sub, tabview->subcontainer);
771 break;
772 }
773 case UI_CONTAINER_HBOX: {
774 sub = ui_gtk_hbox_new(tabview->spacing);
775 container = ui_box_container(obj, sub, tabview->subcontainer);
776 break;
777 }
778 case UI_CONTAINER_GRID: {
779 sub = ui_create_grid_widget(tabview->columnspacing, tabview->rowspacing);
780 container = ui_grid_container(obj, sub, FALSE, FALSE, FALSE, FALSE);
781 break;
782 }
783 }
784
785 uic_object_push_container(obj, container);
786
787 GtkWidget *widget = ui_box_set_margin(sub, tabview->padding);
788 tabview->add_tab(tabview->widget, tab, title, widget);
789
790 return sub;
791 }
792
828 void ui_tab_create(UiObject* obj, const char* title) { 793 void ui_tab_create(UiObject* obj, const char* title) {
829 UiObject* current = uic_current_obj(obj); 794 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
830 UiGtkTabView *data = ui_widget_get_tabview_data(current->widget); 795 GtkWidget *tabview = ct->widget;
796 UiGtkTabView *data = ui_widget_get_tabview_data(tabview);
831 if(!data) { 797 if(!data) {
832 fprintf(stderr, "UI Error: widget is not a tabview\n"); 798 fprintf(stderr, "UI Error: widget is not a tabview\n");
833 return; 799 return;
834 } 800 }
835 801
836 UiObject *newobj = ui_tabview_add(current->widget, title, -1); 802 create_tab(obj, data, title, -1);
837 current->next = newobj;
838 } 803 }
839 804
840 805
841 806
842 void ui_tabview_select(UIWIDGET tabview, int tab) { 807 void ui_tabview_select(UIWIDGET tabview, int tab) {
862 if(!data) { 827 if(!data) {
863 fprintf(stderr, "UI Error: widget is not a tabview\n"); 828 fprintf(stderr, "UI Error: widget is not a tabview\n");
864 return NULL; 829 return NULL;
865 } 830 }
866 831
867 UiObject *newobj = cxCalloc(data->obj->ctx->allocator, 1, sizeof(UiObject)); 832 UiObject *newobj = uic_object_new_toplevel();
868 newobj->ctx = data->obj->ctx; 833 newobj->widget = create_tab(newobj, data, name, tab_index);
869
870 GtkWidget *sub;
871 switch(data->subcontainer) {
872 default: {
873 sub = ui_gtk_vbox_new(data->spacing);
874 newobj->container = ui_box_container(newobj, sub, data->subcontainer);
875 break;
876 }
877 case UI_CONTAINER_HBOX: {
878 sub = ui_gtk_hbox_new(data->spacing);
879 newobj->container = ui_box_container(newobj, sub, data->subcontainer);
880 break;
881 }
882 case UI_CONTAINER_GRID: {
883 sub = ui_create_grid_widget(data->columnspacing, data->rowspacing);
884 newobj->container = ui_grid_container(newobj, sub, FALSE, FALSE, FALSE, FALSE);
885 break;
886 }
887 }
888 newobj->widget = sub;
889 GtkWidget *widget = ui_box_set_margin(sub, data->margin);
890
891 data->add_tab(data->widget, tab_index, name, widget);
892 834
893 return newobj; 835 return newobj;
894 } 836 }
895 837
896 838
897 /* -------------------- Headerbar -------------------- */ 839 /* -------------------- Headerbar -------------------- */
898 840
899 static void hb_set_part(UiObject *obj, int part) { 841 static void hb_set_part(UiObject *obj, int part) {
900 UiObject* current = uic_current_obj(obj); 842 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
901 GtkWidget *headerbar = current->widget; 843 GtkWidget *headerbar = ct->widget;
902 844
903 UiHeaderbarContainer *hb = cxCalloc( 845 UiHeaderbarContainer *hb = cxCalloc(
904 obj->ctx->allocator, 846 obj->ctx->allocator,
905 1, 847 1,
906 sizeof(UiHeaderbarContainer)); 848 sizeof(UiHeaderbarContainer));
907 memcpy(hb, current->container, sizeof(UiHeaderbarContainer)); 849 memcpy(hb, ct, sizeof(UiHeaderbarContainer));
908
909 UiObject *newobj = uic_object_new(obj, headerbar);
910 newobj->container = (UiContainer*)hb;
911 uic_obj_add(obj, newobj);
912
913 hb->part = part; 850 hb->part = part;
851 uic_object_push_container(obj, (UiContainerX*)hb);
914 } 852 }
915 853
916 void ui_headerbar_start_create(UiObject *obj) { 854 void ui_headerbar_start_create(UiObject *obj) {
917 hb_set_part(obj, 0); 855 hb_set_part(obj, 0);
918 } 856 }
924 void ui_headerbar_end_create(UiObject *obj) { 862 void ui_headerbar_end_create(UiObject *obj) {
925 hb_set_part(obj, 1); 863 hb_set_part(obj, 1);
926 } 864 }
927 865
928 UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs *args) { 866 UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs *args) {
929 UiObject *current = uic_current_obj(obj); 867 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
930 UiContainer *ct = current->container; 868 UiLayout layout = UI_ARGS2LAYOUT(args);
931 UI_APPLY_LAYOUT2(current, args);
932 869
933 GtkWidget *box = ui_gtk_hbox_new(args->alt_spacing); 870 GtkWidget *box = ui_gtk_hbox_new(args->alt_spacing);
934 ui_set_name_and_style(box, args->name, args->style_class); 871 ui_set_name_and_style(box, args->name, args->style_class);
935 ct->add(ct, box); 872 ct->add(ct, box, &layout);
936 873
937 UiObject *newobj = uic_object_new(obj, box); 874 UiContainerX *container = ui_headerbar_fallback_container(obj, box);
938 newobj->container = ui_headerbar_fallback_container(obj, box); 875 uic_object_push_container(obj, container);
939 uic_obj_add(obj, newobj);
940 876
941 return box; 877 return box;
942 } 878 }
943 879
944 static void hb_fallback_set_part(UiObject *obj, int part) { 880 static void hb_fallback_set_part(UiObject *obj, int part) {
945 UiObject* current = uic_current_obj(obj); 881 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
946 GtkWidget *headerbar = current->widget; 882 GtkWidget *headerbar = ct->widget;
947 883
948 UiObject *newobj = uic_object_new(obj, headerbar); 884 UiContainerX *container = ui_headerbar_container(obj, headerbar);
949 newobj->container = ui_headerbar_container(obj, headerbar); 885 uic_object_push_container(obj, container);
950 uic_obj_add(obj, newobj); 886
951 887 UiHeaderbarContainer *hb = (UiHeaderbarContainer*)container;
952 UiHeaderbarContainer *hb = (UiHeaderbarContainer*)newobj->container;
953 hb->part = part; 888 hb->part = part;
954 } 889 }
955 890
956 UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) { 891 UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) {
957 UiHeaderbarContainer *ct = cxCalloc( 892 UiHeaderbarContainer *ct = cxCalloc(
958 obj->ctx->allocator, 893 obj->ctx->allocator,
959 1, 894 1,
960 sizeof(UiHeaderbarContainer)); 895 sizeof(UiHeaderbarContainer));
961 ct->container.widget = headerbar; 896 ct->container.widget = headerbar;
962 ct->container.add = ui_headerbar_fallback_container_add; 897 ct->container.add = ui_headerbar_fallback_container_add;
963 return (UiContainer*)ct; 898 return (UiContainerX*)ct;
964 } 899 }
965 900
966 void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget) { 901 void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
967 UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct; 902 UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct;
968 BOX_ADD(ct->widget, widget); 903 BOX_ADD(ct->widget, widget);
969 } 904 }
970 905
971 #if GTK_CHECK_VERSION(3, 10, 0) 906 #if GTK_CHECK_VERSION(3, 10, 0)
972 907
973 UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) { 908 UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) {
974 GtkWidget *headerbar = g_object_get_data(G_OBJECT(obj->widget), "ui_headerbar"); 909 GtkWidget *headerbar = g_object_get_data(G_OBJECT(obj->widget), "ui_headerbar");
975 if(!headerbar) { 910 if(!headerbar) {
976 return ui_headerbar_fallback_create(obj, args); 911 return ui_headerbar_fallback_create(obj, args);
977 } 912 }
978 913
979 UiObject *newobj = uic_object_new(obj, headerbar); 914 UiContainerX *container = ui_headerbar_container(obj, headerbar);
980 newobj->container = ui_headerbar_container(obj, headerbar); 915 uic_object_push_container(obj, container);
981 uic_obj_add(obj, newobj);
982 916
983 return headerbar; 917 return headerbar;
984 } 918 }
985 919
986 UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) { 920 UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) {
987 UiHeaderbarContainer *ct = cxCalloc( 921 UiHeaderbarContainer *ct = cxCalloc(
988 obj->ctx->allocator, 922 obj->ctx->allocator,
989 1, 923 1,
990 sizeof(UiHeaderbarContainer)); 924 sizeof(UiHeaderbarContainer));
991 ct->container.widget = headerbar; 925 ct->container.widget = headerbar;
992 ct->container.add = ui_headerbar_container_add; 926 ct->container.add = ui_headerbar_container_add;
993 return (UiContainer*)ct; 927 return (UiContainerX*)ct;
994 } 928 }
995 929
996 void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget) { 930 void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
997 UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct; 931 UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct;
998 if(hb->part == 0) { 932 if(hb->part == 0) {
999 UI_HEADERBAR_PACK_START(ct->widget, widget); 933 UI_HEADERBAR_PACK_START(ct->widget, widget);
1000 } else if(hb->part == 1) { 934 } else if(hb->part == 1) {
1001 UI_HEADERBAR_PACK_END(ct->widget, widget); 935 UI_HEADERBAR_PACK_END(ct->widget, widget);
1029 963
1030 GtkWidget *box = ui_gtk_vbox_new(args->spacing); 964 GtkWidget *box = ui_gtk_vbox_new(args->spacing);
1031 ui_box_set_margin(box, args->margin); 965 ui_box_set_margin(box, args->margin);
1032 adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box); 966 adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box);
1033 967
1034 UiObject *newobj = uic_object_new(obj, box); 968 UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
1035 newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX); 969 uic_object_push_container(obj, container);
1036 uic_obj_add(obj, newobj);
1037 970
1038 return box; 971 return box;
1039 } 972 }
1040 #else 973 #else
1041 UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) { 974 UIWIDGET ui_sidebar_create(UiObject *obj, UiSidebarArgs *args) {
1043 976
1044 GtkWidget *box = ui_gtk_vbox_new(args->spacing); 977 GtkWidget *box = ui_gtk_vbox_new(args->spacing);
1045 ui_box_set_margin(box, args->margin); 978 ui_box_set_margin(box, args->margin);
1046 BOX_ADD_EXPAND(sidebar_vbox, box); 979 BOX_ADD_EXPAND(sidebar_vbox, box);
1047 980
1048 UiObject *newobj = uic_object_new(obj, box); 981 UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
1049 newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX); 982 uic_object_push_container(obj, container);
1050 uic_obj_add(obj, newobj);
1051 983
1052 return box; 984 return box;
1053 } 985 }
1054 #endif 986 #endif
1055 987
1064 GtkWidget *box = ui_gtk_vbox_new(args->spacing); 996 GtkWidget *box = ui_gtk_vbox_new(args->spacing);
1065 ui_set_name_and_style(box, args->name, args->style_class); 997 ui_set_name_and_style(box, args->name, args->style_class);
1066 ui_box_set_margin(box, args->margin); 998 ui_box_set_margin(box, args->margin);
1067 BOX_ADD_EXPAND(pbox, box); 999 BOX_ADD_EXPAND(pbox, box);
1068 1000
1069 UiObject *newobj = uic_object_new(obj, box); 1001 UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
1070 newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX); 1002 uic_object_push_container(obj, container);
1071 uic_obj_add(obj, newobj);
1072 1003
1073 return box; 1004 return box;
1074 } 1005 }
1075 1006
1076 UIWIDGET ui_left_panel_create(UiObject *obj, UiSidebarArgs *args) { 1007 UIWIDGET ui_left_panel_create(UiObject *obj, UiSidebarArgs *args) {
1106 ui_set_property(property_name, buf); 1037 ui_set_property(property_name, buf);
1107 free(property_name); 1038 free(property_name);
1108 } 1039 }
1109 1040
1110 static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs *args) { 1041 static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs *args) {
1111 UiObject* current = uic_current_obj(obj); 1042 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
1043 UiLayout layout = UI_ARGS2LAYOUT(args);
1112 1044
1113 GtkWidget *pane0 = create_paned(orientation); 1045 GtkWidget *pane0 = create_paned(orientation);
1114 1046 ct->add(ct, pane0, &layout);
1115 UI_APPLY_LAYOUT2(current, args);
1116 current->container->add(current->container, pane0);
1117 1047
1118 int max = args->max_panes == 0 ? 2 : args->max_panes; 1048 int max = args->max_panes == 0 ? 2 : args->max_panes;
1119 1049
1120 if(args->position_property) { 1050 if(args->position_property) {
1121 const char *pos_str = ui_get_property(args->position_property); 1051 const char *pos_str = ui_get_property(args->position_property);
1132 "destroy", 1062 "destroy",
1133 G_CALLBACK(save_pane_pos), 1063 G_CALLBACK(save_pane_pos),
1134 strdup(args->position_property)); 1064 strdup(args->position_property));
1135 } 1065 }
1136 1066
1137 UiObject *newobj = uic_object_new(obj, pane0); 1067 UiContainerX *container = ui_splitpane_container(obj, pane0, orientation, max, args->initial_position);
1138 newobj->container = ui_splitpane_container(obj, pane0, orientation, max, args->initial_position); 1068 uic_object_push_container(obj, container);
1139 uic_obj_add(obj, newobj); 1069
1140 1070 g_object_set_data(G_OBJECT(pane0), "ui_splitpane", container);
1141 g_object_set_data(G_OBJECT(pane0), "ui_splitpane", newobj->container); 1071
1142 1072 UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER);
1143 UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER);
1144 if(var) { 1073 if(var) {
1145 UiSplitPaneContainer *s = (UiSplitPaneContainer*)newobj->container; 1074 UiSplitPaneContainer *s = (UiSplitPaneContainer*)container;
1146 UiInteger *i = var->value; 1075 UiInteger *i = var->value;
1147 s->initial_position = i->value; 1076 s->initial_position = i->value;
1148 1077
1149 i->obj = s; 1078 i->obj = s;
1150 i->get = ui_splitpane_get; 1079 i->get = ui_splitpane_get;
1160 1089
1161 UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs *args) { 1090 UIWIDGET ui_vsplitpane_create(UiObject *obj, UiSplitPaneArgs *args) {
1162 return splitpane_create(obj, UI_VERTICAL, args); 1091 return splitpane_create(obj, UI_VERTICAL, args);
1163 } 1092 }
1164 1093
1165 UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init) { 1094 UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init) {
1166 UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer)); 1095 UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer));
1167 ct->container.widget = pane; 1096 ct->container.widget = pane;
1168 ct->container.add = ui_splitpane_container_add; 1097 ct->container.add = ui_splitpane_container_add;
1169 ct->current_pane = pane; 1098 ct->current_pane = pane;
1170 ct->orientation = orientation; 1099 ct->orientation = orientation;
1171 ct->max = max; 1100 ct->max = max;
1172 ct->initial_position = init; 1101 ct->initial_position = init;
1173 ct->children = cxArrayListCreateSimple(CX_STORE_POINTERS, 4); 1102 ct->children = cxArrayListCreateSimple(CX_STORE_POINTERS, 4);
1174 return (UiContainer*)ct; 1103 return (UiContainerX*)ct;
1175 } 1104 }
1176 1105
1177 void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget) { 1106 void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
1178 UiSplitPaneContainer *s = (UiSplitPaneContainer*)ct; 1107 UiSplitPaneContainer *s = (UiSplitPaneContainer*)ct;
1179 1108
1180 if(s->nchildren >= s->max) { 1109 if(s->nchildren >= s->max) {
1181 fprintf(stderr, "splitpane: maximum number of children reached\n"); 1110 fprintf(stderr, "splitpane: maximum number of children reached\n");
1182 return; 1111 return;
1277 while(elm) { 1206 while(elm) {
1278 CxHashKey key = cx_hash_key(&elm, sizeof(void*)); 1207 CxHashKey key = cx_hash_key(&elm, sizeof(void*));
1279 UiObject *item_obj = cxMapGet(ct->current_items, key); 1208 UiObject *item_obj = cxMapGet(ct->current_items, key);
1280 if(item_obj) { 1209 if(item_obj) {
1281 // re-add previously created widget 1210 // re-add previously created widget
1282 ui_box_container_add(ct->container, item_obj->widget); 1211 UiLayout layout = {0};
1212 ui_box_container_add(ct->container, item_obj->widget, &layout);
1283 } else { 1213 } else {
1284 // create new widget and object for this list element 1214 // create new widget and object for this list element
1285 CxMempool *mp = cxMempoolCreateSimple(256); 1215 UiObject *obj = uic_object_new_toplevel();
1286 const CxAllocator *a = mp->allocator; 1216 obj->ctx->parent = ct->parent->ctx;
1287 UiObject *obj = cxCalloc(a, 1, sizeof(UiObject));
1288 obj->ctx = uic_context(obj, mp);
1289 obj->window = NULL; 1217 obj->window = NULL;
1290 obj->widget = ui_subcontainer_create( 1218 obj->widget = ui_subcontainer_create(
1291 ct->subcontainer, 1219 ct->subcontainer,
1292 obj, 1220 obj,
1293 ct->spacing, 1221 ct->spacing,
1294 ct->columnspacing, 1222 ct->columnspacing,
1295 ct->rowspacing, 1223 ct->rowspacing,
1296 ct->margin); 1224 ct->margin);
1297 ui_box_container_add(ct->container, obj->widget); 1225 UiLayout layout = {0};
1226 ui_box_container_add(ct->container, obj->widget, &layout);
1298 if(ct->create_ui) { 1227 if(ct->create_ui) {
1299 ct->create_ui(obj, index, elm, ct->userdata); 1228 ct->create_ui(obj, index, elm, ct->userdata);
1300 } 1229 }
1301 cxMapPut(new_items, key, obj); 1230 cxMapPut(new_items, key, obj);
1302 } 1231 }
1314 cxMapFree(container->current_items); 1243 cxMapFree(container->current_items);
1315 free(container); 1244 free(container);
1316 } 1245 }
1317 1246
1318 UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs *args) { 1247 UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs *args) {
1319 UiObject *current = uic_current_obj(obj); 1248 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
1320 UiContainer *ct = current->container; 1249 UiLayout layout = UI_ARGS2LAYOUT(args);
1321 UI_APPLY_LAYOUT2(current, args);
1322 1250
1323 GtkWidget *box = args->container == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing); 1251 GtkWidget *box = args->container == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing);
1324 ui_set_name_and_style(box, args->name, args->style_class); 1252 ui_set_name_and_style(box, args->name, args->style_class);
1325 GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box; 1253 GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box;
1326 ct->add(ct, widget); 1254 ct->add(ct, widget, &layout);
1327 1255
1328 UiGtkItemListContainer *container = malloc(sizeof(UiGtkItemListContainer)); 1256 UiGtkItemListContainer *container = malloc(sizeof(UiGtkItemListContainer));
1329 container->parent = obj; 1257 container->parent = obj;
1330 container->widget = box; 1258 container->widget = box;
1331 container->container = ui_box_container(current, box, args->container); 1259 container->container = (UiContainerPrivate*)ui_box_container(obj, box, args->container);
1332 container->create_ui = args->create_ui; 1260 container->create_ui = args->create_ui;
1333 container->userdata = args->userdata; 1261 container->userdata = args->userdata;
1334 container->subcontainer = args->subcontainer; 1262 container->subcontainer = args->subcontainer;
1335 container->current_items = cxHashMapCreateSimple(CX_STORE_POINTERS); 1263 container->current_items = cxHashMapCreateSimple(CX_STORE_POINTERS);
1336 container->current_items->collection.advanced_destructor = remove_item; 1264 container->current_items->collection.advanced_destructor = remove_item;
1339 container->spacing = args->sub_spacing; 1267 container->spacing = args->sub_spacing;
1340 container->columnspacing = args->sub_columnspacing; 1268 container->columnspacing = args->sub_columnspacing;
1341 container->rowspacing = args->sub_rowspacing; 1269 container->rowspacing = args->sub_rowspacing;
1342 container->remove_items = TRUE; 1270 container->remove_items = TRUE;
1343 1271
1344 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_LIST); 1272 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_LIST);
1345 if(var) { 1273 if(var) {
1346 UiList *list = var->value; 1274 UiList *list = var->value;
1347 list->obj = container; 1275 list->obj = container;
1348 list->update = update_itemlist; 1276 list->update = update_itemlist;
1349 update_itemlist(list, 0); 1277 update_itemlist(list, 0);
1356 1284
1357 return box; 1285 return box;
1358 } 1286 }
1359 1287
1360 1288
1361
1362 /*
1363 * -------------------- Layout Functions --------------------
1364 *
1365 * functions for setting layout attributes for the current container
1366 *
1367 */
1368
1369 void ui_layout_fill(UiObject *obj, UiBool fill) {
1370 UiContainer *ct = uic_get_current_container(obj);
1371 ct->layout.fill = fill;
1372 }
1373
1374 void ui_layout_hexpand(UiObject *obj, UiBool expand) {
1375 UiContainer *ct = uic_get_current_container(obj);
1376 ct->layout.hexpand = expand;
1377 }
1378
1379 void ui_layout_vexpand(UiObject *obj, UiBool expand) {
1380 UiContainer *ct = uic_get_current_container(obj);
1381 ct->layout.vexpand = expand;
1382 }
1383
1384 void ui_layout_hfill(UiObject *obj, UiBool fill) {
1385 UiContainer *ct = uic_get_current_container(obj);
1386 ct->layout.hfill = fill;
1387 }
1388
1389 void ui_layout_vfill(UiObject *obj, UiBool fill) {
1390 UiContainer *ct = uic_get_current_container(obj);
1391 ct->layout.vfill = fill;
1392 }
1393
1394 UIEXPORT void ui_layout_override_defaults(UiObject *obj, UiBool d) {
1395 UiContainer *ct = uic_get_current_container(obj);
1396 ct->layout.override_defaults = d;
1397 }
1398
1399 void ui_layout_colspan(UiObject* obj, int cols) {
1400 UiContainer* ct = uic_get_current_container(obj);
1401 ct->layout.colspan = cols;
1402 }
1403
1404 void ui_layout_rowspan(UiObject* obj, int rows) {
1405 UiContainer* ct = uic_get_current_container(obj);
1406 ct->layout.rowspan = rows;
1407 }
1408
1409 void ui_newline(UiObject *obj) {
1410 UiContainer *ct = uic_get_current_container(obj);
1411 ct->layout.newline = TRUE;
1412 }
1413

mercurial