UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2024 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <inttypes.h> 32 33 #include "container.h" 34 #include "../common/context.h" 35 #include "../common/object.h" 36 37 #include "Grid.h" 38 39 /* ---------------------------- Box Container ---------------------------- */ 40 41 static UIWIDGET box_create(UiObject *obj, UiContainerArgs args, UiBoxOrientation orientation) { 42 UiContainerPrivate *ctn = ui_obj_container(obj); 43 UI_APPLY_LAYOUT(ctn->layout, args); 44 45 Arg xargs[16]; 46 int n = 0; 47 48 if(orientation == UI_BOX_VERTICAL) { 49 //XtSetArg(xargs[n], gridRowSpacing, args.spacing); n++; 50 } else { 51 //XtSetArg(xargs[n], gridColumnSpacing, args.spacing); n++; 52 } 53 54 Widget parent = ctn->prepare(ctn, xargs, &n); 55 Widget grid = XtCreateManagedWidget(args.name ? args.name : "boxcontainer", gridClass, parent, xargs, n); 56 ctn->add(ctn, grid); 57 58 UiContainerX *container = ui_box_container(obj, grid, orientation); 59 uic_object_push_container(obj, container); 60 61 return grid; 62 } 63 64 // public 65 UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs args) { 66 return box_create(obj, args, UI_BOX_VERTICAL); 67 } 68 69 // public 70 UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs args) { 71 return box_create(obj, args, UI_BOX_HORIZONTAL); 72 } 73 74 UiContainerX* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation) { 75 UiBoxContainer *ctn = ui_malloc(obj->ctx, sizeof(UiBoxContainer)); 76 memset(ctn, 0, sizeof(UiBoxContainer)); 77 ctn->container.prepare = orientation == UI_BOX_VERTICAL ? ui_vbox_prepare : ui_hbox_prepare; 78 ctn->container.add = ui_box_container_add; 79 ctn->container.widget = grid; 80 ctn->n = 0; 81 return (UiContainerX*)ctn; 82 } 83 84 static Widget ui_box_container_prepare(UiBoxContainer *box, Arg *args, int *n) { 85 int a = *n; 86 box->n++; 87 return box->container.widget; 88 } 89 90 Widget ui_vbox_prepare(UiContainerPrivate *ctn, Arg *args, int *n) { 91 UiBoxContainer *box = (UiBoxContainer*)ctn; 92 int a = *n; 93 XtSetArg(args[a], gridRow, box->n); a++; 94 if(box->container.layout.fill == UI_ON) { 95 XtSetArg(args[a], gridVExpand, TRUE); a++; 96 XtSetArg(args[a], gridVFill, TRUE); a++; 97 } 98 XtSetArg(args[a], gridHExpand, TRUE); a++; 99 XtSetArg(args[a], gridHFill, TRUE); a++; 100 *n = a; 101 return ui_box_container_prepare(box, args, n); 102 } 103 104 Widget ui_hbox_prepare(UiContainerPrivate *ctn, Arg *args, int *n) { 105 UiBoxContainer *box = (UiBoxContainer*)ctn; 106 int a = *n; 107 XtSetArg(args[a], gridColumn, box->n); a++; 108 if(box->container.layout.fill == UI_ON) { 109 XtSetArg(args[a], gridHExpand, TRUE); a++; 110 XtSetArg(args[a], gridHFill, TRUE); a++; 111 } 112 XtSetArg(args[a], gridVExpand, TRUE); a++; 113 XtSetArg(args[a], gridVFill, TRUE); a++; 114 *n = a; 115 return ui_box_container_prepare(box, args, n); 116 } 117 118 void ui_box_container_add(UiContainerPrivate *ctn, Widget widget) { 119 ui_reset_layout(ctn->layout); 120 121 } 122 123 124 /* ---------------------------- Grid Container ---------------------------- */ 125 126 // public 127 UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs args) { 128 Arg xargs[16]; 129 int n = 0; 130 131 UiContainerPrivate *ctn = ui_obj_container(obj); 132 UI_APPLY_LAYOUT(ctn->layout, args); 133 134 Widget parent = ctn->prepare(ctn, xargs, &n); 135 XtSetArg(xargs[n], gridMargin, args.margin); n++; 136 XtSetArg(xargs[n], gridColumnSpacing, args.columnspacing); n++; 137 XtSetArg(xargs[n], gridRowSpacing, args.rowspacing); n++; 138 Widget grid = XtCreateManagedWidget(args.name ? args.name : "gridcontainer", gridClass, parent, xargs, n); 139 ctn->add(ctn, grid); 140 141 UiContainerX *container = ui_grid_container(obj, grid); 142 uic_object_push_container(obj, container); 143 144 return grid; 145 } 146 147 UiContainerX* ui_grid_container(UiObject *obj, Widget grid) { 148 UiGridContainer *ctn = ui_malloc(obj->ctx, sizeof(UiGridContainer)); 149 memset(ctn, 0, sizeof(UiBoxContainer)); 150 ctn->container.prepare = ui_grid_container_prepare; 151 ctn->container.add = ui_grid_container_add; 152 ctn->container.widget = grid; 153 ctn->x = 0; 154 ctn->y = 0; 155 return (UiContainerX*)ctn; 156 } 157 158 Widget ui_grid_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n) { 159 UiGridContainer *grid = (UiGridContainer*)ctn; 160 if(ctn->layout.newline) { 161 grid->y++; 162 grid->x = 0; 163 } 164 165 int a = *n; 166 XtSetArg(args[a], gridColumn, grid->x); a++; 167 XtSetArg(args[a], gridRow, grid->y); a++; 168 if(ctn->layout.colspan > 0) { 169 XtSetArg(args[a], gridColspan, ctn->layout.colspan); a++; 170 } 171 if(ctn->layout.rowspan > 0) { 172 XtSetArg(args[a], gridRowspan, ctn->layout.rowspan); a++; 173 } 174 175 if(grid->container.layout.fill == UI_ON) { 176 grid->container.layout.hfill = TRUE; 177 grid->container.layout.vfill = TRUE; 178 grid->container.layout.hexpand = TRUE; 179 grid->container.layout.vexpand = TRUE; 180 } 181 182 if(grid->container.layout.hfill) { 183 XtSetArg(args[a], gridHFill, TRUE); a++; 184 } 185 if(grid->container.layout.vfill) { 186 XtSetArg(args[a], gridVFill, TRUE); a++; 187 } 188 if(grid->container.layout.hexpand) { 189 XtSetArg(args[a], gridHExpand, TRUE); a++; 190 } 191 if(grid->container.layout.vexpand) { 192 XtSetArg(args[a], gridVExpand, TRUE); a++; 193 } 194 195 *n = a; 196 return ctn->widget; 197 } 198 199 void ui_grid_container_add(UiContainerPrivate *ctn, Widget widget) { 200 UiGridContainer *grid = (UiGridContainer*)ctn; 201 grid->x++; 202 ui_reset_layout(ctn->layout); 203 } 204 205 206 /* -------------------- Container Helper Functions -------------------- */ 207 208 void ui_container_begin_close(UiObject *obj) { 209 UiContainerPrivate *ct = ui_obj_container(obj); 210 ct->container.close = 1; 211 } 212 213 int ui_container_finish(UiObject *obj) { 214 UiContainerPrivate *ct = ui_obj_container(obj); 215 if(ct->container.close) { 216 ui_end_new(obj); 217 return 0; 218 } 219 return 1; 220 } 221 222 223 /* 224 * -------------------- Layout Functions -------------------- 225 * 226 * functions for setting layout attributes for the current container 227 * 228 */ 229 230 void ui_newline(UiObject *obj) { 231 UiContainerPrivate *ct = ui_obj_container(obj); 232 ct->layout.newline = TRUE; 233 } 234