UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2025 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 "args.h" 30 31 #include "../ui/common/args.h" 32 33 #define DEFAULT_ARG_FUNCS(var, prefix) \ 34 static ArgDefaultFuncs var = { \ 35 .fill = (argfunc_set_bool)prefix##_args_set_fill, \ 36 .hexpand = (argfunc_set_bool)prefix##_args_set_hexpand, \ 37 .vexpand = (argfunc_set_bool)prefix##_args_set_vexpand, \ 38 .hfill = (argfunc_set_bool)prefix##_args_set_hfill, \ 39 .vfill = (argfunc_set_bool)prefix##_args_set_vfill, \ 40 .override_defaults = (argfunc_set_bool)prefix##_args_set_override_defaults, \ 41 .margin = (argfunc_set_int)prefix##_args_set_margin, \ 42 .margin_left = (argfunc_set_int)prefix##_args_set_margin_left, \ 43 .margin_right = (argfunc_set_int)prefix##_args_set_margin_right, \ 44 .margin_top = (argfunc_set_int)prefix##_args_set_margin_top, \ 45 .margin_bottom = (argfunc_set_int)prefix##_args_set_margin_bottom, \ 46 .colspan = (argfunc_set_int)prefix##_args_set_colspan, \ 47 .rowspan = (argfunc_set_int)prefix##_args_set_rowspan, \ 48 .name = (argfunc_set_str)prefix##_args_set_name, \ 49 .style_class = (argfunc_set_str)prefix##_args_set_style_class \ 50 } 51 52 DEFAULT_ARG_FUNCS(container_args, ui_container); 53 54 DEFAULT_ARG_FUNCS(button_args, ui_button); 55 56 57 58 static void init_common_args(const CxJsonValue *value, void *args, ArgDefaultFuncs *funcs) { 59 CxJsonValue *val; 60 61 // boolean args 62 val = cxJsonObjGet(value, "fill"); 63 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 64 funcs->fill(args, TRUE); 65 } 66 67 val = cxJsonObjGet(value, "hexpand"); 68 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 69 funcs->hexpand(args, TRUE); 70 } 71 72 val = cxJsonObjGet(value, "vexpand"); 73 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 74 funcs->vexpand(args, TRUE); 75 } 76 77 val = cxJsonObjGet(value, "hfill"); 78 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 79 funcs->hfill(args, TRUE); 80 } 81 82 val = cxJsonObjGet(value, "vfill"); 83 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 84 funcs->vfill(args, TRUE); 85 } 86 87 val = cxJsonObjGet(value, "override_defaults"); 88 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 89 funcs->override_defaults(args, TRUE); 90 } 91 92 // int args 93 val = cxJsonObjGet(value, "margin"); 94 if(val && val->type == CX_JSON_INTEGER) { 95 funcs->margin(args, (int)val->value.integer); 96 } 97 98 val = cxJsonObjGet(value, "margin_left"); 99 if(val && val->type == CX_JSON_INTEGER) { 100 funcs->margin_left(args, (int)val->value.integer); 101 } 102 103 val = cxJsonObjGet(value, "margin_right"); 104 if(val && val->type == CX_JSON_INTEGER) { 105 funcs->margin_right(args, (int)val->value.integer); 106 } 107 108 val = cxJsonObjGet(value, "margin_top"); 109 if(val && val->type == CX_JSON_INTEGER) { 110 funcs->margin_top(args, (int)val->value.integer); 111 } 112 113 val = cxJsonObjGet(value, "margin_bottom"); 114 if(val && val->type == CX_JSON_INTEGER) { 115 funcs->margin_bottom(args, (int)val->value.integer); 116 } 117 118 val = cxJsonObjGet(value, "colspan"); 119 if(val && val->type == CX_JSON_INTEGER) { 120 funcs->colspan(args, (int)val->value.integer); 121 } 122 123 val = cxJsonObjGet(value, "rowspan"); 124 if(val && val->type == CX_JSON_INTEGER) { 125 funcs->rowspan(args, (int)val->value.integer); 126 } 127 128 // string args 129 val = cxJsonObjGet(value, "name"); 130 if(val && val->type == CX_JSON_STRING) { 131 funcs->name(args, val->value.string.ptr); 132 } 133 134 val = cxJsonObjGet(value, "style_class"); 135 if(val && val->type == CX_JSON_STRING) { 136 funcs->name(args, val->value.string.ptr); 137 } 138 } 139 140 void init_states(const CxJsonValue *value, void *args, argfunc_set_intarray setarray) { 141 CxJsonValue *val = cxJsonObjGet(value, "states"); 142 if(!val || val->type != CX_JSON_ARRAY) { 143 return; 144 } 145 146 int len = (int)val->value.array.array_size; 147 int *states = calloc(len, sizeof(int)); 148 for(int i=0;i<len;i++) { 149 CxJsonValue *s = val->value.array.array[i]; 150 if(s->type == CX_JSON_INTEGER) { 151 states[i] = (int)s->value.integer; 152 } 153 } 154 155 setarray(args, states, len); 156 } 157 158 UiContainerArgs* json2container_args(const CxJsonValue *value) { 159 UiContainerArgs *args = ui_container_args_new(); 160 if(value->type != CX_JSON_OBJECT) { 161 return args; 162 } 163 164 init_common_args(value, args, &container_args); 165 166 CxJsonValue *val = cxJsonObjGet(value, "spacing"); 167 if(val && val->type == CX_JSON_INTEGER) { 168 args->spacing = (int)val->value.integer; 169 } 170 171 val = cxJsonObjGet(value, "columnspacing"); 172 if(val && val->type == CX_JSON_INTEGER) { 173 args->columnspacing = (int)val->value.integer; 174 } 175 176 val = cxJsonObjGet(value, "rowspacing"); 177 if(val && val->type == CX_JSON_INTEGER) { 178 args->rowspacing = (int)val->value.integer; 179 } 180 181 val = cxJsonObjGet(value, "def_hfill"); 182 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 183 args->def_hfill = TRUE; 184 } 185 186 val = cxJsonObjGet(value, "def_vfill"); 187 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 188 args->def_vfill = TRUE; 189 } 190 191 val = cxJsonObjGet(value, "def_hexpand"); 192 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 193 args->def_hexpand = TRUE; 194 } 195 196 val = cxJsonObjGet(value, "def_vexpand"); 197 if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { 198 args->def_vexpand = TRUE; 199 } 200 201 return args; 202 } 203 204 UiButtonArgs* json2button_args(const CxJsonValue *value) { 205 UiButtonArgs *args = ui_button_args_new(); 206 if(value->type != CX_JSON_OBJECT) { 207 return args; 208 } 209 210 init_common_args(value, args, &button_args); 211 init_states(value, args, (argfunc_set_intarray)ui_button_args_set_states); 212 213 CxJsonValue *val = cxJsonObjGet(value, "label"); 214 if(val && val->type == CX_JSON_STRING) { 215 ui_button_args_set_label(args, val->value.string.ptr); 216 } 217 218 val = cxJsonObjGet(value, "icon"); 219 if(val && val->type == CX_JSON_STRING) { 220 ui_button_args_set_icon(args, val->value.string.ptr); 221 } 222 223 val = cxJsonObjGet(value, "tooltip"); 224 if(val && val->type == CX_JSON_STRING) { 225 ui_button_args_set_tooltip(args, val->value.string.ptr); 226 } 227 228 val = cxJsonObjGet(value, "labeltype"); 229 if(val && val->type == CX_JSON_INTEGER) { 230 ui_button_args_set_labeltype(args, (int)val->value.integer); 231 } 232 233 return args; 234 } 235 236 UiToggleArgs* json2toggle_args(const CxJsonValue *value) { 237 UiToggleArgs *args = ui_toggle_args_new(); 238 if(value->type != CX_JSON_OBJECT) { 239 return args; 240 } 241 242 init_common_args(value, args, &button_args); 243 init_states(value, args, (argfunc_set_intarray)ui_button_args_set_states); 244 245 CxJsonValue *val = cxJsonObjGet(value, "label"); 246 if(val && val->type == CX_JSON_STRING) { 247 ui_toggle_args_set_label(args, val->value.string.ptr); 248 } 249 250 val = cxJsonObjGet(value, "icon"); 251 if(val && val->type == CX_JSON_STRING) { 252 ui_toggle_args_set_icon(args, val->value.string.ptr); 253 } 254 255 val = cxJsonObjGet(value, "tooltip"); 256 if(val && val->type == CX_JSON_STRING) { 257 ui_toggle_args_set_tooltip(args, val->value.string.ptr); 258 } 259 260 val = cxJsonObjGet(value, "labeltype"); 261 if(val && val->type == CX_JSON_INTEGER) { 262 ui_toggle_args_set_labeltype(args, (int)val->value.integer); 263 } 264 265 val = cxJsonObjGet(value, "enable_group"); 266 if(val && val->type == CX_JSON_INTEGER) { 267 ui_toggle_args_set_enablestate(args, (int)val->value.integer); 268 } 269 270 return args; 271 } 272