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 "button.h" 30 #include <cx/buffer.h> 31 #include <cx/printf.h> 32 33 #include "args.h" 34 #include "container.h" 35 #include "widget.h" 36 #include "var.h" 37 38 cxmutstr ui_button_args_to_string(UiContext *ctx, UiButtonArgs *args) { 39 CxBuffer buf; 40 cxBufferInit(&buf, NULL, 256, ctx->allocator, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); 41 42 cxBufferPutString(&buf, "{"); 43 44 UI_STANDARD_ARGS(&buf, args); 45 UI_LABEL_ARGS(&buf, args); 46 if(args->labeltype != UI_LABEL_DEFAULT) ui_argstr_add_int(&buf, "labeltype", (int)args->labeltype); 47 48 if(buf.size > 0 && buf.space[buf.size-1] == ',') { 49 buf.space[buf.size-1] = ' '; 50 } 51 cxBufferPutString(&buf, "}"); 52 return cx_mutstrn(buf.space, buf.size); 53 } 54 55 cxmutstr ui_toggle_args_to_string(UiContext *ctx, UiToggleArgs *args, cxmutstr value) { 56 CxBuffer buf; 57 cxBufferInit(&buf, NULL, 256, ctx->allocator, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); 58 59 cxBufferPutString(&buf, "{"); 60 61 UI_STANDARD_ARGS(&buf, args); 62 UI_LABEL_ARGS(&buf, args); 63 if(value.ptr) ui_argstr_add_str(&buf, "value", value.ptr); 64 if(args->labeltype != UI_LABEL_DEFAULT) ui_argstr_add_int(&buf, "labeltype", (int)args->labeltype); 65 66 if(buf.size > 0 && buf.space[buf.size-1] == ',') { 67 buf.space[buf.size-1] = ' '; 68 } 69 cxBufferPutString(&buf, "}"); 70 return cx_mutstrn(buf.space, buf.size); 71 } 72 73 74 UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) { 75 UiCallbackWidget *widget = cxZalloc(obj->ctx->allocator, sizeof(UiCallbackWidget)); 76 widget->widget.obj = obj->widget->obj; 77 widget->widget.type = CX_STR("button"); 78 widget->widget.args = ui_button_args_to_string(obj->ctx, args); 79 widget->widget.serialize = (ui_serialize_func)ui_button_serialize; 80 widget->callback = args->onclick; 81 widget->userdata = args->onclickdata; 82 ui_reg_widget((UiWidget*)widget); 83 84 UiWidget *parent = obj->container_end->container; 85 cxListAdd(parent->children, widget); 86 87 return (UiWidget*)widget; 88 } 89 90 cxmutstr ui_button_serialize(UiCallbackWidget *w) { 91 CxBuffer buf; 92 cxBufferInit(&buf, NULL, 1024, NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); 93 94 cxBufferPutString(&buf, "{"); 95 ui_serialize_type_obj_id(&w->widget, &buf); 96 cxBufferPutString(&buf, ",\"args\":"); 97 cxBufferPutString(&buf, w->widget.args.ptr); 98 if(w->widget.var_id.ptr) { 99 cxBufferPutString(&buf, ",\"value\":\""); 100 cxBufferPutString(&buf, w->widget.var_id.ptr); 101 cxBufferPutString(&buf, "\""); 102 } 103 cxBufferPutString(&buf, "}\n"); 104 105 return cx_mutstrn(buf.space, buf.size); 106 } 107 108 static UIWIDGET togglebutton_create(UiObject *obj, const char *type, UiToggleArgs *args) { 109 cxmutstr var_id = cx_mutstrn(NULL, 0); 110 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); 111 if(var) { 112 UiInteger *i = var->value; 113 if(!i->obj) { 114 ui_server_bind_int(obj->ctx, i); 115 } 116 var_id = cx_mutstr(i->obj); 117 } 118 119 UiCallbackWidget *widget = cxZalloc(obj->ctx->allocator, sizeof(UiCallbackWidget)); 120 widget->widget.obj = obj->widget->obj; 121 widget->widget.type = cx_str(type); 122 widget->widget.args = ui_toggle_args_to_string(obj->ctx, args, var_id); 123 widget->widget.var_id = var_id; 124 widget->widget.var_type = UI_VAR_INTEGER; 125 widget->widget.serialize = (ui_serialize_func)ui_button_serialize; 126 widget->callback = args->onchange; 127 widget->userdata = args->onchangedata; 128 ui_reg_widget((UiWidget*)widget); 129 130 UiWidget *parent = obj->container_end->container; 131 cxListAdd(parent->children, widget); 132 133 return (UiWidget*)widget; 134 } 135 136 UIWIDGET ui_togglebutton_create(UiObject *obj, UiToggleArgs *args) { 137 return togglebutton_create(obj, "togglebutton", args); 138 } 139 140 UIWIDGET ui_checkbox_create(UiObject *obj, UiToggleArgs *args) { 141 return togglebutton_create(obj, "checkbox", args); 142 } 143 144 UIWIDGET ui_switch_create(UiObject *obj, UiToggleArgs *args) { 145 return togglebutton_create(obj, "switch", args); 146 } 147 148 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args) { 149 return togglebutton_create(obj, "radiobutton", args); 150 } 151