270 ret = a; |
247 ret = a; |
271 #endif |
248 #endif |
272 return ret; |
249 return ret; |
273 } |
250 } |
274 |
251 |
275 UIWIDGET ui_vbox_sp(UiObject *obj, int margin, int spacing) { |
252 UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs args, UiSubContainerType type) { |
276 UiContainer *ct = uic_get_current_container(obj); |
253 UiObject *current = uic_current_obj(obj); |
277 |
254 UiContainer *ct = current->container; |
278 GtkWidget *vbox = ui_gtk_vbox_new(spacing); |
255 UI_APPLY_LAYOUT1(current, args); |
279 GtkWidget *widget = margin > 0 ? box_set_margin(vbox, margin) : vbox; |
256 |
|
257 GtkWidget *vbox = ui_gtk_vbox_new(args.spacing); |
|
258 GtkWidget *widget = args.margin > 0 ? box_set_margin(vbox, args.margin) : vbox; |
280 ct->add(ct, widget, TRUE); |
259 ct->add(ct, widget, TRUE); |
281 |
260 |
282 UiObject *newobj = uic_object_new(obj, vbox); |
261 UiObject *newobj = uic_object_new(obj, vbox); |
283 newobj->container = ui_box_container(obj, vbox); |
262 newobj->container = ui_box_container(obj, vbox); |
284 uic_obj_add(obj, newobj); |
263 uic_obj_add(obj, newobj); |
285 |
264 |
286 return widget; |
265 return widget; |
287 } |
266 } |
288 |
267 |
289 UIWIDGET ui_hbox_sp(UiObject *obj, int margin, int spacing) { |
268 UIEXPORT UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args) { |
290 UiContainer *ct = uic_get_current_container(obj); |
269 return ui_box_create(obj, args, UI_CONTAINER_VBOX); |
291 |
270 } |
292 GtkWidget *hbox = ui_gtk_hbox_new(spacing); |
271 |
293 GtkWidget *widget = margin > 0 ? box_set_margin(hbox, margin) : hbox; |
272 UIEXPORT UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args) { |
294 ct->add(ct, widget, TRUE); |
273 return ui_box_create(obj, args, UI_CONTAINER_HBOX); |
295 |
274 } |
296 UiObject *newobj = uic_object_new(obj, hbox); |
275 |
297 newobj->container = ui_box_container(obj, hbox); |
276 |
298 uic_obj_add(obj, newobj); |
277 |
299 |
278 UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args) { |
300 return widget; |
|
301 } |
|
302 |
|
303 UIWIDGET ui_grid(UiObject *obj) { |
|
304 return ui_grid_sp(obj, 0, 0, 0); |
|
305 } |
|
306 |
|
307 UIWIDGET ui_grid_sp(UiObject *obj, int margin, int columnspacing, int rowspacing) { |
|
308 UiContainer *ct = uic_get_current_container(obj); |
279 UiContainer *ct = uic_get_current_container(obj); |
309 GtkWidget *widget; |
280 GtkWidget *widget; |
310 |
281 |
311 #ifdef UI_GTK3 |
282 #ifdef UI_GTK3 |
312 GtkWidget *grid = gtk_grid_new(); |
283 GtkWidget *grid = gtk_grid_new(); |
313 gtk_grid_set_column_spacing(GTK_GRID(grid), columnspacing); |
284 gtk_grid_set_column_spacing(GTK_GRID(grid), args.columnspacing); |
314 gtk_grid_set_row_spacing(GTK_GRID(grid), rowspacing); |
285 gtk_grid_set_row_spacing(GTK_GRID(grid), args.rowspacing); |
315 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 12 |
286 #if GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION >= 12 |
316 gtk_widget_set_margin_start(grid, margin); |
287 gtk_widget_set_margin_start(grid, args.margin); |
317 gtk_widget_set_margin_end(grid, margin); |
288 gtk_widget_set_margin_end(grid, args.margin); |
318 #else |
289 #else |
319 gtk_widget_set_margin_left(grid, margin); |
290 gtk_widget_set_margin_left(grid, margin); |
320 gtk_widget_set_margin_right(grid, margin); |
291 gtk_widget_set_margin_right(grid, margin); |
321 #endif |
292 #endif |
322 gtk_widget_set_margin_top(grid, margin); |
293 gtk_widget_set_margin_top(grid, args.margin); |
323 gtk_widget_set_margin_bottom(grid, margin); |
294 gtk_widget_set_margin_bottom(grid, args.margin); |
324 |
295 |
325 widget = grid; |
296 widget = grid; |
326 #elif defined(UI_GTK2) |
297 #elif defined(UI_GTK2) |
327 GtkWidget *grid = gtk_table_new(1, 1, FALSE); |
298 GtkWidget *grid = gtk_table_new(1, 1, FALSE); |
328 |
299 |
345 uic_obj_add(obj, newobj); |
316 uic_obj_add(obj, newobj); |
346 |
317 |
347 return widget; |
318 return widget; |
348 } |
319 } |
349 |
320 |
350 UIWIDGET ui_scrolledwindow(UiObject *obj) { |
|
351 UiContainer *ct = uic_get_current_container(obj); |
|
352 GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL); |
|
353 ct->add(ct, sw, TRUE); |
|
354 |
|
355 UiObject *newobj = uic_object_new(obj, sw); |
|
356 newobj->container = ui_scrolledwindow_container(obj, sw); |
|
357 uic_obj_add(obj, newobj); |
|
358 |
|
359 return sw; |
|
360 } |
|
361 |
|
362 UIWIDGET ui_tabview(UiObject *obj) { |
|
363 GtkWidget *tabview = gtk_notebook_new(); |
|
364 gtk_notebook_set_show_border(GTK_NOTEBOOK(tabview), FALSE); |
|
365 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(tabview), FALSE); |
|
366 |
|
367 UiContainer *ct = uic_get_current_container(obj); |
|
368 ct->add(ct, tabview, TRUE); |
|
369 |
|
370 UiObject *tabviewobj = uic_object_new(obj, tabview); |
|
371 tabviewobj->container = ui_tabview_container(obj, tabview); |
|
372 uic_obj_add(obj, tabviewobj); |
|
373 |
|
374 return tabview; |
|
375 } |
|
376 |
|
377 void ui_tab(UiObject *obj, char *title) { |
|
378 UiContainer *ct = uic_get_current_container(obj); |
|
379 ct->layout.label = title; |
|
380 ui_vbox(obj); |
|
381 } |
|
382 |
321 |
383 void ui_select_tab(UIWIDGET tabview, int tab) { |
322 void ui_select_tab(UIWIDGET tabview, int tab) { |
384 gtk_notebook_set_current_page(GTK_NOTEBOOK(tabview), tab); |
323 gtk_notebook_set_current_page(GTK_NOTEBOOK(tabview), tab); |
385 } |
324 } |
386 |
325 |
399 } |
338 } |
400 #endif |
339 #endif |
401 return NULL; |
340 return NULL; |
402 } |
341 } |
403 |
342 |
404 UIWIDGET ui_splitpane(UiObject *obj, int max, UiOrientation orientation) { |
343 |
405 GtkWidget *paned = create_paned(orientation); |
344 |
406 UiContainer *ct = uic_get_current_container(obj); |
345 |
407 ct->add(ct, paned, TRUE); |
|
408 |
|
409 if(max <= 0) max = INT_MAX; |
|
410 |
|
411 UiPanedContainer *pctn = cxCalloc( |
|
412 obj->ctx->allocator, |
|
413 1, |
|
414 sizeof(UiPanedContainer)); |
|
415 pctn->container.widget = paned; |
|
416 pctn->container.add = ui_paned_container_add; |
|
417 pctn->current_pane = paned; |
|
418 pctn->orientation = orientation; |
|
419 pctn->max = max; |
|
420 pctn->cur = 0; |
|
421 |
|
422 UiObject *pobj = uic_object_new(obj, paned); |
|
423 pobj->container = (UiContainer*)pctn; |
|
424 |
|
425 uic_obj_add(obj, pobj); |
|
426 |
|
427 return paned; |
|
428 } |
|
429 |
|
430 UIWIDGET ui_hsplitpane(UiObject *obj, int max) { |
|
431 return ui_splitpane(obj, max, UI_HORIZONTAL); |
|
432 } |
|
433 |
|
434 UIWIDGET ui_vsplitpane(UiObject *obj, int max) { |
|
435 return ui_splitpane(obj, max, UI_VERTICAL); |
|
436 } |
|
437 |
|
438 void ui_paned_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) { |
|
439 UiPanedContainer *pctn = (UiPanedContainer*)ct; |
|
440 |
|
441 gboolean resize = (ct->layout.hexpand || ct->layout.vexpand) ? TRUE : FALSE; |
|
442 int width = ct->layout.width; |
|
443 ui_reset_layout(ct->layout); |
|
444 |
|
445 if(pctn->cur == 0) { |
|
446 gtk_paned_pack1(GTK_PANED(pctn->current_pane), widget, resize, resize); |
|
447 } else if(pctn->cur < pctn->max-1) { |
|
448 GtkWidget *nextPane = create_paned(pctn->orientation); |
|
449 gtk_paned_pack2(GTK_PANED(pctn->current_pane), nextPane, TRUE, TRUE); |
|
450 gtk_paned_pack1(GTK_PANED(nextPane), widget, resize, resize); |
|
451 pctn->current_pane = nextPane; |
|
452 } else if(pctn->cur == pctn->max-1) { |
|
453 gtk_paned_pack2(GTK_PANED(pctn->current_pane), widget, resize, resize); |
|
454 width = 0; // disable potential call of gtk_paned_set_position |
|
455 } else { |
|
456 fprintf(stderr, "Splitpane max reached: %d\n", pctn->max); |
|
457 return; |
|
458 } |
|
459 |
|
460 if(width > 0) { |
|
461 gtk_paned_set_position(GTK_PANED(pctn->current_pane), width); |
|
462 } |
|
463 |
|
464 pctn->cur++; |
|
465 } |
|
466 |
|
467 |
|
468 /* -------------------- Sidebar (deprecated) -------------------- */ |
|
469 UIWIDGET ui_sidebar(UiObject *obj) { |
|
470 #ifdef UI_GTK3 |
|
471 GtkWidget *paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); |
|
472 #else |
|
473 GtkWidget *paned = gtk_hpaned_new(); |
|
474 #endif |
|
475 gtk_paned_set_position(GTK_PANED(paned), 200); |
|
476 |
|
477 GtkWidget *sidebar = ui_gtk_vbox_new(0); |
|
478 gtk_paned_pack1(GTK_PANED(paned), sidebar, TRUE, FALSE); |
|
479 |
|
480 UiObject *left = uic_object_new(obj, sidebar); |
|
481 UiContainer *ct1 = ui_box_container(obj, sidebar); |
|
482 left->container = ct1; |
|
483 |
|
484 UiObject *right = uic_object_new(obj, sidebar); |
|
485 UiContainer *ct2 = cxCalloc( |
|
486 obj->ctx->allocator, |
|
487 1, |
|
488 sizeof(UiContainer)); |
|
489 ct2->widget = paned; |
|
490 ct2->add = ui_split_container_add2; |
|
491 right->container = ct2; |
|
492 |
|
493 UiContainer *ct = uic_get_current_container(obj); |
|
494 ct->add(ct, paned, TRUE); |
|
495 |
|
496 uic_obj_add(obj, right); |
|
497 uic_obj_add(obj, left); |
|
498 |
|
499 return sidebar; |
|
500 } |
|
501 |
|
502 void ui_split_container_add1(UiContainer *ct, GtkWidget *widget, UiBool fill) { |
|
503 // TODO: remove |
|
504 gtk_paned_pack1(GTK_PANED(ct->widget), widget, TRUE, FALSE); |
|
505 |
|
506 ui_reset_layout(ct->layout); |
|
507 ct->current = widget; |
|
508 } |
|
509 |
|
510 void ui_split_container_add2(UiContainer *ct, GtkWidget *widget, UiBool fill) { |
|
511 gtk_paned_pack2(GTK_PANED(ct->widget), widget, TRUE, FALSE); |
|
512 |
|
513 ui_reset_layout(ct->layout); |
|
514 ct->current = widget; |
|
515 } |
|
516 |
|
517 |
|
518 /* -------------------- Document Tabview -------------------- */ |
|
519 static void page_change(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data) { |
|
520 GQuark q = g_quark_from_static_string("ui.tab.object"); |
|
521 UiObject *tab = g_object_get_qdata(G_OBJECT(page), q); |
|
522 if(!tab) { |
|
523 return; |
|
524 } |
|
525 |
|
526 //printf("page_change: %d\n", page_num); |
|
527 UiContext *ctx = tab->ctx; |
|
528 uic_context_detach_all(ctx->parent); // TODO: fix? |
|
529 ctx->parent->attach_document(ctx->parent, ctx->document); |
|
530 } |
|
531 |
|
532 UiTabbedPane* ui_tabbed_document_view(UiObject *obj) { |
|
533 GtkWidget *tabview = gtk_notebook_new(); |
|
534 gtk_notebook_set_show_border(GTK_NOTEBOOK(tabview), FALSE); |
|
535 |
|
536 g_signal_connect( |
|
537 tabview, |
|
538 "switch-page", |
|
539 G_CALLBACK(page_change), |
|
540 NULL); |
|
541 |
|
542 UiContainer *ct = uic_get_current_container(obj); |
|
543 ct->add(ct, tabview, TRUE); |
|
544 |
|
545 UiTabbedPane *tabbedpane = ui_malloc(obj->ctx, sizeof(UiTabbedPane)); |
|
546 tabbedpane->ctx = uic_current_obj(obj)->ctx; |
|
547 tabbedpane->widget = tabview; |
|
548 tabbedpane->document = NULL; |
|
549 |
|
550 return tabbedpane; |
|
551 } |
|
552 |
|
553 UiObject* ui_document_tab(UiTabbedPane *view) { |
|
554 GtkWidget *frame = gtk_frame_new(NULL); |
|
555 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE); |
|
556 // TODO: label |
|
557 gtk_notebook_append_page(GTK_NOTEBOOK(view->widget), frame, NULL); |
|
558 |
|
559 UiObject *tab = ui_malloc(view->ctx, sizeof(UiObject)); |
|
560 tab->widget = NULL; // initialization for uic_context() |
|
561 tab->ctx = uic_context(tab, view->ctx->allocator); |
|
562 tab->ctx->parent = view->ctx; |
|
563 tab->ctx->attach_document = uic_context_attach_document; |
|
564 tab->ctx->detach_document2 = uic_context_detach_document2; |
|
565 tab->widget = frame; |
|
566 tab->window = view->ctx->obj->window; |
|
567 tab->container = ui_frame_container(tab, frame); |
|
568 tab->next = NULL; |
|
569 |
|
570 GQuark q = g_quark_from_static_string("ui.tab.object"); |
|
571 g_object_set_qdata(G_OBJECT(frame), q, tab); |
|
572 |
|
573 return tab; |
|
574 } |
|
575 |
|
576 void ui_tab_set_document(UiContext *ctx, void *document) { |
|
577 // TODO: remove? |
|
578 if(ctx->parent->document) { |
|
579 //ctx->parent->detach_document(ctx->parent, ctx->parent->document); |
|
580 } |
|
581 //uic_context_set_document(ctx, document); |
|
582 //uic_context_set_document(ctx->parent, document); |
|
583 //ctx->parent->document = document; |
|
584 } |
|
585 |
|
586 void ui_tab_detach_document(UiContext *ctx) { |
|
587 // TODO: remove? |
|
588 //uic_context_detach_document(ctx->parent); |
|
589 } |
|
590 |
346 |
591 |
347 |
592 /* |
348 /* |
593 * -------------------- Layout Functions -------------------- |
349 * -------------------- Layout Functions -------------------- |
594 * |
350 * |
609 void ui_layout_vexpand(UiObject *obj, UiBool expand) { |
365 void ui_layout_vexpand(UiObject *obj, UiBool expand) { |
610 UiContainer *ct = uic_get_current_container(obj); |
366 UiContainer *ct = uic_get_current_container(obj); |
611 ct->layout.vexpand = expand; |
367 ct->layout.vexpand = expand; |
612 } |
368 } |
613 |
369 |
614 void ui_layout_width(UiObject *obj, int width) { |
|
615 UiContainer *ct = uic_get_current_container(obj); |
|
616 ct->layout.width = width; |
|
617 } |
|
618 |
|
619 void ui_layout_gridwidth(UiObject *obj, int width) { |
370 void ui_layout_gridwidth(UiObject *obj, int width) { |
620 UiContainer *ct = uic_get_current_container(obj); |
371 UiContainer *ct = uic_get_current_container(obj); |
621 ct->layout.gridwidth = width; |
372 ct->layout.gridwidth = width; |
622 } |
373 } |
623 |
374 |
|
375 void ui_layout_colspan(UiObject* obj, int cols) { |
|
376 UiContainer* ct = uic_get_current_container(obj); |
|
377 ct->layout.colspan = cols; |
|
378 } |
|
379 |
|
380 void ui_layout_rowspan(UiObject* obj, int rows) { |
|
381 UiContainer* ct = uic_get_current_container(obj); |
|
382 ct->layout.rowspan = rows; |
|
383 } |
|
384 |
624 void ui_newline(UiObject *obj) { |
385 void ui_newline(UiObject *obj) { |
625 UiContainer *ct = uic_get_current_container(obj); |
386 UiContainer *ct = uic_get_current_container(obj); |
626 ct->layout.newline = TRUE; |
387 ct->layout.newline = TRUE; |
627 } |
388 } |
628 |
389 |