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 XtSetArg(xargs[n], XmNbackground, 0); n++; 132 133 UiContainerPrivate *ctn = ui_obj_container(obj); 134 UI_APPLY_LAYOUT(ctn->layout, args); 135 136 Widget parent = ctn->prepare(ctn, xargs, &n); 137 Widget grid = XtCreateManagedWidget(args.name ? args.name : "gridcontainer", gridClass, parent, xargs, n); 138 ctn->add(ctn, grid); 139 140 UiContainerX *container = ui_grid_container(obj, grid); 141 uic_object_push_container(obj, container); 142 143 return grid; 144 } 145 146 UiContainerX* ui_grid_container(UiObject *obj, Widget grid) { 147 UiGridContainer *ctn = ui_malloc(obj->ctx, sizeof(UiGridContainer)); 148 memset(ctn, 0, sizeof(UiBoxContainer)); 149 ctn->container.prepare = ui_grid_container_prepare; 150 ctn->container.add = ui_grid_container_add; 151 ctn->container.widget = grid; 152 ctn->x = 0; 153 ctn->y = 0; 154 return (UiContainerX*)ctn; 155 } 156 157 Widget ui_grid_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n) { 158 UiGridContainer *grid = (UiGridContainer*)ctn; 159 if(ctn->layout.newline) { 160 grid->y++; 161 grid->x = 0; 162 } 163 164 int a = *n; 165 XtSetArg(args[a], gridColumn, grid->x); a++; 166 XtSetArg(args[a], gridRow, grid->y); a++; 167 if(ctn->layout.colspan > 0) { 168 XtSetArg(args[a], gridColspan, ctn->layout.colspan); a++; 169 } 170 if(ctn->layout.rowspan > 0) { 171 XtSetArg(args[a], gridRowspan, ctn->layout.rowspan); a++; 172 } 173 174 if(grid->container.layout.fill == UI_ON) { 175 grid->container.layout.hfill = TRUE; 176 grid->container.layout.vfill = TRUE; 177 grid->container.layout.hexpand = TRUE; 178 grid->container.layout.vexpand = TRUE; 179 } 180 181 if(grid->container.layout.hfill) { 182 XtSetArg(args[a], gridHFill, TRUE); a++; 183 } 184 if(grid->container.layout.vfill) { 185 XtSetArg(args[a], gridVFill, TRUE); a++; 186 } 187 if(grid->container.layout.hexpand) { 188 XtSetArg(args[a], gridHExpand, TRUE); a++; 189 } 190 if(grid->container.layout.vexpand) { 191 XtSetArg(args[a], gridVExpand, TRUE); a++; 192 } 193 194 *n = a; 195 return ctn->widget; 196 } 197 198 void ui_grid_container_add(UiContainerPrivate *ctn, Widget widget) { 199 UiGridContainer *grid = (UiGridContainer*)ctn; 200 grid->x++; 201 ui_reset_layout(ctn->layout); 202 } 203 204 205 /* -------------------- Container Helper Functions -------------------- */ 206 207 void ui_container_begin_close(UiObject *obj) { 208 UiContainerPrivate *ct = ui_obj_container(obj); 209 ct->container.close = 1; 210 } 211 212 int ui_container_finish(UiObject *obj) { 213 UiContainerPrivate *ct = ui_obj_container(obj); 214 if(ct->container.close) { 215 ui_end_new(obj); 216 return 0; 217 } 218 return 1; 219 } 220 221 222 /* 223 * -------------------- Layout Functions -------------------- 224 * 225 * functions for setting layout attributes for the current container 226 * 227 */ 228 229 void ui_newline(UiObject *obj) { 230 UiContainerPrivate *ct = ui_obj_container(obj); 231 ct->layout.newline = TRUE; 232 } 233