d89ef83551
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.
85 lines
2.4 KiB
C
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;
|
|
}
|