clay/src/layout.c
Gwendolyn d89ef83551 Reworked property system completely.
Properties can now have values of different types, and they are registered with their name, either to a layout class or globally.
Layout classes are also registered with their name.
2023-02-08 01:09:21 +01:00

85 lines
2.4 KiB
C

#include <malloc.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include "layout.h"
#include "context.h"
#include "clay.h"
clay clay_create(clay_ctx ctx, const char *layout_class_name) {
clay_layout_class class = clay_ctx_get_layout_class(ctx, layout_class_name);
return clay_layout_create(ctx, class);
}
clay clay_layout_create(clay_ctx ctx, clay_layout_class class) {
clay layout = malloc(sizeof(*layout));
assert(layout != NULL);
layout->properties = clay_map_create(clay_property_map, 5);
layout->children = clay_list_create(clay_layout_list);
layout->class = class;
layout->ctx = ctx;
if (layout->class->init != NULL) {
layout->class->init(layout);
}
clay_ctx_register_layout(ctx, layout);
return layout;
}
void clay_layout_destroy(clay layout) {
clay_ctx_unregister_layout(layout->ctx, layout);
clay_layout_cleanup(layout);
free(layout);
}
void clay_layout_cleanup(clay layout) {
if (layout->class->cleanup != NULL) {
layout->class->cleanup(layout);
}
clay_map_destroy(layout->properties);
clay_list_destroy(layout->children);
}
clay clay_clone(clay layout) {
clay cloned = malloc(sizeof(*cloned));
cloned->class = layout->class;
cloned->ctx = layout->ctx;
cloned->properties = clay_map_clone(layout->properties);
cloned->children = clay_list_create(clay_layout_list);
clay_ctx_register_layout(layout->ctx, cloned);
return cloned;
}
clay clay_clone_recursive(clay layout) {
// todo: should this function be made non-recursive (i.e. replace with loop + manual stack)?
clay cloned = clay_clone(layout);
CLAY_LIST_FOREACH(layout->children, child, _) {
clay cloned_child = clay_clone_recursive(*child);
clay_list_append(cloned->children, cloned_child);
}
return cloned;
}
void clay_append_child(clay parent, clay child) {
if (child->parent != NULL) {
CLAY_LIST_FOREACH(child->parent->children, el_ptr, idx) {
if (*el_ptr == child) {
clay_list_remove(child->parent->children, idx);
break;
}
}
}
clay_list_append(parent->children, child);
child->parent = parent;
}
clay_layout_list_const clay_layout_get_children(clay layout) {
return layout->children;
}
clay clay_layout_get_parent(clay layout) {
return layout->parent;
}