From 29af23992ed4168f2b9c2b0557d6b1f1b9d408cc Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Fri, 23 Dec 2022 00:18:04 +0100 Subject: [PATCH] haha --- ugui.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++-------- ugui.h | 55 +++++++++++++++++++++++++--- 2 files changed, 147 insertions(+), 21 deletions(-) diff --git a/ugui.c b/ugui.c index 53f4e16..ec5108a 100644 --- a/ugui.c +++ b/ugui.c @@ -171,6 +171,20 @@ static void update_style_cache(ug_ctx_t *ctx) } +void scale_rect(ug_ctx_t *ctx, ug_rect_t *rect) +{ + if (ctx->ppi != ctx->last_ppi) { + // if the scale has been updated than we need to scale the container + // as well + float scale = ctx->ppi / ctx->last_ppi; + rect->x = roundf(rect->x * scale); + rect->y = roundf(rect->y * scale); + rect->w = roundf(rect->w * scale); + rect->h = roundf(rect->h * scale); + } +} + + /*=============================================================================* * Command Operations * *=============================================================================*/ @@ -378,24 +392,16 @@ static void sort_containers(ug_ctx_t *ctx) // update the container position in the context area static int position_container(ug_ctx_t *ctx, ug_container_t *cnt) { - if (!TEST(cnt->flags, UG_CNT_FLOATING)) + if (!TEST(cnt->flags, UG_CNT_FLOATING)) { // if there is no space left propagate the error if (ctx->origin.w <= 0 || ctx->origin.h <= 0) return -1; + } ug_rect_t *rect, *rca; - rect = &cnt->rect; - rca = &cnt->rca; - - if (ctx->ppi != ctx->last_ppi) { - // if the scale has been updated than we need to scale the container - // as well - float scale = ctx->ppi / ctx->last_ppi; - rect->x = roundf(rect->x * scale); - rect->y = roundf(rect->y * scale); - rect->w = roundf(rect->w * scale); - rect->h = roundf(rect->h * scale); - } + rect = &(cnt->rect); + rca = &(cnt->rca); + scale_rect(ctx, rect); *rca = *rect; @@ -863,9 +869,11 @@ int ug_container_body(ug_ctx_t *ctx, const char *name) int ug_container_remove(ug_ctx_t *ctx, const char *name) { TEST_CTX(ctx); - TEST_STR(name); - ug_id_t id = hash(name, strlen(name)); + ug_id_t id = ctx->selected_cnt; + if (name) + id = hash(name, strlen(name)); + ug_container_t *c = search_container(ctx, id); if (c) { c->flags |= CNT_STATE_DELETE; @@ -874,6 +882,23 @@ int ug_container_remove(ug_ctx_t *ctx, const char *name) } +ug_rect_t ug_container_get_rect(ug_ctx_t *ctx, const char *name) +{ + ug_rect_t r = {0}; + if(!ctx) + return r; + + ug_id_t id = ctx->selected_cnt; + if (name) + id = hash(name, strlen(name)); + + ug_container_t *c = search_container(ctx, id); + if (c) + r = c->rca; + return r; +} + + /*=============================================================================* * Input Handling * *=============================================================================*/ @@ -981,6 +1006,9 @@ int ug_frame_end(ug_ctx_t *ctx) for (int i = 0; i < ctx->cnt_stack.idx; i++) { ug_container_t *c = &ctx->cnt_stack.items[i]; draw_container(ctx, c, c->name); + // TODO: draw elements + // reset the layout to row + c->flags &= ~(CNT_LAYOUT_COLUMN); } ctx->input_text[0] = '\0'; @@ -1009,3 +1037,58 @@ int ug_frame_end(ug_ctx_t *ctx) return 0; } + + +/*=============================================================================* + * Layouting * + *=============================================================================*/ + + +#define GET_SELECTED_CONTAINER(ctx, cp) \ +{ \ + cp = search_container(ctx, ctx->selected_cnt); \ + if (!cp) \ + return -1; \ +} + + +// set the layout to row +int ug_layout_row(ug_ctx_t *ctx) +{ + TEST_CTX(ctx); + + ug_container_t *cp; + GET_SELECTED_CONTAINER(ctx, cp); + cp->flags &= ~CNT_LAYOUT_COLUMN; + return 0; +} + + +// set the layout to column +int ug_layout_column(ug_ctx_t *ctx) +{ + TEST_CTX(ctx); + + ug_container_t *cp; + GET_SELECTED_CONTAINER(ctx, cp); + cp->flags |= CNT_LAYOUT_COLUMN; + return 0; +} + + +/*=============================================================================* + * Elements * + *=============================================================================*/ + + +int ug_element_button(ug_ctx_t *ctx, const char *name, const char *txt, ug_div_t dim) +{ + TEST_CTX(ctx); + TEST_STR(name); + + ug_container_t *cp; + GET_SELECTED_CONTAINER(ctx, cp); + + // TODO: this + return 0; +} diff --git a/ugui.h b/ugui.h index 8d0d152..a360c0a 100644 --- a/ugui.h +++ b/ugui.h @@ -24,6 +24,30 @@ typedef enum { UG_UNIT_PT, } ug_unit_t; + +// element type +typedef struct { + ug_id_t id; + unsigned int type; + ug_rect_t rect, rca; + char *name, *content; +} ug_element_t; + +enum { + UG_ELEM_BUTTON, // button + UG_ELEM_TXTBTN, // textual button, a button but without frame + UG_ELEM_CHECK, // checkbox + UG_ELEM_RADIO, // radio button + UG_ELEM_TOGGLE, // toggle button + UG_ELEM_LABEL, // simple text + UG_ELEM_UPDOWN, // text with two buttons up and down + UG_ELEM_TEXTINPUT, // text input box + UG_ELEM_TEXTBOX, // text surrounded by a box + UG_ELEM_IMG, // image, icon + UG_ELEM_SPACE, // takes up space +}; + + // container type, a container is an entity that contains layouts, a container has // a haight a width and their maximum values, in essence a container is a rectangular // area that can be resized and sits somewhere on the drawable region @@ -35,6 +59,10 @@ typedef struct { // absolute position rect ug_rect_t rca; unsigned int flags; + // layouting and elements + ug_rect_t orig; // origin and space available + int r, c; // row and column + UG_STACK(ug_element_t); } ug_container_t; // the container flags @@ -55,6 +83,8 @@ enum { CNT_STATE_RESIZE_L = BIT(26), CNT_STATE_RESIZE_R = BIT(25), CNT_STATE_DELETE = BIT(24), // The container is marked for removal + // layouting + CNT_LAYOUT_COLUMN = BIT(23), }; // style, defines default height, width, color, margins, borders, etc @@ -174,6 +204,8 @@ typedef struct { ug_id_t cnt, elem; } last_active; // id of the selected container, used for layout + // NOTE: since the stacks can be relocated with realloc it is better not + // to use a pointer here, even tough it would be better for efficiency ug_id_t selected_cnt; // count the frames for fun unsigned long int frame; @@ -228,13 +260,24 @@ int ug_container_sidebar(ug_ctx_t *ctx, const char *name, ug_size_t size, int si // a body is a container that scales with the window, sits at it's center and cannot // be resized, it also fills all the available space int ug_container_body(ug_ctx_t *ctx, const char *name); -// mark a conatiner for removal, it will be freed at the next frame beginning +// mark a conatiner for removal, it will be freed at the next frame beginning if +// name is NULL then use the selected container int ug_container_remove(ug_ctx_t *ctx, const char *name); - - -// layouts - - +// get the drawable area of the container, if name is NULL then use the selected +// container +ug_rect_t ug_container_get_rect(ug_ctx_t *ctx, const char *name); + +// layouting, the following functions define how different ui elements are placed +// inside the selected container. A new element is aligned respective to the +// previous element and/or to the container, particularly elements can be placed +// in a row or a column. +int ug_layout_row(ug_ctx_t *ctx); +int ug_layout_column(ug_ctx_t *ctx); +int ug_layout_next_row(ug_ctx_t *ctx); +int ug_layout_next_column(ug_ctx_t *ctx); + +// elements +int ug_element_button(ug_ctx_t *ctx, const char *name, const char *txt, ug_div_t dim); // Input functions int ug_input_mousemove(ug_ctx_t *ctx, int x, int y);