directional resize

master
Alessandro Mauri 2 years ago
parent e998b6c287
commit 46e6e378d0
  1. 2
      test/main.c
  2. 101
      ugui.c
  3. 18
      ugui.h

@ -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

101
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,8 +389,8 @@ static void update_container(ug_ctx_t *ctx, ug_container_t *cnt)
}
}
if (cnt->flags & UG_CNT_RESIZABLE) {
// right border resize
if (cnt->flags & UG_CNT_RESIZE_RIGHT) {
minx = rca->x + rca->w - br;
maxx = rca->x + rca->w;
miny = rca->y;
@ -394,8 +399,25 @@ static void update_container(ug_ctx_t *ctx, ug_container_t *cnt)
rect->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
if (cnt->flags & UG_CNT_RESIZE_BOTTOM) {
minx = rca->x;
maxx = rca->x + rca->w;
miny = rca->y + rca->h - bb;
@ -406,6 +428,21 @@ static void update_container(ug_ctx_t *ctx, ug_container_t *cnt)
}
}
// 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;
}
}
// TODO: what if I want to close a floating container?
// Maybe add a UG_CNT_CLOSABLE flag?
@ -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 *
*=============================================================================*/

@ -40,9 +40,12 @@ 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_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);

Loading…
Cancel
Save