mostly correct resizing

master
Alessandro Mauri 2 years ago
parent c930520cbd
commit 05b6f9eae8
  1. 7
      test/main.c
  2. 103
      ugui.c
  3. 8
      ugui.h

@ -175,11 +175,14 @@ int main(void)
ug_frame_begin(ctx); ug_frame_begin(ctx);
ug_ctx_set_unit(ctx, UG_UNIT_MM);
ug_container_floating(ctx, "stupid name", ug_container_floating(ctx, "stupid name",
(ug_div_t){.x=SIZE_PX(0), .y=SIZE_PX(0), .w=SIZE_PX(100), .h=SIZE_MM(75.0)}); (ug_div_t){.x=SIZE_PX(0), .y=SIZE_PX(0), .w=SIZE_PX(100), .h=SIZE_MM(75.0)});
ug_container_sidebar(ctx, "Sidebar", (ug_size_t)SIZE_PX(300), UG_SIDE_RIGHT); ug_container_floating(ctx, "stupid er",
(ug_div_t){.x=SIZE_PX(150), .y=SIZE_PX(-100), .w=SIZE_PX(100), .h=SIZE_MM(75.0)});
ug_container_sidebar(ctx, "Right Sidebar", (ug_size_t)SIZE_PX(300), UG_SIDE_RIGHT);
ug_container_sidebar(ctx, "Bottom Sidebar", (ug_size_t)SIZE_MM(10), UG_SIDE_BOTTOM);
ug_frame_end(ctx); ug_frame_end(ctx);
// fill background // fill background

103
ugui.c

