Add functionality to draw nodes with user-defined inputs count

This commit is contained in:
Abdelrahman Said 2024-02-24 23:53:04 +00:00
parent 30986e3c99
commit 2d31233a1e
4 changed files with 73 additions and 39 deletions

View File

@ -5,6 +5,8 @@
#include "ui.h" #include "ui.h"
#define MAX_NODES 1024 #define MAX_NODES 1024
#define IO_INPUT_COUNT 0
#define OP_INPUT_COUNT 2
typedef i32 (*node_func)(i32 a, i32 b); typedef i32 (*node_func)(i32 a, i32 b);
typedef enum node_type node_type; typedef enum node_type node_type;
@ -28,6 +30,7 @@ struct node {
ui_elem_colours colours; ui_elem_colours colours;
node_type type; node_type type;
node_data data; node_data data;
u64 inputs;
}; };
#endif // !NODES_H #endif // !NODES_H

View File

@ -39,8 +39,9 @@ struct ui_elem_colours {
typedef struct ui_node_elem ui_node_elem; typedef struct ui_node_elem ui_node_elem;
struct ui_node_elem { struct ui_node_elem {
line noodle;
rect rec; rect rec;
line *noodles;
u64 inputs;
}; };
struct ui_ctx { struct ui_ctx {

View File

@ -32,8 +32,8 @@ struct compositor {
ui_ctx ctx; ui_ctx ctx;
}; };
void add_node(compositor *comp, node_type type, node_data data, i32 x, i32 y, void add_node(compositor *comp, node_type type, node_data data, u64 inputs,
ui_elem_colours colours); i32 x, i32 y, ui_elem_colours colours);
i32 run_main_loop(void) { i32 run_main_loop(void) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
@ -124,8 +124,8 @@ i32 run_main_loop(void) {
if (comp.event.drop.windowID == main_window->id) { if (comp.event.drop.windowID == main_window->id) {
node_data data = (node_data){.path = comp.event.drop.file}; node_data data = (node_data){.path = comp.event.drop.file};
add_node(&comp, NODEYPE_IO, data, comp.ctx.mouse_x, comp.ctx.mouse_y, add_node(&comp, NODEYPE_IO, data, IO_INPUT_COUNT, comp.ctx.mouse_x,
io_node_colours); comp.ctx.mouse_y, io_node_colours);
break; break;
} }
@ -147,8 +147,8 @@ i32 run_main_loop(void) {
if (ui_button(toolbox, &(comp.ctx), rect, button_colours)) { if (ui_button(toolbox, &(comp.ctx), rect, button_colours)) {
node_data data = (node_data){.func = ops[i]}; node_data data = (node_data){.func = ops[i]};
add_node(&comp, NODEYPE_OP, data, comp.ctx.mouse_x, comp.ctx.mouse_y, add_node(&comp, NODEYPE_OP, data, OP_INPUT_COUNT, comp.ctx.mouse_x,
op_node_colours); comp.ctx.mouse_y, op_node_colours);
} }
} }
@ -175,15 +175,18 @@ i32 run_main_loop(void) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void add_node(compositor *comp, node_type type, node_data data, i32 x, i32 y, void add_node(compositor *comp, node_type type, node_data data, u64 inputs,
ui_elem_colours colours) { i32 x, i32 y, ui_elem_colours colours) {
if (comp->count + 1 >= MAX_NODES) { if (comp->count + 1 >= MAX_NODES) {
return; return;
} }
comp->nodes[(comp->count)++] = (node){ line *noodles = mem_arena_alloc(comp->arena, inputs * sizeof(line));
.node = if (!noodles) {
(ui_node_elem){ return;
}
ui_node_elem elem = {
.rec = .rec =
(rect){ (rect){
.topleft.x = x, .topleft.x = x,
@ -191,8 +194,12 @@ void add_node(compositor *comp, node_type type, node_data data, i32 x, i32 y,
.w = NODE_WIDTH, .w = NODE_WIDTH,
.h = NODE_HEIGHT, .h = NODE_HEIGHT,
}, },
.noodle = (line){0}, .inputs = inputs,
}, .noodles = noodles,
};
comp->nodes[(comp->count)++] = (node){
.node = elem,
.colours = colours, .colours = colours,
.type = type, .type = type,
.data.path = data.path, .data.path = data.path,

View File

@ -10,8 +10,8 @@
#define NOODLE_HALF_WIDTH 2 #define NOODLE_HALF_WIDTH 2
#define DEFAULT_NOODLE_LENGTH 60 #define DEFAULT_NOODLE_LENGTH 60
line ui_noodle(const window *wnd, ui_ctx *ctx, line ln, internal line ui_noodle(const window *wnd, ui_ctx *ctx, line ln,
ui_elem_colours colours); ui_elem_colours colours, rect node);
internal bool aabb(rect rec, i32 x, i32 y); internal bool aabb(rect rec, i32 x, i32 y);
internal line line_from_origin(point origin, f64 angle, i32 line_length); internal line line_from_origin(point origin, f64 angle, i32 line_length);
@ -103,17 +103,36 @@ ui_node_elem ui_node(const window *wnd, ui_ctx *ctx, ui_node_elem node,
u64 id = (ctx->count)++; u64 id = (ctx->count)++;
line ln; line ln = {0};
if (node.noodle.p0.x == node.noodle.p1.x && f64 angle = 90.0;
node.noodle.p0.y == node.noodle.p1.y) { f64 angle_delta = 25.0;
ln = line_from_origin((point){node.rec.topleft.x + node.rec.w / 2, i64 delta_multiplier = node.inputs % 2 == 0 ? -1 : 0;
node.rec.topleft.y + node.rec.h / 2},
90.0, DEFAULT_NOODLE_LENGTH); for (u64 i = 0; i < node.inputs; ++i) {
} else { if (node.noodles[i].p0.x == node.noodles[i].p1.x &&
ln = node.noodle; node.noodles[i].p0.y == node.noodles[i].p1.y) {
point origin = {node.rec.topleft.x + node.rec.w / 2,
node.rec.topleft.y + node.rec.h / 2};
f64 new_angle = angle + angle_delta * delta_multiplier;
ln = line_from_origin(origin, new_angle, DEFAULT_NOODLE_LENGTH);
if (delta_multiplier > 0) {
angle = new_angle;
} }
node.noodle = ui_noodle(wnd, ctx, ln, colours); if (delta_multiplier == 0) {
delta_multiplier = -1;
} else {
delta_multiplier *= -1;
}
} else {
ln = node.noodles[i];
}
node.noodles[i] = ui_noodle(wnd, ctx, ln, colours, node.rec);
}
fill_rect(wnd, node.rec, colours.fill); fill_rect(wnd, node.rec, colours.fill);
draw_rect(wnd, node.rec, colours.border); draw_rect(wnd, node.rec, colours.border);
@ -131,10 +150,13 @@ ui_node_elem ui_node(const window *wnd, ui_ctx *ctx, ui_node_elem node,
if (ctx->hovered == id && ctx->active == id) { if (ctx->hovered == id && ctx->active == id) {
node.rec.topleft.x += ctx->rel_x; node.rec.topleft.x += ctx->rel_x;
node.rec.topleft.y += ctx->rel_y; node.rec.topleft.y += ctx->rel_y;
node.noodle.p0.x += ctx->rel_x;
node.noodle.p0.y += ctx->rel_y; for (u64 i = 0; i < node.inputs; ++i) {
node.noodle.p1.x += ctx->rel_x; node.noodles[i].p0.x += ctx->rel_x;
node.noodle.p1.y += ctx->rel_y; node.noodles[i].p0.y += ctx->rel_y;
node.noodles[i].p1.x += ctx->rel_x;
node.noodles[i].p1.y += ctx->rel_y;
}
return node; return node;
} }
@ -152,8 +174,8 @@ ui_node_elem ui_node(const window *wnd, ui_ctx *ctx, ui_node_elem node,
return node; return node;
} }
line ui_noodle(const window *wnd, ui_ctx *ctx, line ln, internal line ui_noodle(const window *wnd, ui_ctx *ctx, line ln,
ui_elem_colours colours) { ui_elem_colours colours, rect node) {
if (ctx->count + 1 >= MAX_UI_ELEMENTS) { if (ctx->count + 1 >= MAX_UI_ELEMENTS) {
return (line){0}; return (line){0};
} }
@ -242,7 +264,8 @@ line ui_noodle(const window *wnd, ui_ctx *ctx, line ln,
return ln; return ln;
} }
if (!aabb(bounding_box, ctx->mouse_x, ctx->mouse_y)) { if (!aabb(bounding_box, ctx->mouse_x, ctx->mouse_y) ||
aabb(node, ctx->mouse_x, ctx->mouse_y)) {
return ln; return ln;
} }