1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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