diff -r 7ee124a58fe3 -r 70d2aee84432 ui/motif/container.c --- a/ui/motif/container.c Thu Jan 01 17:22:55 2015 +0100 +++ b/ui/motif/container.c Sun Jan 04 22:12:07 2015 +0100 @@ -28,11 +28,14 @@ #include #include +#include #include "container.h" #include "../common/context.h" #include "../common/object.h" +#define UI_GRID_MAX_COLUMNS 512 + static UiBool ui_lb2bool(UiLayoutBool b) { return b == UI_LAYOUT_TRUE ? TRUE : FALSE; } @@ -54,12 +57,11 @@ } Widget ui_frame_container_prepare(UiContainer *ct, Arg *args, int *n, UiBool fill) { - ui_reset_layout(ct->layout); return ct->widget; } void ui_frame_container_add(UiContainer *ct, Widget widget) { - + ui_reset_layout(ct->layout); } @@ -126,7 +128,7 @@ XtSetArg(args[a], d1, XmATTACH_FORM); a++; } - *n += a; + *n = a; return ct->widget; } @@ -175,6 +177,125 @@ ui_reset_layout(ct->layout); } +UiContainer* ui_grid_container(UiObject *obj, Widget form) { + UiGridContainer *ct = ucx_mempool_calloc( + obj->ctx->mempool, + 1, + sizeof(UiGridContainer)); + ct->container.widget = form; + ct->container.prepare = ui_grid_container_prepare; + ct->container.add = ui_grid_container_add; + return (UiContainer*)ct; +} + +void ui_grid_newline(UiGridContainer *grid) { + if(grid->current) { + grid->current = NULL; + } + grid->container.layout.newline = FALSE; +} + +Widget ui_grid_container_prepare(UiContainer *ct, Arg *args, int *n, UiBool fill) { + UiGridContainer *grid = (UiGridContainer*)ct; + if(ct->layout.newline) { + ui_grid_newline(grid); + } + return ct->widget; +} + +void ui_grid_container_add(UiContainer *ct, Widget widget) { + UiGridContainer *grid = (UiGridContainer*)ct; + + if(grid->current) { + grid->current = ucx_list_append(grid->current, widget); + } else { + grid->current = ucx_list_append(grid->current, widget); + grid->lines = ucx_list_append(grid->lines, grid->current); + } + + ui_reset_layout(ct->layout); +} + +static void ui_grid_resize(Widget widget, XtPointer udata, XtPointer cdata) { + UiGridContainer *grid = udata; + + UcxList *rowdim = NULL; + int coldim[UI_GRID_MAX_COLUMNS]; + memset(coldim, 0, UI_GRID_MAX_COLUMNS*sizeof(int)); + int numcol = 0; + + // get the minimum size of the columns and rows + int sumw = 0; + int sumh = 0; + UCX_FOREACH(row, grid->lines) { + int rheight = 0; + int i=0; + int sum_width = 0; + UCX_FOREACH(elm, row->data) { + Widget w = elm->data; + int widget_width = 0; + int widget_height = 0; + XtVaGetValues( + w, + XmNwidth, + &widget_width, + XmNheight, + &widget_height, + 0); + + // get the maximum height in this row + if(widget_height > rheight) { + rheight = widget_height; + } + rowdim = ucx_list_append(rowdim, (void*)(intptr_t)rheight); + + // get the maximum width in this column + if(widget_width > coldim[i]) { + coldim[i] = widget_width; + } + sum_width += widget_width; + if(sum_width > sumw) { + sumw = sum_width; + } + + i++; + if(i > numcol) { + numcol = i; + } + } + sumh += rheight; + } + + // check container size + int gwidth = 0; + int gheight = 0; + XtVaGetValues(widget, XmNwidth, &gwidth, XmNheight, &gheight, NULL); + if(gwidth < sumw || gheight < sumh) { + XtVaSetValues(widget, XmNwidth, sumw, XmNheight, sumh, NULL); + ucx_list_free(rowdim); + return; + } + + + // adjust the positions of all children + int y = 0; + UCX_FOREACH(row, grid->lines) { + int x = 0; + int i=0; + UCX_FOREACH(elm, row->data) { + Widget w = elm->data; + XtVaSetValues(w, XmNx, x, XmNy, y, NULL); + + x += coldim[i]; + i++; + } + y += (intptr_t)rowdim->data; + rowdim = rowdim->next; + } + + ucx_list_free(rowdim); +} + UIWIDGET ui_box(UiObject *obj, UiBoxOrientation orientation) { UiContainer *ct = uic_get_current_container(obj); @@ -200,11 +321,31 @@ return ui_box(obj, UI_BOX_HORIZONTAL); } +UIWIDGET ui_grid(UiObject *obj) { + UiContainer *ct = uic_get_current_container(obj); + + Arg args[16]; + int n = 0; + Widget parent = ct->prepare(ct, args, &n, TRUE); + Widget grid = XmCreateDrawingArea(parent, "grid", args, n); + ct->add(ct, grid); + XtManageChild(grid); + + UiObject *newobj = uic_object_new(obj, grid); + newobj->container = ui_grid_container(obj, grid); + uic_obj_add(obj, newobj); + + XtAddCallback (grid, XmNresizeCallback , ui_grid_resize, newobj->container); + + return grid; +} + UIWIDGET ui_sidebar(UiObject *obj) { UiContainer *ct = uic_get_current_container(obj); Arg args[16]; int n = 0; + XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; @@ -214,21 +355,19 @@ XtManageChild(pane); // add sidebar widget - XtSetArg(args[0], XmNshadowType, XmSHADOW_ETCHED_OUT); - XtSetArg(args[1], XmNshadowThickness, 0); - Widget sidebar = XmCreateFrame(pane, "sidebar", args, 2); + Widget sidebar = XmCreateForm(pane, "sidebar", args, 0); XtManageChild(sidebar); UiObject *left = uic_object_new(obj, sidebar); - left->container = ui_frame_container(left, sidebar); + left->container = ui_box_container(left, sidebar, UI_BOX_VERTICAL); // add content widget - XtSetArg (args[2], XmNpaneMaximum, 8000); - Widget content = XmCreateFrame(pane, "content_area", args, 3); + XtSetArg (args[0], XmNpaneMaximum, 8000); + Widget content = XmCreateForm(pane, "content_area", args, 1); XtManageChild(content); UiObject *right = uic_object_new(obj, content); - right->container = ui_frame_container(right, content); + right->container = ui_box_container(right, content, UI_BOX_VERTICAL); uic_obj_add(obj, right); uic_obj_add(obj, left); @@ -269,7 +408,6 @@ tabbedpane->view.widget = tabct; tabbedpane->view.document = NULL; tabbedpane->tabbar = tabbar; - //tabbedpane->form = tabview; tabbedpane->tabs = NULL; tabbedpane->current = NULL; @@ -450,3 +588,8 @@ UiContainer *ct = uic_get_current_container(obj); ct->layout.fill = ui_bool2lb(fill); } + +void ui_newline(UiObject *obj) { + UiContainer *ct = uic_get_current_container(obj); + ct->layout.newline = TRUE; +}