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 <cx/linked_list.h> 30 #include <cx/buffer.h> 31 32 #include "container.h" 33 #include "widget.h" 34 #include "args.h" 35 36 void ui_container_begin_close(UiObject *obj) { 37 UiContainerX *ct = obj->container_end; 38 ct->close = 1; 39 } 40 41 int ui_container_finish(UiObject *obj) { 42 UiContainerX *ct = obj->container_end; 43 if(ct->close) { 44 ui_end_new(obj); 45 return 0; 46 } 47 return 1; 48 } 49 50 UiContainerX* ui_widget_container(UiWidget *w) { 51 UiContainerX *container = cxZalloc(w->obj->ctx->allocator, sizeof(UiContainerX)); 52 container->container = w; 53 return container; 54 } 55 56 cxmutstr ui_container_args_to_string(UiContext *ctx, UiContainerArgs *args) { 57 CxBuffer buf; 58 cxBufferInit(&buf, NULL, 256, ctx->allocator, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); 59 60 cxBufferPutString(&buf, "{"); 61 62 UI_STANDARD_ARGS(&buf, args); 63 UI_SPACING_ARGS(&buf, args); 64 if(args->def_hfill) cxBufferPutString(&buf, "\"def_hfill\":true,"); 65 if(args->def_vfill) cxBufferPutString(&buf, "\"def_vfill\":true,"); 66 if(args->def_hexpand) cxBufferPutString(&buf, "\"def_hexpand\":true,"); 67 if(args->def_vexpand) cxBufferPutString(&buf, "\"def_vexpand\":true,"); 68 69 if(buf.size > 0 && buf.space[buf.size-1] == ',') { 70 buf.space[buf.size-1] = ' '; 71 } 72 cxBufferPutString(&buf, "}"); 73 return cx_mutstrn(buf.space, buf.size); 74 } 75 76 static UIWIDGET container_create(UiObject *obj, const char *type, UiContainerArgs *args) { 77 const CxAllocator *a = obj->ctx->allocator; 78 UiWidget *widget = cxZalloc(a, sizeof(UiWidget)); 79 widget->obj = obj->widget->obj; 80 widget->type = cx_str(type); 81 widget->args = ui_container_args_to_string(obj->ctx, args); 82 widget->children = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS); 83 widget->serialize = ui_container_serialize; 84 85 UiWidget *parent = obj->container_end->container; 86 cxListAdd(parent->children, widget); 87 88 uic_object_push_container(obj, ui_widget_container(widget)); 89 ui_reg_widget((UiWidget*)widget); 90 91 return widget; 92 } 93 94 void ui_serialize_children(UiWidget *w, CxBuffer *buf) { 95 size_t numchildren = cxListSize(w->children); 96 if(numchildren > 0) { 97 cxBufferPutString(buf, ",\"children\":["); 98 CxIterator i = cxListIterator(w->children); 99 cx_foreach(UiWidget *, child, i) { 100 cxmutstr child_str = child->serialize(child); 101 cxBufferWrite(child_str.ptr, 1, child_str.length, buf); 102 if(i.index+1 < numchildren) { 103 cxBufferPut(buf, ','); 104 } 105 } 106 cxBufferPutString(buf, "]"); 107 } 108 } 109 110 cxmutstr ui_container_serialize(UiWidget *w) { 111 CxBuffer buf; 112 cxBufferInit(&buf, NULL, 1024, NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); 113 114 cxBufferPutString(&buf, "{"); 115 ui_serialize_type_obj_id(w, &buf); 116 cxBufferPutString(&buf, ",\"args\":"); 117 cxBufferPutString(&buf, w->args.ptr); 118 119 ui_serialize_children(w, &buf); 120 121 cxBufferPutString(&buf, "}\n"); 122 123 return cx_mutstrn(buf.space, buf.size); 124 } 125 126 UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args) { 127 return container_create(obj, "vbox", args); 128 } 129 130 UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args) { 131 return container_create(obj, "hbox", args); 132 } 133 134 UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { 135 return container_create(obj, "grid", args); 136 } 137