@ -17,6 +17,7 @@
UG_CNT_RESIZE_BOTTOM | \ UG_CNT_RESIZE_BOTTOM | \
UG_CNT_RESIZE_LEFT | \ UG_CNT_RESIZE_LEFT | \
UG_CNT_RESIZE_TOP UG_CNT_RESIZE_TOP
#define BTN_ANY UG_BTN_LEFT | UG_BTN_RIGHT | UG_BTN_MIDDLE | UG_BTN_4 | UG_BTN_5
#define PPI_PPM(ppi, scale) (ppi * scale * 0.03937008) #define PPI_PPM(ppi, scale) (ppi * scale * 0.03937008)
#define PPI_PPD(ppi, scale) (PPI_PPM(ppi, scale) * 0.3528) #define PPI_PPD(ppi, scale) (PPI_PPM(ppi, scale) * 0.3528)
@ -24,7 +25,8 @@
#define UG_ERR(...) err(errno, "__FUNCTION__: " __VA_ARGS__) #define UG_ERR(...) err(errno, "__FUNCTION__: " __VA_ARGS__)
#define BETWEEN(x, min, max) (x <= max && x >= min) #define BETWEEN(x, min, max) (x <= max && x >= min)
#define INTERSECTS(v, r) (BETWEEN(v.x, r.x, r.x+r.w) && BETWEEN(v.y, r.y, r.y+r.h)) #define INTERSECTS(v, r) (BETWEEN(v.x, r.x, r.x+r.w) && BETWEEN(v.y, r.y, r.y+r.h))
#define CAP(x, s) { if (x < s) x = s; } #define TEST(f, b) (f & b)
#define MAX(a, b) (a > b ? a : b)
// default style // default style
@ -40,7 +42,7 @@ static const ug_style_t default_style = {
.bg_color = RGB_FORMAT(0x0000ff), .bg_color = RGB_FORMAT(0x0000ff),
.border.t = SIZE_PX(3), .border.t = SIZE_PX(3),
.border.b = SIZE_PX(3), .border.b = SIZE_PX(3),
.border.l = SIZE_PX(3), .border.l = SIZE_PX(10),
.border.r = SIZE_PX(3), .border.r = SIZE_PX(3),
.border.color = RGB_FORMAT(0x00ff00), .border.color = RGB_FORMAT(0x00ff00),
.titlebar.height = SIZE_PX(20), .titlebar.height = SIZE_PX(20),
@ -166,7 +168,6 @@ ug_ctx_t *ug_ctx_new(void)
err(errno, "__FUNCTION__:" "Could not allocate context: %s", strerror(errno)); err(errno, "__FUNCTION__:" "Could not allocate context: %s", strerror(errno));
memset(ctx, 0, sizeof(ug_ctx_t)); memset(ctx, 0, sizeof(ug_ctx_t));
ctx->unit = UG_UNIT_PX;
ctx->style = &default_style; ctx->style = &default_style;
ctx->style_px = &style_cache; ctx->style_px = &style_cache;
ug_ctx_set_displayinfo(ctx, DEF_SCALE, DEF_PPI); ug_ctx_set_displayinfo(ctx, DEF_SCALE, DEF_PPI);
@ -245,18 +246,6 @@ int ug_ctx_set_style(ug_ctx_t *ctx, const ug_style_t *style)
} }
int ug_ctx_set_unit(ug_ctx_t *ctx, ug_unit_t unit)
{
TEST_CTX(ctx);
if (!IS_VALID_UNIT(unit))
return -1;
ctx->unit = unit;
return 0;
}
/*=============================================================================* /*=============================================================================*
* Container Operations * * Container Operations *
*=============================================================================*/ *=============================================================================*/
@ -338,35 +327,34 @@ static void position_container(ug_ctx_t *ctx, ug_container_t *cnt)
int cw = ctx->size.w; int cw = ctx->size.w;
int ch = ctx->size.h; int ch = ctx->size.h;
// 0 -> take all the space, <0 -> take absolute // handle relative sizes
if (rect->w < 0) rca->w = -rect->w;
if (rect->h < 0) rca->h = -rect->h;
// handle relative position
// and move to fit borders
if (rect->w == 0) rca->w = cw; if (rect->w == 0) rca->w = cw;
else rca->w += bl + br; else rca->w += bl + br;
if (rect->h == 0) rca->h = ch; if (rect->h == 0) rca->h = ch;
else if (cnt->flags & UG_CNT_MOVABLE) rca->h += hh + 2*bt + bb; else if (TEST(cnt->flags, UG_CNT_MOVABLE)) rca->h += hh + 2*bt + bb;
else rca->h += bt + bb; else rca->h += bt + bb;
// if the container is not fixed than it can have positions outside of the
// main window, thus negative
if (!TEST(cnt->flags, UG_CNT_MOVABLE)) {
// <0 -> relative to the right margin // <0 -> relative to the right margin
if (rect->x < 0) rca->x = cw - rca->w + rca->x; if (rect->x <= 0) rca->x = cw - rca->w + rca->x;
if (rect->y < 0) rca->y = ch - rca->h + rca->y; if (rect->y <= 0) rca->y = ch - rca->h + rca->y;
}
} }
void handle_container(ug_ctx_t *ctx, ug_container_t *cnt) void handle_container(ug_ctx_t *ctx, ug_container_t *cnt)
{ {
// if we had focus the frame before, then do shit // if we had focus the frame before, then do shit
if (ctx->hover.cnt_last != cnt->id) if (ctx->active.cnt != cnt->id)
return; return;
// mouse pressed handle resize, for simplicity containers can only // mouse pressed handle resize, for simplicity containers can only
// be resized from the bottom and right border // be resized from the bottom and right border
// TODO: bring selected container to the top of the stack // TODO: bring selected container to the top of the stack
if (!(ctx->mouse.down_mask & UG_BTN_LEFT) || if (!TEST(ctx->mouse.down_mask, UG_BTN_LEFT) ||
!(cnt->flags & (RESIZEALL | UG_CNT_MOVABLE))) !TEST(cnt->flags, (RESIZEALL | UG_CNT_MOVABLE)))
return; return;
ug_rect_t *rect, *rca; ug_rect_t *rect, *rca;
@ -379,25 +367,17 @@ void handle_container(ug_ctx_t *ctx, ug_container_t *cnt)
int bt = s->cnt.border.t.size.i; int bt = s->cnt.border.t.size.i;
int bb = s->cnt.border.b.size.i; int bb = s->cnt.border.b.size.i;
int hh = s->cnt.titlebar.height.size.i; int hh = s->cnt.titlebar.height.size.i;
int cw = ctx->size.w;
int ch = ctx->size.h;
ug_vec2_t mpos = ctx->mouse.pos; ug_vec2_t mpos = ctx->mouse.pos;
int minx, maxx, miny, maxy; int minx, maxx, miny, maxy;
// handle movable windows // handle movable windows
if (cnt->flags & UG_CNT_MOVABLE) { if (TEST(cnt->flags, UG_CNT_MOVABLE)) {
minx = rca->x + bl; minx = rca->x + bl;
maxx = rca->x + rca->w - br; maxx = rca->x + rca->w - br;
miny = rca->y + bt; miny = rca->y + bt;
maxy = rca->y + bt + hh; maxy = rca->y + bt + hh;
if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) {
// if a relative container has been moved consider it no
// longer relative
if (rect->x < 0)
rect->x = cw + rect->x - rect->w - bl - br;
if (rect->y < 0)
rect->y = ch + rect->y - rect->h - 2*bt - bb - hh;
rect->x += ctx->mouse.delta.x; rect->x += ctx->mouse.delta.x;
rect->y += ctx->mouse.delta.y; rect->y += ctx->mouse.delta.y;
rca->x += ctx->mouse.delta.x; rca->x += ctx->mouse.delta.x;
@ -406,34 +386,38 @@ void handle_container(ug_ctx_t *ctx, ug_container_t *cnt)
} }
// right border resize // right border resize
if (cnt->flags & UG_CNT_RESIZE_RIGHT) { if (TEST(cnt->flags, UG_CNT_RESIZE_RIGHT)) {
minx = rca->x + rca->w - br; minx = rca->x + rca->w - br;
maxx = rca->x + rca->w; maxx = rca->x + rca->w;
miny = rca->y; miny = rca->y;
maxy = rca->y + rca->h; maxy = rca->y + rca->h;
if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) {
rect->w += ctx->mouse.delta.x; rect->w = MAX(10, rect->w + ctx->mouse.delta.x);
rca->w += ctx->mouse.delta.x; rca->w = MAX(10, rca->w + ctx->mouse.delta.x);
} }
} }
// left border resize // left border resize
if (cnt->flags & UG_CNT_RESIZE_LEFT) { if (TEST(cnt->flags, UG_CNT_RESIZE_LEFT)) {
minx = rca->x - bl; minx = rca->x;
maxx = rca->x; maxx = rca->x + bl;
miny = rca->y; miny = rca->y;
maxy = rca->y + rca->h; maxy = rca->y + rca->h;
if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) {
if (rect->w - ctx->mouse.delta.x >= 10) {
rect->w -= ctx->mouse.delta.x; rect->w -= ctx->mouse.delta.x;
rca->w -= ctx->mouse.delta.x; if (TEST(cnt->flags, UG_CNT_MOVABLE))
rect->x += ctx->mouse.delta.x; rect->x += ctx->mouse.delta.x;
}
if (rca->w - ctx->mouse.delta.x >= 10) {
rca->w -= ctx->mouse.delta.x;
rca->x += ctx->mouse.delta.x; rca->x += ctx->mouse.delta.x;
} }
} }
}
// bottom border resize // bottom border resize
if (cnt->flags & UG_CNT_RESIZE_BOTTOM) { if (TEST(cnt->flags, UG_CNT_RESIZE_BOTTOM)) {
minx = rca->x; minx = rca->x;
maxx = rca->x + rca->w; maxx = rca->x + rca->w;
miny = rca->y + rca->h - bb; miny = rca->y + rca->h - bb;
@ -445,19 +429,23 @@ void handle_container(ug_ctx_t *ctx, ug_container_t *cnt)
} }
// top border resize // top border resize
if (cnt->flags & UG_CNT_RESIZE_TOP) { if (TEST(cnt->flags, UG_CNT_RESIZE_TOP)) {
minx = rca->x; minx = rca->x;
maxx = rca->x + rca->w; maxx = rca->x + rca->w;
miny = rca->y - bt; miny = rca->y;
maxy = rca->y; maxy = rca->y + bt;
if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) { if (BETWEEN(mpos.x, minx, maxx) && BETWEEN(mpos.y, miny, maxy)) {
if (rect->h - ctx->mouse.delta.y >= 10) {
rect->h -= ctx->mouse.delta.y; rect->h -= ctx->mouse.delta.y;
rca->h -= ctx->mouse.delta.y; if (TEST(cnt->flags, UG_CNT_MOVABLE))
rect->y += ctx->mouse.delta.y; rect->y += ctx->mouse.delta.y;
}
if (rca->h - ctx->mouse.delta.y >= 10) {
rca->h -= ctx->mouse.delta.y;
rca->y += ctx->mouse.delta.y; rca->y += ctx->mouse.delta.y;
} }
} }
}
// TODO: what if I want to close a floating container? // TODO: what if I want to close a floating container?
// Maybe add a UG_CNT_CLOSABLE flag? // Maybe add a UG_CNT_CLOSABLE flag?
@ -562,7 +550,7 @@ int ug_container_sidebar(ug_ctx_t *ctx, const char *name, ug_size_t size, int si
case UG_SIDE_BOTTOM: case UG_SIDE_BOTTOM:
cnt->flags |= UG_CNT_RESIZE_TOP; cnt->flags |= UG_CNT_RESIZE_TOP;
// FIXME: we do not support relative zero position yet // FIXME: we do not support relative zero position yet
rect.y = -1; rect.y = 0;
rect.h = size_to_px(ctx, size); rect.h = size_to_px(ctx, size);
break; break;
case UG_SIDE_TOP: case UG_SIDE_TOP:
@ -571,7 +559,7 @@ int ug_container_sidebar(ug_ctx_t *ctx, const char *name, ug_size_t size, int si
break; break;
case UG_SIDE_RIGHT: case UG_SIDE_RIGHT:
cnt->flags |= UG_CNT_RESIZE_LEFT; cnt->flags |= UG_CNT_RESIZE_LEFT;
rect.x = -1; rect.x = 0;
rect.w = size_to_px(ctx, size); rect.w = size_to_px(ctx, size);
break; break;
case UG_SIDE_LEFT: case UG_SIDE_LEFT:
@ -655,15 +643,20 @@ int ug_frame_begin(ug_ctx_t *ctx)
// update hover index // update hover index
ug_vec2_t v = ctx->mouse.pos; ug_vec2_t v = ctx->mouse.pos;
// printf("mouse: x=%d, y=%d\n", ctx->mouse.pos.x, ctx->mouse.pos.x);
for (int i = 0; i < ctx->cnt_stack.idx; i++) { for (int i = 0; i < ctx->cnt_stack.idx; i++) {
ug_rect_t r = ctx->cnt_stack.items[i].rca; ug_rect_t r = ctx->cnt_stack.items[i].rca;
if (INTERSECTS(v, r)) { if (INTERSECTS(v, r)) {
ctx->hover.cnt = ctx->cnt_stack.items[i].id; ctx->hover.cnt = ctx->cnt_stack.items[i].id;
// printf("intersects! %.8x\n", ctx->hover.cnt);
} }
} }
// update active container
if (MOUSEDOWN(ctx, UG_BTN_LEFT)) {
ctx->active.cnt = ctx->hover.cnt;
} else if (MOUSEUP(ctx, UG_BTN_LEFT)) {
ctx->active.cnt = 0;
}
return 0; return 0;
} }

