#ifndef CLAYOUT_CLAY_H #define CLAYOUT_CLAY_H #include #include typedef struct clay_ctx_t *clay_ctx; typedef struct clay_t *clay; clay_ctx clay_create_context(void); void clay_destroy_context(clay_ctx); clay clay_create(clay_ctx ctx, const char *layout_class_name); clay clay_clone(clay); clay clay_clone_recursive(clay); void clay_layout_set_property(clay layout, const char *prop_name, int num_values, ...); /* * A layout can only be child of one parent layout. * If a layout that is already a child of a parent layout is appended as a child to another layout, * it is automatically removed from its previous parent. */ void clay_append_child(clay parent, clay child); void clay_layout_destroy(clay layout); void clay_render_to_png(clay, const char *); void clay_print_layout_tree(clay doc); typedef struct { uint8_t red; uint8_t green; uint8_t blue; uint8_t alpha; } clay_color; enum clay_prop_val_in_type { TYPE_INT, TYPE_DOUBLE, TYPE_STRING, TYPE_COLOR, }; struct clay_prop_val_in { enum clay_prop_val_in_type type; union { int value_int; double value_double; const char *value_string; clay_color value_color; }; }; static inline struct clay_prop_val_in clay_make_prop_val(enum clay_prop_val_in_type type, ...) { struct clay_prop_val_in result = {.type=type}; va_list args; va_start(args, type); switch (type) { case TYPE_INT: result.value_int = va_arg(args, int); break; case TYPE_DOUBLE: result.value_double = va_arg(args, double); break; case TYPE_STRING: result.value_string = va_arg(args, const char *); break; case TYPE_COLOR: result.value_color = va_arg(args, clay_color); break; } va_end(args); return result; } #define _clay_value(v) _Generic(v, \ char *: clay_make_prop_val(TYPE_STRING, v), \ const char *: clay_make_prop_val(TYPE_STRING, v), \ int: clay_make_prop_val(TYPE_INT, v), \ double: clay_make_prop_val(TYPE_DOUBLE, v), \ clay_color: clay_make_prop_val(TYPE_COLOR, v) \ ) #define _clay_set1(l, n, v1) clay_layout_set_property(l, n, 1, _clay_value(v1)) #define _clay_set2(l, n, v1, v2) clay_layout_set_property(l, n, 2, _clay_value(v1), _clay_value(v2)) #define _clay_set3(l, n, v1, v2, v3) clay_layout_set_property(l, n, 3, _clay_value(v1), _clay_value(v2), _clay_value(v3)) #define _clay_set4(l, n, v1, v2, v3, v4) clay_layout_set_property(l, n, 4, _clay_value(v1), _clay_value(v2), _clay_value(v3), _clay_value(v4)) #define _clay_macro_overload(_1, _2, _3, _4, NAME, ...) NAME #define clay_set(l, n, ...) _clay_macro_overload(__VA_ARGS__, _clay_set4, _clay_set3, _clay_set2, _clay_set1)(l, n, __VA_ARGS__) /////////////////////////////////////////////////////////////////////// void clay_document_register(clay_ctx ctx); // todo: should be private void clay_flex_register(clay_ctx ctx); // todo: should be private void clay_text_register(clay_ctx ctx); // todo: should be private #endif //CLAYOUT_CLAY_H