diff --git a/ugui.c b/ugui.c index 3e57bf8..334568a 100644 --- a/ugui.c +++ b/ugui.c @@ -150,6 +150,10 @@ struct _UgCtx { int width, height; } size; + struct { + UgPoint margin; + } style; + // input structure, it describes the events received between frames struct { uint32_t flags; @@ -159,21 +163,22 @@ struct _UgCtx { }; // layouting -int ug_layout_row(void); -int ug_layout_column(void); -int ug_layout_floating(void); -int ug_layout_next_row(void); -int ug_layout_next_column(void); - -int ug_div_begin(UgCtx *ctx, const char *label, UgRect div); -int ug_div_end(UgCtx *ctx); -int ug_input_window_size(UgCtx *ctx, int width, int height); -UgId djb2(const char *str); -UgId FNV_1a(const char *str); +int ug_layout_set_row(UgCtx *ctx); +int ug_layout_set_column(UgCtx *ctx); +int ug_layout_set_floating(UgCtx *ctx); +// these reset the offsets introduced by the previous elements +int ug_layout_next_row(UgCtx *ctx); +int ug_layout_next_column(UgCtx *ctx); + +int ug_div_begin(UgCtx *ctx, const char *label, UgRect div); +int ug_div_end(UgCtx *ctx); +int ug_input_window_size(UgCtx *ctx, int width, int height); +static UgId djb2(const char *str); +static UgId FNV_1a(const char *str); int ug_button(UgCtx *ctx, const char *label, UgRect size); -UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect); +UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect, int style); int main(void) { @@ -201,21 +206,16 @@ int main(void) // main div, fill the whole window ug_div_begin(&ctx, "main", DIV_FILL); { + ug_layout_set_column(&ctx); ug_button( &ctx, - "batt342353453452wrwea", - (UgRect) {.y = 100, .x = 130, .w = 100, .h = 16} - ); - ug_button( - &ctx, - "arieasd3ree2234tast", - (UgRect) {.x = 10, .w = 30, .h = 30} - ); - ug_button( - &ctx, - "bughsdfsfdstton2", - (UgRect) {.x = 10, .w = 30, .h = 30} + "button0", + (UgRect) {.y = 100, .x = 100, .w = 30, .h = 30} ); + ug_layout_next_column(&ctx); + ug_button(&ctx, "button1", (UgRect) {.w = 30, .h = 30}); + ug_layout_next_column(&ctx); + ug_button(&ctx, "button2", (UgRect) {.w = 30, .h = 30}); } ug_div_end(&ctx); @@ -271,7 +271,7 @@ int main(void) // search the element of the corresponding id in the cache, if no element is found // insert a new one of that id. Return the pointer to the element -int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id) +static int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id) { int is_new = 0; uint32_t cache_idx; @@ -287,6 +287,21 @@ int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id) return is_new; } +static int get_parent(UgCtx *ctx, UgElem **parent) +{ + // take a reference to the parent + // FIXME: if the tree held pointers to the elements then no more + // redundant cache search + UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); + *parent = ug_cache_search(&ctx->cache, parent_id); + if (parent == NULL) { + // Error, did you forget to do frame_begin()? + return -1; + } + + return 0; +} + int ug_init(UgCtx *ctx) { if (ctx == NULL) { @@ -300,6 +315,9 @@ int ug_init(UgCtx *ctx) ctx->layout = row; ctx->div_using = 0; + // TODO: add style config + ctx->style.margin = (UgPoint) {2, 2}; + return 0; } @@ -316,7 +334,7 @@ int ug_destroy(UgCtx *ctx) return 0; } -void print_tree(UgCtx *ctx) +static void print_tree(UgCtx *ctx) { printf("ctx->tree: ["); for (int c = -1, x; (x = ug_tree_level_order_it(&ctx->tree, 0, &c)) != -1;) { @@ -423,7 +441,7 @@ int ug_input_window_size(UgCtx *ctx, int width, int height) return 0; } -UgId FNV_1a(const char *str) +static UgId FNV_1a(const char *str) { const uint64_t fnv_off = 0xcbf29ce484222325; const uint64_t fnv_prime = 0x100000001b3; @@ -437,7 +455,7 @@ UgId FNV_1a(const char *str) return hash; } -UgId djb2(const char *str) +static UgId djb2(const char *str) { uint64_t hash = 5381; uint32_t c; @@ -468,13 +486,8 @@ int ug_div_begin(UgCtx *ctx, const char *label, UgRect div) printf("Error adding to tree\n"); } - // take a reference to the parent - // FIXME: if the tree held pointers to the elements then no more - // redundant cache search - UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); - UgElem *parent = ug_cache_search(&ctx->cache, parent_id); - if (parent == NULL) { - // Error, did you forget to do frame_begin()? + UgElem *parent; + if (get_parent(ctx, &parent)) { return -1; } @@ -491,7 +504,7 @@ int ug_div_begin(UgCtx *ctx, const char *label, UgRect div) // do layout and update flags only if the element was updated if (is_new || FTEST(parent, ELEM_UPDATED)) { // 2. layout the element - c_elem->rect = position_element(ctx, parent, div); + c_elem->rect = position_element(ctx, parent, div, 0); // 3. Mark the element as updated c_elem->flags |= ELEM_UPDATED; @@ -532,7 +545,7 @@ int ug_div_end(UgCtx *ctx) } // position the rectangle inside the parent according to the layout -UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect) +UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect, int style) { UgRect elem_rect = {0}; UgPoint origin = {0}; @@ -571,6 +584,18 @@ UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect) .y = elem_rect.y + elem_rect.h, }; + // if using the style then apply margins + if (style && parent->div.layout != DIV_LAYOUT_FLOATING) { + elem_rect.x += ctx->style.margin.x; + elem_rect.y += ctx->style.margin.y; + + parent->div.origin_r.x += ctx->style.margin.x; + // parent->div.origin_r.y += ctx->style.margin.y; + + // parent->div.origin_c.x += ctx->style.margin.x; + parent->div.origin_c.y += ctx->style.margin.y; + } + /* printf( "positioning rect: %lx {%d %d %d %d}(%d %d %d %d) -> {%d %d %d @@ -603,13 +628,8 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size) ug_tree_add(&ctx->tree, id, ctx->div_using); print_tree(ctx); - // take a reference to the parent - // FIXME: if the tree held pointers to the elements then no more - // redundant cache search - UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); - UgElem *parent = ug_cache_search(&ctx->cache, parent_id); - if (parent == NULL) { - // Error, did you forget to do frame_begin()? + UgElem *parent; + if (get_parent(ctx, &parent)) { return -1; } @@ -621,7 +641,7 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size) // if the element is new or the parent was updated then redo layout if (is_new || parent->flags & ELEM_UPDATED) { // 2. Layout - c_elem->rect = position_element(ctx, parent, size); + c_elem->rect = position_element(ctx, parent, size, 1); // 3. TODO: Fill the button specific fields } else { @@ -641,3 +661,128 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size) return 0; } + +int ug_layout_set_row(UgCtx *ctx) +{ + if (ctx == NULL) { + return -1; + } + + UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); + UgElem *parent = ug_cache_search(&ctx->cache, parent_id); + if (parent == NULL) { + // Error, did you forget to do frame_begin()? + return -1; + } + + if (parent->type != ETYPE_DIV) { + // what? + return -1; + } + + parent->div.layout = DIV_LAYOUT_ROW; + + return 0; +} + +int ug_layout_set_column(UgCtx *ctx) +{ + if (ctx == NULL) { + return -1; + } + + UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); + UgElem *parent = ug_cache_search(&ctx->cache, parent_id); + if (parent == NULL) { + // Error, did you forget to do frame_begin()? + return -1; + } + + if (parent->type != ETYPE_DIV) { + // what? + return -1; + } + + parent->div.layout = DIV_LAYOUT_COLUMN; + + return 0; +} + +int ug_layout_set_floating(UgCtx *ctx) +{ + if (ctx == NULL) { + return -1; + } + + UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); + UgElem *parent = ug_cache_search(&ctx->cache, parent_id); + if (parent == NULL) { + // Error, did you forget to do frame_begin()? + return -1; + } + + if (parent->type != ETYPE_DIV) { + // what? + return -1; + } + + parent->div.layout = DIV_LAYOUT_FLOATING; + + return 0; +} + +int ug_layout_next_row(UgCtx *ctx) +{ + if (ctx == NULL) { + return -1; + } + + UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); + UgElem *parent = ug_cache_search(&ctx->cache, parent_id); + if (parent == NULL) { + // Error, did you forget to do frame_begin()? + return -1; + } + + if (parent->type != ETYPE_DIV) { + // what? + return -1; + } + + parent->div.origin_r = (UgPoint) { + .x = parent->rect.x, + .y = parent->div.origin_c.y, + }; + + parent->div.origin_c = parent->div.origin_r; + + return 0; +} + +int ug_layout_next_column(UgCtx *ctx) +{ + if (ctx == NULL) { + return -1; + } + + UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using); + UgElem *parent = ug_cache_search(&ctx->cache, parent_id); + if (parent == NULL) { + // Error, did you forget to do frame_begin()? + return -1; + } + + if (parent->type != ETYPE_DIV) { + // what? + return -1; + } + + parent->div.origin_c = (UgPoint) { + .x = parent->div.origin_r.x, + .y = parent->rect.y, + }; + + parent->div.origin_r = parent->div.origin_c; + + return 0; +}