| 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) { |
| 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 |
| 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); |
| 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; |
| 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 |
|