@ -150,14 +150,15 @@ typedef struct {
ug_id_t cnt, elem; ug_id_t cnt, elem;
ug_id_t cnt_last, elem_last; ug_id_t cnt_last, elem_last;
} hover; } hover;
// active is updated on mousedown and released on mouseup
// the id of the "active" element, active means different things for // the id of the "active" element, active means different things for
// different elements, for exaple active for a button means to be pressed, // different elements, for exaple active for a button means to be pressed,
// and for a text box it means to be focused // and for a text box it means to be focused
ug_id_t active; struct {
ug_id_t cnt, elem;
} active;
// count the frames for fun // count the frames for fun
unsigned long int frame; unsigned long int frame;
// current measurement unit
ug_unit_t unit;
// mouse data // mouse data
struct { struct {
ug_vec2_t pos; ug_vec2_t pos;
@ -191,7 +192,6 @@ void ug_ctx_free(ug_ctx_t *ctx);
int ug_ctx_set_displayinfo(ug_ctx_t *ctx, float scale, float ppi); int ug_ctx_set_displayinfo(ug_ctx_t *ctx, float scale, float ppi);
int ug_ctx_set_drawableregion(ug_ctx_t *ctx, ug_vec2_t size); int ug_ctx_set_drawableregion(ug_ctx_t *ctx, ug_vec2_t size);
int ug_ctx_set_style(ug_ctx_t *ctx, const ug_style_t *style); int ug_ctx_set_style(ug_ctx_t *ctx, const ug_style_t *style);
int ug_ctx_set_unit(ug_ctx_t *ctx, ug_unit_t unit);
// define containers, name is used as a salt for the container id, all sizes are // define containers, name is used as a salt for the container id, all sizes are

Loading…
Cancel
Save