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