From 46e6e378d0b4bc3291204751b136cca453cb4189 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Thu, 8 Dec 2022 16:09:42 +0100 Subject: [PATCH] directional resize --- test/main.c | 2 +- ugui.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++----- ugui.h | 20 +++++++--- 3 files changed, 116 insertions(+), 15 deletions(-) diff --git a/test/main.c b/test/main.c index daefef0..aae0719 100644 --- a/test/main.c +++ b/test/main.c @@ -180,7 +180,7 @@ int main(void) (ug_div_t){.x=SIZE_PX(0), .y=SIZE_PX(0), .w=SIZE_PX(100), .h=SIZE_MM(75.0)}); ug_container_floating(ctx, "better name", (ug_div_t){.x=SIZE_PX(-10), .y=SIZE_PT(-16), .w=SIZE_MM(100), .h=SIZE_PX(15)}); - + ug_container_sidebar(ctx, "Sidebar", (ug_size_t)SIZE_PX(300), UG_SIDE_BOTTOM); ug_frame_end(ctx); // fill background diff --git a/ugui.c b/ugui.c index fc6ed13..9754f0e 100644 --- a/ugui.c +++ b/ugui.c @@ -13,6 +13,11 @@ #define DEF_PPI 96.0 #define STACK_STEP 64 +#define RESIZEALL UG_CNT_RESIZE_RIGHT | \ + UG_CNT_RESIZE_BOTTOM | \ + UG_CNT_RESIZE_LEFT | \ + UG_CNT_RESIZE_TOP + #define PPI_PPM(ppi, scale) (ppi * scale * 0.03937008) #define PPI_PPD(ppi, scale) (PPI_PPM(ppi, scale) * 0.3528) #define IS_VALID_UNIT(u) (u==UG_UNIT_PX||u==UG_UNIT_MM||u==UG_UNIT_PT) @@ -357,7 +362,7 @@ static void update_container(ug_ctx_t *ctx, ug_container_t *cnt) // be resized from the bottom and right border // TODO: bring selected container to the top of the stack if (!(ctx->mouse.down_mask & UG_BTN_LEFT) || - !(cnt->flags & (UG_CNT_RESIZABLE | UG_CNT_MOVABLE))) + !(cnt->flags & (RESIZEALL | UG_CNT_MOVABLE))) goto cnt_draw; ug_vec2_t mpos = ctx->mouse.pos; @@ -365,9 +370,9 @@ static void update_container(ug_ctx_t *ctx, ug_container_t *cnt) // handle movable windows if (cnt->flags & UG_CNT_MOVABLE) { - minx = rca->x; + minx = rca->x + bl; maxx = rca->x + rca->w - br; - miny = rca->y; + miny = rca->y + bt; maxy = rca->y + bt + hh; if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { // if a relative container has been moved consider it no @@ -384,25 +389,57 @@ static void update_container(ug_ctx_t *ctx, ug_container_t *cnt) } } - if (cnt->flags & UG_CNT_RESIZABLE) { - // right border resize + // right border resize + if (cnt->flags & UG_CNT_RESIZE_RIGHT) { minx = rca->x + rca->w - br; maxx = rca->x + rca->w; miny = rca->y; maxy = rca->y + rca->h; if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { rect->w += ctx->mouse.delta.x; - rca->w += ctx->mouse.delta.x; + rca->w += ctx->mouse.delta.x; + } + } + + // left border resize + if (cnt->flags & UG_CNT_RESIZE_LEFT) { + minx = rca->x - bl; + maxx = rca->x; + miny = rca->y; + maxy = rca->y + rca->h; + if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { + rect->w -= ctx->mouse.delta.x; + rca->w -= ctx->mouse.delta.x; + + rect->x += ctx->mouse.delta.x; + rca->x += ctx->mouse.delta.x; } + } - // bottom border resize + // bottom border resize + if (cnt->flags & UG_CNT_RESIZE_BOTTOM) { minx = rca->x; maxx = rca->x + rca->w; miny = rca->y + rca->h - bb; maxy = rca->y + rca->h; if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { rect->h += ctx->mouse.delta.y; - rca->h += ctx->mouse.delta.y; + rca->h += ctx->mouse.delta.y; + } + } + + // top border resize + if (cnt->flags & UG_CNT_RESIZE_TOP) { + minx = rca->x; + maxx = rca->x + rca->w; + miny = rca->y - bt; + maxy = rca->y; + if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { + rect->h -= ctx->mouse.delta.y; + rca->h -= ctx->mouse.delta.y; + + rect->y += ctx->mouse.delta.y; + rca->y += ctx->mouse.delta.y; } } @@ -461,7 +498,7 @@ int ug_container_floating(ug_ctx_t *ctx, const char *name, ug_div_t div) cnt->id = id; cnt->max_size = max_size; cnt->rect = div_to_rect(ctx, &div); - cnt->flags = UG_CNT_MOVABLE | UG_CNT_RESIZABLE | + cnt->flags = UG_CNT_MOVABLE | RESIZEALL | UG_CNT_SCROLL_X | UG_CNT_SCROLL_Y ; } @@ -471,6 +508,60 @@ int ug_container_floating(ug_ctx_t *ctx, const char *name, ug_div_t div) } +int ug_container_sidebar(ug_ctx_t *ctx, const char *name, ug_size_t size, int side) +{ + TEST_CTX(ctx); + + ug_id_t id = 0; + if (name) { + id = hash(name, strlen(name)); + } else { + int blob[3] = { size.size.i, size.unit, side}; + id = hash(blob, sizeof(blob)); + } + + ug_container_t *cnt = get_container(ctx, id); + + if (cnt->id) { + // nothing? maybe we can skip updating all dimensions and stuff + } else { + cnt->id = id; + cnt->max_size = max_size; + cnt->flags = UG_CNT_SCROLL_X | UG_CNT_SCROLL_Y; + ug_rect_t rect = {0}; + switch (side) { + case UG_SIDE_BOTTOM: + cnt->flags |= UG_CNT_RESIZE_TOP; + // FIXME: we do not support relative zero position yet + rect.y = -1; + rect.h = size_to_px(ctx, size); + break; + case UG_SIDE_TOP: + cnt->flags |= UG_CNT_RESIZE_BOTTOM; + rect.h = size_to_px(ctx, size); + break; + case UG_SIDE_RIGHT: + cnt->flags |= UG_CNT_RESIZE_LEFT; + rect.x = -1; + rect.w = size_to_px(ctx, size); + break; + case UG_SIDE_LEFT: + cnt->flags |= UG_CNT_RESIZE_RIGHT; + rect.w = size_to_px(ctx, size); + break; + default: return -1; + } + cnt->rect = rect; + } + + update_container(ctx, cnt); + + // TODO: change available context space to reflect adding a sidebar + + return 0; +} + + /*=============================================================================* * Input Handling * *=============================================================================*/ diff --git a/ugui.h b/ugui.h index 9686cee..08bd325 100644 --- a/ugui.h +++ b/ugui.h @@ -39,10 +39,13 @@ typedef struct { // the container flags enum { - UG_CNT_MOVABLE = BIT(0), // can be moved - UG_CNT_RESIZABLE = BIT(1), // can be resized - UG_CNT_SCROLL_X = BIT(2), // can have horizontal scrolling - UG_CNT_SCROLL_Y = BIT(3), // can have vertical scrolling + UG_CNT_MOVABLE = BIT(0), // can be moved + UG_CNT_RESIZE_RIGHT = BIT(1), // can be resized + UG_CNT_RESIZE_BOTTOM = BIT(2), // can be resized + UG_CNT_RESIZE_LEFT = BIT(3), // can be resized + UG_CNT_RESIZE_TOP = BIT(4), // can be resized + UG_CNT_SCROLL_X = BIT(5), // can have horizontal scrolling + UG_CNT_SCROLL_Y = BIT(6), // can have vertical scrolling }; // style, defines default height, width, color, margins, borders, etc @@ -111,6 +114,13 @@ typedef enum { UG_CMD_RECT, } ug_cmd_type_t; +// window side +enum { + UG_SIDE_TOP = 0, + UG_SIDE_BOTTOM, + UG_SIDE_LEFT, + UG_SIDE_RIGHT, +}; // mouse buttons enum { @@ -196,7 +206,7 @@ int ug_container_popup(ug_ctx_t *ctx, const char *name, ug_rect_t rect); // top of the window int ug_container_menu_bar(ug_ctx_t *ctx, const char *name, int height); // a sidebar is a variable size container anchored to one side of the window -int ug_container_sidebar(ug_ctx_t *ctx, const char *name, int width); +int ug_container_sidebar(ug_ctx_t *ctx, const char *name, ug_size_t size, int side); // a body is a container that scales with the window, sits at it's center and cannot // be resized int ug_container_body(ug_ctx_t *ctx, const char *name);