#include <cx/linked_list.h>
#include <cx/buffer.h>
#include "container.h"
#include "widget.h"
#include "args.h"
void ui_container_begin_close(UiObject *obj) {
UiContainerX *ct = obj->container_end;
ct->close =
1;
}
int ui_container_finish(UiObject *obj) {
UiContainerX *ct = obj->container_end;
if(ct->close) {
ui_end_new(obj);
return 0;
}
return 1;
}
UiContainerX* ui_widget_container(UiWidget *w) {
UiContainerX *container = cxZalloc(w->obj->ctx->allocator,
sizeof(UiContainerX));
container->container = w;
return container;
}
cxmutstr ui_container_args_to_string(UiContext *ctx, UiContainerArgs *args) {
CxBuffer buf;
cxBufferInit(&buf,
NULL,
256, ctx->allocator,
CX_BUFFER_AUTO_EXTEND |
CX_BUFFER_FREE_CONTENTS);
cxBufferPutString(&buf,
"{");
UI_STANDARD_ARGS(&buf, args);
UI_SPACING_ARGS(&buf, args);
if(args->def_hfill) cxBufferPutString(&buf,
"\"def_hfill\":true,");
if(args->def_vfill) cxBufferPutString(&buf,
"\"def_vfill\":true,");
if(args->def_hexpand) cxBufferPutString(&buf,
"\"def_hexpand\":true,");
if(args->def_vexpand) cxBufferPutString(&buf,
"\"def_vexpand\":true,");
if(buf.size >
0 && buf.space[buf.size
-1] ==
',') {
buf.space[buf.size
-1] =
' ';
}
cxBufferPutString(&buf,
"}");
return cx_mutstrn(buf.space, buf.size);
}
static UIWIDGET container_create(UiObject *obj,
const char *type, UiContainerArgs *args) {
const CxAllocator *a = obj->ctx->allocator;
UiWidget *widget = cxZalloc(a,
sizeof(UiWidget));
widget->obj = obj->widget->obj;
widget->type = cx_str(type);
widget->args = ui_container_args_to_string(obj->ctx, args);
widget->children = cxLinkedListCreate(a,
NULL,
CX_STORE_POINTERS);
widget->serialize = ui_container_serialize;
UiWidget *parent = obj->container_end->container;
cxListAdd(parent->children, widget);
uic_object_push_container(obj, ui_widget_container(widget));
ui_reg_widget((UiWidget*)widget);
return widget;
}
void ui_serialize_children(UiWidget *w, CxBuffer *buf) {
size_t numchildren = cxListSize(w->children);
if(numchildren >
0) {
cxBufferPutString(buf,
",\"children\":[");
CxIterator i = cxListIterator(w->children);
cx_foreach(UiWidget *, child, i) {
cxmutstr child_str = child->serialize(child);
cxBufferWrite(child_str.ptr,
1, child_str.length, buf);
if(i.index
+1 < numchildren) {
cxBufferPut(buf,
',');
}
}
cxBufferPutString(buf,
"]");
}
}
cxmutstr ui_container_serialize(UiWidget *w) {
CxBuffer buf;
cxBufferInit(&buf,
NULL,
1024,
NULL,
CX_BUFFER_AUTO_EXTEND |
CX_BUFFER_FREE_CONTENTS);
cxBufferPutString(&buf,
"{");
ui_serialize_type_obj_id(w, &buf);
cxBufferPutString(&buf,
",\"args\":");
cxBufferPutString(&buf, w->args.ptr);
ui_serialize_children(w, &buf);
cxBufferPutString(&buf,
"}\n");
return cx_mutstrn(buf.space, buf.size);
}
UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args) {
return container_create(obj,
"vbox", args);
}
UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args) {
return container_create(obj,
"hbox", args);
}
UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) {
return container_create(obj,
"grid", args);
}