Simplify the immediate mode functions and move node
connection logic to the application level
This commit is contained in:
162
src/ui.c
162
src/ui.c
@@ -8,14 +8,8 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NOODLE_HALF_WIDTH 2
|
||||
#define DEFAULT_NOODLE_LENGTH 60
|
||||
|
||||
internal u64 get_id(ui_ctx *ctx);
|
||||
internal ui_noodle_elem ui_noodle(const window *wnd, ui_ctx *ctx,
|
||||
ui_noodle_elem noodle,
|
||||
ui_elem_colours colours, u64 parent_id);
|
||||
internal bool aabb(rect rec, i32 x, i32 y);
|
||||
internal line line_from_origin(point origin, f64 angle, i32 line_length);
|
||||
|
||||
void init_ui_ctx(ui_ctx *ctx) {
|
||||
*ctx = (ui_ctx){0};
|
||||
@@ -102,55 +96,24 @@ bool ui_button(const window *wnd, ui_ctx *ctx, rect rec,
|
||||
return false;
|
||||
}
|
||||
|
||||
ui_node_elem ui_node(const window *wnd, ui_ctx *ctx, ui_node_elem node,
|
||||
ui_elem_colours colours) {
|
||||
bool ui_node(const window *wnd, ui_ctx *ctx, rect rect,
|
||||
ui_elem_colours colours) {
|
||||
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
||||
return (ui_node_elem){0};
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 id = get_id(ctx);
|
||||
ctx->elements[id] = (ui_elem){
|
||||
.id = id,
|
||||
.rec = node.rec,
|
||||
.rec = rect,
|
||||
.type = UI_ELEM_NODE,
|
||||
};
|
||||
|
||||
f64 angle = 90.0;
|
||||
f64 angle_delta = 25.0;
|
||||
i64 delta_multiplier = node.inputs % 2 == 0 ? -1 : 0;
|
||||
|
||||
for (u64 i = 0; i < node.inputs; ++i) {
|
||||
f64 new_angle = angle + angle_delta * delta_multiplier;
|
||||
|
||||
if (node.noodles[i].noodle.p0.x == node.noodles[i].noodle.p1.x &&
|
||||
node.noodles[i].noodle.p0.y == node.noodles[i].noodle.p1.y) {
|
||||
point origin = {node.rec.topleft.x + node.rec.w / 2,
|
||||
node.rec.topleft.y + node.rec.h / 2};
|
||||
|
||||
node.noodles[i].noodle =
|
||||
line_from_origin(origin, new_angle, DEFAULT_NOODLE_LENGTH);
|
||||
} else {
|
||||
node.noodles[i].noodle = node.noodles[i].noodle;
|
||||
}
|
||||
|
||||
node.noodles[i] = ui_noodle(wnd, ctx, node.noodles[i], colours, id);
|
||||
|
||||
if (delta_multiplier > 0) {
|
||||
angle = new_angle;
|
||||
}
|
||||
|
||||
if (delta_multiplier == 0) {
|
||||
delta_multiplier = -1;
|
||||
} else {
|
||||
delta_multiplier *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
fill_rect(wnd, node.rec, colours.fill);
|
||||
draw_rect(wnd, node.rec, colours.border);
|
||||
fill_rect(wnd, rect, colours.fill);
|
||||
draw_rect(wnd, rect, colours.border);
|
||||
|
||||
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != id)) {
|
||||
return node;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx->mouse_up) {
|
||||
@@ -158,28 +121,15 @@ ui_node_elem ui_node(const window *wnd, ui_ctx *ctx, ui_node_elem node,
|
||||
ctx->hovered = ctx->active = -1;
|
||||
}
|
||||
|
||||
return node;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx->hovered == id && ctx->active == id) {
|
||||
node.rec.topleft.x += ctx->rel_x;
|
||||
node.rec.topleft.y += ctx->rel_y;
|
||||
|
||||
for (u64 i = 0; i < node.inputs; ++i) {
|
||||
if (node.noodles[i].connected_node == RESERVED_UI_SLOT) {
|
||||
node.noodles[i].noodle.p0.x += ctx->rel_x;
|
||||
node.noodles[i].noodle.p0.y += ctx->rel_y;
|
||||
}
|
||||
|
||||
node.noodles[i].noodle.p1.x += ctx->rel_x;
|
||||
node.noodles[i].noodle.p1.y += ctx->rel_y;
|
||||
}
|
||||
|
||||
return node;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!aabb(node.rec, ctx->mouse_x, ctx->mouse_y)) {
|
||||
return node;
|
||||
if (!aabb(rect, ctx->mouse_x, ctx->mouse_y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx->hovered = id;
|
||||
@@ -188,7 +138,7 @@ ui_node_elem ui_node(const window *wnd, ui_ctx *ctx, ui_node_elem node,
|
||||
ctx->active = id;
|
||||
}
|
||||
|
||||
return node;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal u64 get_id(ui_ctx *ctx) {
|
||||
@@ -196,47 +146,42 @@ internal u64 get_id(ui_ctx *ctx) {
|
||||
return ++(ctx->count);
|
||||
}
|
||||
|
||||
internal ui_noodle_elem ui_noodle(const window *wnd, ui_ctx *ctx,
|
||||
ui_noodle_elem noodle,
|
||||
ui_elem_colours colours, u64 parent_id) {
|
||||
bool ui_noodle(const window *wnd, ui_ctx *ctx, line ln, ui_elem_colours colours,
|
||||
rect parent_node) {
|
||||
if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
|
||||
return (ui_noodle_elem){0};
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 id = get_id(ctx);
|
||||
ctx->elements[id] = (ui_elem){
|
||||
.id = id,
|
||||
.ln = noodle.noodle,
|
||||
.ln = ln,
|
||||
.type = UI_ELEM_NOODLE,
|
||||
};
|
||||
|
||||
bool horizontal = noodle.noodle.p0.y == noodle.noodle.p1.y;
|
||||
bool horizontal = ln.p0.y == ln.p1.y;
|
||||
|
||||
rect bounding_box = (rect){0};
|
||||
|
||||
if (horizontal) {
|
||||
i32 x = min(noodle.noodle.p0.x, noodle.noodle.p1.x);
|
||||
i32 x = min(ln.p0.x, ln.p1.x);
|
||||
|
||||
bounding_box.topleft = (point){x, noodle.noodle.p0.y - NOODLE_HALF_WIDTH};
|
||||
bounding_box.w = abs(noodle.noodle.p1.x - noodle.noodle.p0.x);
|
||||
bounding_box.topleft = (point){x, ln.p0.y - NOODLE_HALF_WIDTH};
|
||||
bounding_box.w = abs(ln.p1.x - ln.p0.x);
|
||||
bounding_box.h = NOODLE_HALF_WIDTH * 2;
|
||||
|
||||
fill_rect(wnd, bounding_box, colours.fill);
|
||||
} else {
|
||||
vec2 direction = line_direction(&noodle.noodle);
|
||||
vec2 direction = line_direction(&ln);
|
||||
|
||||
quad qd = (quad){0};
|
||||
|
||||
if (direction.x == 0) {
|
||||
qd = (quad){
|
||||
.p0 = (point){noodle.noodle.p0.x - NOODLE_HALF_WIDTH,
|
||||
noodle.noodle.p0.y},
|
||||
.p1 = (point){noodle.noodle.p0.x + NOODLE_HALF_WIDTH,
|
||||
noodle.noodle.p0.y},
|
||||
.p2 = (point){noodle.noodle.p1.x - NOODLE_HALF_WIDTH,
|
||||
noodle.noodle.p1.y},
|
||||
.p3 = (point){noodle.noodle.p1.x + NOODLE_HALF_WIDTH,
|
||||
noodle.noodle.p1.y},
|
||||
.p0 = (point){ln.p0.x - NOODLE_HALF_WIDTH, ln.p0.y},
|
||||
.p1 = (point){ln.p0.x + NOODLE_HALF_WIDTH, ln.p0.y},
|
||||
.p2 = (point){ln.p1.x - NOODLE_HALF_WIDTH, ln.p1.y},
|
||||
.p3 = (point){ln.p1.x + NOODLE_HALF_WIDTH, ln.p1.y},
|
||||
};
|
||||
} else {
|
||||
f32 slope = (f32)(direction.y) / direction.x;
|
||||
@@ -246,14 +191,10 @@ internal ui_noodle_elem ui_noodle(const window *wnd, ui_ctx *ctx,
|
||||
f32 perpendicular_dx = -1.0f * slope * perpendicular_dy;
|
||||
|
||||
qd = (quad){
|
||||
.p0 = (point){noodle.noodle.p0.x - perpendicular_dx,
|
||||
noodle.noodle.p0.y - perpendicular_dy},
|
||||
.p1 = (point){noodle.noodle.p0.x + perpendicular_dx,
|
||||
noodle.noodle.p0.y + perpendicular_dy},
|
||||
.p2 = (point){noodle.noodle.p1.x - perpendicular_dx,
|
||||
noodle.noodle.p1.y - perpendicular_dy},
|
||||
.p3 = (point){noodle.noodle.p1.x + perpendicular_dx,
|
||||
noodle.noodle.p1.y + perpendicular_dy},
|
||||
.p0 = (point){ln.p0.x - perpendicular_dx, ln.p0.y - perpendicular_dy},
|
||||
.p1 = (point){ln.p0.x + perpendicular_dx, ln.p0.y + perpendicular_dy},
|
||||
.p2 = (point){ln.p1.x - perpendicular_dx, ln.p1.y - perpendicular_dy},
|
||||
.p3 = (point){ln.p1.x + perpendicular_dx, ln.p1.y + perpendicular_dy},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -284,7 +225,7 @@ internal ui_noodle_elem ui_noodle(const window *wnd, ui_ctx *ctx,
|
||||
}
|
||||
|
||||
if (wnd != ctx->wnd || (ctx->active >= 0 && ctx->active != id)) {
|
||||
return noodle;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctx->mouse_up) {
|
||||
@@ -292,31 +233,16 @@ internal ui_noodle_elem ui_noodle(const window *wnd, ui_ctx *ctx,
|
||||
ctx->hovered = ctx->active = -1;
|
||||
}
|
||||
|
||||
if (noodle.connected_node > RESERVED_UI_SLOT) {
|
||||
return noodle;
|
||||
}
|
||||
|
||||
line updated_noodle = (line){
|
||||
.p0 = noodle.noodle.p1,
|
||||
.p1 = noodle.noodle.p1,
|
||||
};
|
||||
return (ui_noodle_elem){
|
||||
.noodle = updated_noodle,
|
||||
.connected_node = noodle.connected_node,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ctx->hovered == id && ctx->active == id) {
|
||||
noodle.noodle.p0.x += ctx->rel_x;
|
||||
noodle.noodle.p0.y += ctx->rel_y;
|
||||
|
||||
return noodle;
|
||||
return true;
|
||||
}
|
||||
|
||||
const rect *node = &(ctx->elements[parent_id].rec);
|
||||
if (!aabb(bounding_box, ctx->mouse_x, ctx->mouse_y) ||
|
||||
aabb(*node, ctx->mouse_x, ctx->mouse_y)) {
|
||||
return noodle;
|
||||
aabb(parent_node, ctx->mouse_x, ctx->mouse_y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ctx->hovered = id;
|
||||
@@ -325,23 +251,5 @@ internal ui_noodle_elem ui_noodle(const window *wnd, ui_ctx *ctx,
|
||||
ctx->active = id;
|
||||
}
|
||||
|
||||
return noodle;
|
||||
}
|
||||
|
||||
internal bool aabb(rect rec, i32 x, i32 y) {
|
||||
return x > rec.topleft.x && x <= rec.topleft.x + rec.w && y > rec.topleft.y &&
|
||||
y <= rec.topleft.y + rec.h;
|
||||
}
|
||||
|
||||
internal line line_from_origin(point origin, f64 angle, i32 line_length) {
|
||||
f64 rad = radians(angle);
|
||||
f64 direction = angle / absolute(angle) * -1;
|
||||
|
||||
i32 adjacent = line_length * cos(rad) * direction; // dx
|
||||
i32 opposite = line_length * sin(rad) * direction; // dy
|
||||
|
||||
return (line){
|
||||
(point){origin.x + adjacent, origin.y + opposite},
|
||||
origin,
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user