diff -r e7459e9fbed2 -r 488178e3e328 client/args.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/args.c Sun Nov 30 18:15:46 2025 +0100 @@ -0,0 +1,234 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "args.h" + +#include "../ui/common/args.h" + +#define DEFAULT_ARG_FUNCS(var, prefix) \ + static ArgDefaultFuncs var = { \ + .fill = (argfunc_set_bool)prefix##_args_set_fill, \ + .hexpand = (argfunc_set_bool)prefix##_args_set_hexpand, \ + .vexpand = (argfunc_set_bool)prefix##_args_set_vexpand, \ + .hfill = (argfunc_set_bool)prefix##_args_set_hfill, \ + .vfill = (argfunc_set_bool)prefix##_args_set_vfill, \ + .override_defaults = (argfunc_set_bool)prefix##_args_set_override_defaults, \ + .margin = (argfunc_set_int)prefix##_args_set_margin, \ + .margin_left = (argfunc_set_int)prefix##_args_set_margin_left, \ + .margin_right = (argfunc_set_int)prefix##_args_set_margin_right, \ + .margin_top = (argfunc_set_int)prefix##_args_set_margin_top, \ + .margin_bottom = (argfunc_set_int)prefix##_args_set_margin_bottom, \ + .colspan = (argfunc_set_int)prefix##_args_set_colspan, \ + .rowspan = (argfunc_set_int)prefix##_args_set_rowspan, \ + .name = (argfunc_set_str)prefix##_args_set_name, \ + .style_class = (argfunc_set_str)prefix##_args_set_style_class \ + } + +DEFAULT_ARG_FUNCS(container_args, ui_container); + +DEFAULT_ARG_FUNCS(button_args, ui_button); + + + +static void init_common_args(const CxJsonValue *value, void *args, ArgDefaultFuncs *funcs) { + CxJsonValue *val; + + // boolean args + val = cxJsonObjGet(value, "fill"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + funcs->fill(args, TRUE); + } + + val = cxJsonObjGet(value, "hexpand"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + funcs->hexpand(args, TRUE); + } + + val = cxJsonObjGet(value, "vexpand"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + funcs->vexpand(args, TRUE); + } + + val = cxJsonObjGet(value, "hfill"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + funcs->hfill(args, TRUE); + } + + val = cxJsonObjGet(value, "vfill"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + funcs->vfill(args, TRUE); + } + + val = cxJsonObjGet(value, "override_defaults"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + funcs->override_defaults(args, TRUE); + } + + // int args + val = cxJsonObjGet(value, "margin"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->margin(args, (int)val->value.integer); + } + + val = cxJsonObjGet(value, "margin_left"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->margin_left(args, (int)val->value.integer); + } + + val = cxJsonObjGet(value, "margin_right"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->margin_right(args, (int)val->value.integer); + } + + val = cxJsonObjGet(value, "margin_top"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->margin_top(args, (int)val->value.integer); + } + + val = cxJsonObjGet(value, "margin_bottom"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->margin_bottom(args, (int)val->value.integer); + } + + val = cxJsonObjGet(value, "colspan"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->colspan(args, (int)val->value.integer); + } + + val = cxJsonObjGet(value, "rowspan"); + if(val && val->type == CX_JSON_INTEGER) { + funcs->rowspan(args, (int)val->value.integer); + } + + // string args + val = cxJsonObjGet(value, "name"); + if(val && val->type == CX_JSON_STRING) { + funcs->name(args, val->value.string.ptr); + } + + val = cxJsonObjGet(value, "style_class"); + if(val && val->type == CX_JSON_STRING) { + funcs->name(args, val->value.string.ptr); + } +} + +void init_groups(const CxJsonValue *value, void *args, argfunc_set_intarray setarray) { + CxJsonValue *val = cxJsonObjGet(value, "states"); + if(!val || val->type != CX_JSON_ARRAY) { + return; + } + + int len = (int)val->value.array.array_size; + int *states = calloc(len, sizeof(int)); + for(int i=0;ivalue.array.array[i]; + if(s->type == CX_JSON_INTEGER) { + states[i] = (int)s->value.integer; + } + } + + setarray(args, states, len); +} + +UiContainerArgs* json2container_args(const CxJsonValue *value) { + UiContainerArgs *args = ui_container_args_new(); + if(value->type != CX_JSON_OBJECT) { + return args; + } + + init_common_args(value, args, &container_args); + + CxJsonValue *val = cxJsonObjGet(value, "spacing"); + if(val && val->type == CX_JSON_INTEGER) { + args->spacing = (int)val->value.integer; + } + + val = cxJsonObjGet(value, "columnspacing"); + if(val && val->type == CX_JSON_INTEGER) { + args->columnspacing = (int)val->value.integer; + } + + val = cxJsonObjGet(value, "rowspacing"); + if(val && val->type == CX_JSON_INTEGER) { + args->rowspacing = (int)val->value.integer; + } + + val = cxJsonObjGet(value, "def_hfill"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + args->def_hfill = TRUE; + } + + val = cxJsonObjGet(value, "def_vfill"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + args->def_vfill = TRUE; + } + + val = cxJsonObjGet(value, "def_hexpand"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + args->def_hexpand = TRUE; + } + + val = cxJsonObjGet(value, "def_vexpand"); + if(val && val->type == CX_JSON_LITERAL && val->value.literal == CX_JSON_TRUE) { + args->def_vexpand = TRUE; + } + + return args; +} + +UiButtonArgs* json2button_args(const CxJsonValue *value) { + UiButtonArgs *args = ui_button_args_new(); + if(value->type != CX_JSON_OBJECT) { + return args; + } + + init_common_args(value, args, &button_args); + init_groups(value, args, (argfunc_set_intarray)ui_button_args_set_groups); + + CxJsonValue *val = cxJsonObjGet(value, "label"); + if(val && val->type == CX_JSON_STRING) { + ui_button_args_set_label(args, val->value.string.ptr); + } + + val = cxJsonObjGet(value, "icon"); + if(val && val->type == CX_JSON_STRING) { + ui_button_args_set_icon(args, val->value.string.ptr); + } + + val = cxJsonObjGet(value, "tooltip"); + if(val && val->type == CX_JSON_STRING) { + ui_button_args_set_tooltip(args, val->value.string.ptr); + } + + val = cxJsonObjGet(value, "labeltype"); + if(val && val->type == CX_JSON_INTEGER) { + ui_button_args_set_labeltype(args, (int)val->value.integer); + } + + return args; +}