diff --git a/include/ui.h b/include/ui.h index d36e67e..39b9437 100644 --- a/include/ui.h +++ b/include/ui.h @@ -16,6 +16,8 @@ #define NODE_WIDTH 70 #define NODE_HEIGHT 20 +#define DEFAULT_NOODLE_LENGTH 60 + typedef enum ui_elem_type ui_elem_type; typedef struct ui_elem ui_elem; typedef struct ui_ctx ui_ctx; @@ -43,19 +45,6 @@ struct ui_elem_colours { colour border; }; -typedef struct ui_noodle_elem ui_noodle_elem; -struct ui_noodle_elem { - line noodle; - u64 connected_node; -}; - -typedef struct ui_node_elem ui_node_elem; -struct ui_node_elem { - rect rec; - ui_noodle_elem *noodles; - u64 inputs; -}; - struct ui_ctx { u64 count; i64 hovered; @@ -75,7 +64,9 @@ void reset_ui_ctx(ui_ctx *ctx); void handle_ui_events(const window *wnd, ui_ctx *ctx, const SDL_Event *event); bool ui_button(const window *wnd, ui_ctx *ctx, rect rect, ui_elem_colours colours); -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); +bool ui_noodle(const window *wnd, ui_ctx *ctx, line ln, ui_elem_colours colours, + rect parent_node); #endif // !UI_H diff --git a/src/compositor.c b/src/compositor.c index c2cfa02..19b8338 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #define MAX_WINDOWS 2 @@ -153,8 +154,54 @@ i32 run_main_loop(void) { } for (u64 i = 0; i < comp.count; ++i) { - comp.nodes[i].node = ui_node(main_window, &(comp.ctx), comp.nodes[i].node, - comp.nodes[i].colours); + node *node_elem = &(comp.nodes[i]); + + f64 angle = 90.0; + f64 angle_delta = 25.0; + i64 delta_multiplier = node_elem->inputs % 2 == 0 ? -1 : 0; + + for (u64 j = 0; j < comp.nodes[i].inputs; ++j) { + f64 new_angle = angle + angle_delta * delta_multiplier; + line *ln = &(node_elem->noodles[j]); + + if (ln->p0.x == ln->p1.x && ln->p0.y == ln->p1.y) { + point origin = {node_elem->rec.topleft.x + node_elem->rec.w / 2, + node_elem->rec.topleft.y + node_elem->rec.h / 2}; + + *ln = line_from_origin(origin, new_angle, DEFAULT_NOODLE_LENGTH); + } + + if (ui_noodle(main_window, &(comp.ctx), *ln, node_elem->colours, + node_elem->rec)) { + ln->p0.x += comp.ctx.rel_x; + ln->p0.y += comp.ctx.rel_y; + } + + if (delta_multiplier > 0) { + angle = new_angle; + } + + if (delta_multiplier == 0) { + delta_multiplier = -1; + } else { + delta_multiplier *= -1; + } + } + + if (ui_node(main_window, &(comp.ctx), node_elem->rec, + node_elem->colours)) { + node_elem->rec.topleft.x += comp.ctx.rel_x; + node_elem->rec.topleft.y += comp.ctx.rel_y; + + for (u64 j = 0; j < comp.nodes[i].inputs; ++j) { + line *ln = &(node_elem->noodles[j]); + + ln->p0.x += comp.ctx.rel_x; + ln->p0.y += comp.ctx.rel_y; + ln->p1.x += comp.ctx.rel_x; + ln->p1.y += comp.ctx.rel_y; + } + } } for (u64 i = 0; i < MAX_WINDOWS; ++i) { @@ -181,28 +228,25 @@ void add_node(compositor *comp, node_type type, node_data data, u64 inputs, return; } - u64 alloc_size = inputs * sizeof(ui_noodle_elem); - ui_noodle_elem *noodles = mem_arena_alloc(comp->arena, alloc_size); + u64 alloc_size = inputs * sizeof(line); + line *noodles = mem_arena_alloc(comp->arena, alloc_size); if (!noodles) { return; } - ui_node_elem elem = { - .rec = - (rect){ - .topleft.x = x, - .topleft.y = y, - .w = NODE_WIDTH, - .h = NODE_HEIGHT, - }, - .inputs = inputs, - .noodles = noodles, + rect rec = (rect){ + .topleft.x = x, + .topleft.y = y, + .w = NODE_WIDTH, + .h = NODE_HEIGHT, }; comp->nodes[(comp->count)++] = (node){ - .node = elem, + .rec = rec, .colours = colours, .type = type, .data.path = data.path, + .inputs = inputs, + .noodles = noodles, }; } diff --git a/src/ui.c b/src/ui.c index 1493273..8bd72d2 100644 --- a/src/ui.c +++ b/src/ui.c @@ -8,14 +8,8 @@ #include #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; }