ui/motif/container.c

changeset 62
70d2aee84432
parent 61
7ee124a58fe3
child 63
46a42f0c4f93
--- 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 <stdio.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #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;
+}

mercurial