From 608982952cd4a4c102ba816753011e0809aac40c Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Fri, 31 Mar 2023 11:05:24 +0300 Subject: [PATCH 01/28] Renamed some things + added comments --- demo/common/node_editor.c | 59 ++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index d4f34c3bb..6c6033232 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -14,12 +14,12 @@ struct node { int ID; char name[32]; struct nk_rect bounds; - float value; + float value; /* unused */ struct nk_color color; int input_count; int output_count; - struct node *next; - struct node *prev; + struct node *next; /* Z ordering only */ + struct node *prev; /* Z ordering only */ }; struct node_link { @@ -27,8 +27,8 @@ struct node_link { int input_slot; int output_id; int output_slot; - struct nk_vec2 in; - struct nk_vec2 out; + /* struct nk_vec2 in; + struct nk_vec2 out; */ }; struct node_linking { @@ -102,12 +102,12 @@ static void node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, struct nk_color col, int in_count, int out_count) { - static int IDs = 0; + static int IDs = 0; /* static duration */ struct node *node; NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); - node = &editor->node_buf[editor->node_count++]; - node->ID = IDs++; - node->value = 0; + node = &editor->node_buf[editor->node_count++]; /* next node in buffer */ + node->ID = IDs++; /* increment IDs and set as node ID */ + node->value = 0; /* unused? */ node->color = nk_rgb(255, 0, 0); node->input_count = in_count; node->output_count = out_count; @@ -145,7 +145,7 @@ node_editor_init(struct node_editor *editor) } static int -node_editor(struct nk_context *ctx) +node_editor_main(struct nk_context *ctx) { int n = 0; struct nk_rect total_space; @@ -169,7 +169,7 @@ node_editor(struct nk_context *ctx) { struct node *it = nodedit->begin; struct nk_rect size = nk_layout_space_bounds(ctx); - struct nk_panel *node = 0; + struct nk_panel *nodePanel = 0; if (nodedit->show_grid) { /* display grid */ @@ -183,6 +183,7 @@ node_editor(struct nk_context *ctx) } /* execute each node as a movable group */ + /* (loop through nodes) */ while (it) { /* calculate scrolled node window position and size */ nk_layout_space_push(ctx, nk_rect(it->bounds.x - nodedit->scrolling.x, @@ -193,10 +194,10 @@ node_editor(struct nk_context *ctx) { /* always have last selected node on top */ - node = nk_window_get_panel(ctx); - if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, node->bounds) && + nodePanel = nk_window_get_panel(ctx); + if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nodePanel->bounds) && (!(it->prev && nk_input_mouse_clicked(in, NK_BUTTON_LEFT, - nk_layout_space_rect_to_screen(ctx, node->bounds)))) && + nk_layout_space_rect_to_screen(ctx, nodePanel->bounds)))) && nodedit->end != it) { updated = it; @@ -214,31 +215,35 @@ node_editor(struct nk_context *ctx) } { /* node connector and linking */ - float space; + float space; /* space between output circles */ struct nk_rect bounds; - bounds = nk_layout_space_rect_to_local(ctx, node->bounds); + bounds = nk_layout_space_rect_to_local(ctx, nodePanel->bounds); bounds.x += nodedit->scrolling.x; bounds.y += nodedit->scrolling.y; it->bounds = bounds; /* output connector */ - space = node->bounds.h / (float)((it->output_count) + 1); + space = nodePanel->bounds.h / (float)((it->output_count) + 1); + + /* (loop through outputs) */ for (n = 0; n < it->output_count; ++n) { struct nk_rect circle; - circle.x = node->bounds.x + node->bounds.w-4; - circle.y = node->bounds.y + space * (float)(n+1); + circle.x = nodePanel->bounds.x + nodePanel->bounds.w-4; + circle.y = nodePanel->bounds.y + space * (float)(n+1); circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); /* start linking process */ + /* (set linking active) */ if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true)) { - nodedit->linking.active = nk_true; + nodedit->linking.active = nk_true; nodedit->linking.node = it; nodedit->linking.input_id = it->ID; nodedit->linking.input_slot = n; } /* draw curve from linked node slot to mouse position */ + /* (if linking active) */ if (nodedit->linking.active && nodedit->linking.node == it && nodedit->linking.input_slot == n) { struct nk_vec2 l0 = nk_vec2(circle.x + 3, circle.y + 3); @@ -249,17 +254,19 @@ node_editor(struct nk_context *ctx) } /* input connector */ - space = node->bounds.h / (float)((it->input_count) + 1); + space = nodePanel->bounds.h / (float)((it->input_count) + 1); for (n = 0; n < it->input_count; ++n) { struct nk_rect circle; - circle.x = node->bounds.x-4; - circle.y = node->bounds.y + space * (float)(n+1); + circle.x = nodePanel->bounds.x-4; + circle.y = nodePanel->bounds.y + space * (float)(n+1); circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); + + /* (Create link) */ if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && nodedit->linking.active && nodedit->linking.node != it) { - nodedit->linking.active = nk_false; + nodedit->linking.active = nk_false; node_editor_link(nodedit, nodedit->linking.input_id, nodedit->linking.input_slot, it->ID, n); } @@ -280,8 +287,8 @@ node_editor(struct nk_context *ctx) struct node_link *link = &nodedit->links[n]; struct node *ni = node_editor_find(nodedit, link->input_id); struct node *no = node_editor_find(nodedit, link->output_id); - float spacei = node->bounds.h / (float)((ni->output_count) + 1); - float spaceo = node->bounds.h / (float)((no->input_count) + 1); + float spacei = nodePanel->bounds.h / (float)((ni->output_count) + 1); + float spaceo = nodePanel->bounds.h / (float)((no->input_count) + 1); struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + spacei * (float)(link->input_slot+1))); struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, From 5abe124c5c207aaab43cc97ba01db2a0fbefa476 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Fri, 31 Mar 2023 11:12:56 +0300 Subject: [PATCH 02/28] Added node_connector struct --- demo/common/node_editor.c | 24 +++++++++++++++++++++++- demo/glfw_opengl3/main.c | 13 +++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 6c6033232..e23a16cbb 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -10,6 +10,15 @@ * In addition adding and removing nodes is quite limited at the * moment since it is based on a simple fixed array. If this is to be converted * into something more serious it is probably best to extend it.*/ + + +enum node_connector_type {fValue, fColor}; + +struct node_connector { + enum node_connector_type type; + nk_bool isConnected; +}; + struct node { int ID; char name[32]; @@ -18,8 +27,13 @@ struct node { struct nk_color color; int input_count; int output_count; + struct node_connector *inputs; /* These could be made into arrays to get rid of the allocation at node creation. */ + struct node_connector *outputs; /* For this demo we probably only need a max of four inputs and one output. */ struct node *next; /* Z ordering only */ struct node *prev; /* Z ordering only */ + + void* (*evalFunc)(struct node*, int oIndex); + void (*displayFunc)(struct node*, struct nk_context *ctx); }; struct node_link { @@ -111,6 +125,10 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou node->color = nk_rgb(255, 0, 0); node->input_count = in_count; node->output_count = out_count; + + node->inputs = (node_connector*)malloc(node->input_count * sizeof(node_connector)); + node->outputs = (node_connector*)malloc(node->output_count * sizeof(node_connector)); + node->color = col; node->bounds = bounds; strcpy(node->name, name); @@ -266,7 +284,11 @@ node_editor_main(struct nk_context *ctx) if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && nodedit->linking.active && nodedit->linking.node != it) { - nodedit->linking.active = nk_false; + nodedit->linking.active = nk_false; + + nodedit->linking.node->outputs[nodedit->linking.input_slot].isConnected = nk_true; + it->inputs[n].isConnected = nk_true; + node_editor_link(nodedit, nodedit->linking.input_id, nodedit->linking.input_slot, it->ID, n); } diff --git a/demo/glfw_opengl3/main.c b/demo/glfw_opengl3/main.c index 8eb749de4..364632358 100644 --- a/demo/glfw_opengl3/main.c +++ b/demo/glfw_opengl3/main.c @@ -9,7 +9,8 @@ #include #include -#include +#define GL_SILENCE_DEPRECATION +/* #include */ #include #define NK_INCLUDE_FIXED_TYPES @@ -42,8 +43,8 @@ /*#define INCLUDE_STYLE */ /*#define INCLUDE_CALCULATOR */ /*#define INCLUDE_CANVAS */ -#define INCLUDE_OVERVIEW -/*#define INCLUDE_NODE_EDITOR */ +/*#define INCLUDE_OVERVIEW */ +#define INCLUDE_NODE_EDITOR */ #ifdef INCLUDE_ALL #define INCLUDE_STYLE @@ -104,11 +105,11 @@ int main(void) /* OpenGL */ glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - glewExperimental = 1; + /*glewExperimental = 1; if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to setup GLEW\n"); exit(1); - } + }*/ ctx = nk_glfw3_init(&glfw, win, NK_GLFW3_INSTALL_CALLBACKS); /* Load Fonts: if none of these are loaded a default font will be used */ @@ -191,7 +192,7 @@ int main(void) overview(ctx); #endif #ifdef INCLUDE_NODE_EDITOR - node_editor(ctx); + node_editor_main(ctx); #endif /* ----------------------------------------- */ From da7cf400c3b3c5142c32956b6fd9e8fc272ea047 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Tue, 11 Apr 2023 06:41:29 +0300 Subject: [PATCH 03/28] Node links now take node pointers instead of IDs --- demo/common/node_editor.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index e23a16cbb..ac19f9345 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -13,6 +13,8 @@ enum node_connector_type {fValue, fColor}; +enum node_type {color, mix}; + struct node_connector { enum node_connector_type type; @@ -23,6 +25,7 @@ struct node { int ID; char name[32]; struct nk_rect bounds; + enum node_type type; float value; /* unused */ struct nk_color color; int input_count; @@ -37,9 +40,9 @@ struct node { }; struct node_link { - int input_id; + struct node* input_node; int input_slot; - int output_id; + struct node* output_node; int output_slot; /* struct nk_vec2 in; struct nk_vec2 out; */ @@ -126,8 +129,8 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou node->input_count = in_count; node->output_count = out_count; - node->inputs = (node_connector*)malloc(node->input_count * sizeof(node_connector)); - node->outputs = (node_connector*)malloc(node->output_count * sizeof(node_connector)); + node->inputs = (struct node_connector*)malloc(node->input_count * sizeof(struct node_connector)); + node->outputs = (struct node_connector*)malloc(node->output_count * sizeof(struct node_connector)); node->color = col; node->bounds = bounds; @@ -136,15 +139,15 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou } static void -node_editor_link(struct node_editor *editor, int in_id, int in_slot, - int out_id, int out_slot) +node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, + struct node *out_node, int out_slot) { struct node_link *link; NK_ASSERT((nk_size)editor->link_count < NK_LEN(editor->links)); link = &editor->links[editor->link_count++]; - link->input_id = in_id; + link->input_node = in_node; link->input_slot = in_slot; - link->output_id = out_id; + link->output_node = out_node; link->output_slot = out_slot; } @@ -157,8 +160,8 @@ node_editor_init(struct node_editor *editor) node_editor_add(editor, "Source", nk_rect(40, 10, 180, 220), nk_rgb(255, 0, 0), 0, 1); node_editor_add(editor, "Source", nk_rect(40, 260, 180, 220), nk_rgb(0, 255, 0), 0, 1); node_editor_add(editor, "Combine", nk_rect(400, 100, 180, 220), nk_rgb(0,0,255), 2, 2); - node_editor_link(editor, 0, 0, 2, 0); - node_editor_link(editor, 1, 0, 2, 1); + node_editor_link(editor, node_editor_find(&nodeEditor, 0), 0, node_editor_find(&nodeEditor, 2), 0); + node_editor_link(editor, node_editor_find(&nodeEditor, 1), 0, node_editor_find(&nodeEditor, 2), 1); editor->show_grid = nk_true; } @@ -289,8 +292,8 @@ node_editor_main(struct nk_context *ctx) nodedit->linking.node->outputs[nodedit->linking.input_slot].isConnected = nk_true; it->inputs[n].isConnected = nk_true; - node_editor_link(nodedit, nodedit->linking.input_id, - nodedit->linking.input_slot, it->ID, n); + node_editor_link(nodedit, nodedit->linking.node, + nodedit->linking.input_slot, it, n); } } } @@ -307,8 +310,8 @@ node_editor_main(struct nk_context *ctx) /* draw each link */ for (n = 0; n < nodedit->link_count; ++n) { struct node_link *link = &nodedit->links[n]; - struct node *ni = node_editor_find(nodedit, link->input_id); - struct node *no = node_editor_find(nodedit, link->output_id); + struct node *ni = link->input_node;//node_editor_find(nodedit, link->input_id); + struct node *no = link->output_node;//node_editor_find(nodedit, link->output_id); float spacei = nodePanel->bounds.h / (float)((ni->output_count) + 1); float spaceo = nodePanel->bounds.h / (float)((no->input_count) + 1); struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, From 3d2e410d78c776eea426590a62a39a5a96c783af Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Tue, 11 Apr 2023 09:23:53 +0300 Subject: [PATCH 04/28] Allow only one input per input slot --- demo/common/node_editor.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index ac19f9345..5517908f4 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -132,6 +132,11 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou node->inputs = (struct node_connector*)malloc(node->input_count * sizeof(struct node_connector)); node->outputs = (struct node_connector*)malloc(node->output_count * sizeof(struct node_connector)); + for (int i = 0; i < node->input_count; i++) + node->inputs[i].isConnected = nk_false; + for (i = 0; i < node->output_count; i++) + node->outputs[i].isConnected = nk_false; + node->color = col; node->bounds = bounds; strcpy(node->name, name); @@ -142,9 +147,12 @@ static void node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, struct node *out_node, int out_slot) { + /* Confusingly, in and out nodes/slots here refer to the inputs and outputs OF THE LINK ITSELF, not the nodes */ struct node_link *link; NK_ASSERT((nk_size)editor->link_count < NK_LEN(editor->links)); link = &editor->links[editor->link_count++]; + out_node->inputs[out_slot].isConnected = nk_true; + in_node->outputs[in_slot].isConnected = nk_true; link->input_node = in_node; link->input_slot = in_slot; link->output_node = out_node; @@ -160,8 +168,8 @@ node_editor_init(struct node_editor *editor) node_editor_add(editor, "Source", nk_rect(40, 10, 180, 220), nk_rgb(255, 0, 0), 0, 1); node_editor_add(editor, "Source", nk_rect(40, 260, 180, 220), nk_rgb(0, 255, 0), 0, 1); node_editor_add(editor, "Combine", nk_rect(400, 100, 180, 220), nk_rgb(0,0,255), 2, 2); - node_editor_link(editor, node_editor_find(&nodeEditor, 0), 0, node_editor_find(&nodeEditor, 2), 0); - node_editor_link(editor, node_editor_find(&nodeEditor, 1), 0, node_editor_find(&nodeEditor, 2), 1); + //node_editor_link(editor, node_editor_find(&nodeEditor, 0), 0, node_editor_find(&nodeEditor, 2), 0); + //node_editor_link(editor, node_editor_find(&nodeEditor, 1), 0, node_editor_find(&nodeEditor, 2), 1); editor->show_grid = nk_true; } @@ -286,11 +294,10 @@ node_editor_main(struct nk_context *ctx) /* (Create link) */ if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && - nodedit->linking.active && nodedit->linking.node != it) { + nodedit->linking.active && + nodedit->linking.node != it && + it->inputs[n].isConnected != nk_true) { nodedit->linking.active = nk_false; - - nodedit->linking.node->outputs[nodedit->linking.input_slot].isConnected = nk_true; - it->inputs[n].isConnected = nk_true; node_editor_link(nodedit, nodedit->linking.node, nodedit->linking.input_slot, it, n); From da00363fb19b01ccce5c1333b14e8802019f6a73 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Tue, 11 Apr 2023 16:46:58 +0300 Subject: [PATCH 05/28] Detachable/movable links --- demo/common/node_editor.c | 63 +++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 5517908f4..e131eb297 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -44,6 +44,7 @@ struct node_link { int input_slot; struct node* output_node; int output_slot; + nk_bool isActive; /* struct nk_vec2 in; struct nk_vec2 out; */ }; @@ -115,6 +116,21 @@ node_editor_find(struct node_editor *editor, int ID) return NULL; } +static struct node_link* +node_editor_find_link_by_output(struct node_editor *editor, struct node *output_node, int node_input_connector) +{ + for (int i = 0; i < editor->link_count; i++) + { + if (editor->links[i].output_node == output_node && + editor->links[i].output_slot == node_input_connector && + editor->links[i].isActive == nk_true) + { + return &editor->links[i]; + } + } + return NULL; +} + static void node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, struct nk_color col, int in_count, int out_count) @@ -157,6 +173,7 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, link->input_slot = in_slot; link->output_node = out_node; link->output_slot = out_slot; + link->isActive = nk_true; } static void @@ -291,6 +308,20 @@ node_editor_main(struct nk_context *ctx) circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); + /* Detach link */ + if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true) && + nodedit->linking.active == nk_false && + it->inputs[n].isConnected == nk_true) { + nodedit->linking.active = nk_true; + struct node_link *node_relink = node_editor_find_link_by_output(nodedit, it, n); + nodedit->linking.node = node_relink->input_node; + nodedit->linking.input_id = node_relink->input_node->ID; + nodedit->linking.input_slot = node_relink->input_slot; + node_relink->isActive = nk_false; + it->inputs[n].isConnected = nk_false; + node_relink->input_node->inputs[node_relink->input_slot].isConnected = nk_false; + } + /* (Create link) */ if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && @@ -317,21 +348,23 @@ node_editor_main(struct nk_context *ctx) /* draw each link */ for (n = 0; n < nodedit->link_count; ++n) { struct node_link *link = &nodedit->links[n]; - struct node *ni = link->input_node;//node_editor_find(nodedit, link->input_id); - struct node *no = link->output_node;//node_editor_find(nodedit, link->output_id); - float spacei = nodePanel->bounds.h / (float)((ni->output_count) + 1); - float spaceo = nodePanel->bounds.h / (float)((no->input_count) + 1); - struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, - nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + spacei * (float)(link->input_slot+1))); - struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, - nk_vec2(no->bounds.x, 3.0f + no->bounds.y + spaceo * (float)(link->output_slot+1))); - - l0.x -= nodedit->scrolling.x; - l0.y -= nodedit->scrolling.y; - l1.x -= nodedit->scrolling.x; - l1.y -= nodedit->scrolling.y; - nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, - l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); + if (link->isActive == nk_true){ + struct node *ni = link->input_node;//node_editor_find(nodedit, link->input_id); + struct node *no = link->output_node;//node_editor_find(nodedit, link->output_id); + float spacei = nodePanel->bounds.h / (float)((ni->output_count) + 1); + float spaceo = nodePanel->bounds.h / (float)((no->input_count) + 1); + struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, + nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + spacei * (float)(link->input_slot+1))); + struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, + nk_vec2(no->bounds.x, 3.0f + no->bounds.y + spaceo * (float)(link->output_slot+1))); + + l0.x -= nodedit->scrolling.x; + l0.y -= nodedit->scrolling.y; + l1.x -= nodedit->scrolling.x; + l1.y -= nodedit->scrolling.y; + nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, + l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); + } } if (updated) { From ea9bfef2b5b1e20da67c27577dc54cbc2595928d Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 12 Apr 2023 12:49:17 +0300 Subject: [PATCH 06/28] Drawing of node as a separate function --- demo/common/node_editor.c | 40 ++++++++++---- demo/common/nodeeditor/node_type_color.c | 66 ++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 demo/common/nodeeditor/node_type_color.c diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index e131eb297..c2b1573b6 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -36,7 +36,7 @@ struct node { struct node *prev; /* Z ordering only */ void* (*evalFunc)(struct node*, int oIndex); - void (*displayFunc)(struct node*, struct nk_context *ctx); + void (*displayFunc)(struct nk_context*, struct node*); }; struct node_link { @@ -72,6 +72,8 @@ struct node_editor { }; static struct node_editor nodeEditor; +#include "nodeeditor/node_type_color.c" + static void node_editor_push(struct node_editor *editor, struct node *node) { @@ -135,23 +137,43 @@ static void node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, struct nk_color col, int in_count, int out_count) { + + /* + + Handle generic node creation things such as: + - create panel + - create connectors + - add node to node tree + + This should probably be called by the node type-specific init function? + */ + static int IDs = 0; /* static duration */ struct node *node; NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); node = &editor->node_buf[editor->node_count++]; /* next node in buffer */ node->ID = IDs++; /* increment IDs and set as node ID */ + node->value = 0; /* unused? */ node->color = nk_rgb(255, 0, 0); + node->input_count = in_count; node->output_count = out_count; node->inputs = (struct node_connector*)malloc(node->input_count * sizeof(struct node_connector)); node->outputs = (struct node_connector*)malloc(node->output_count * sizeof(struct node_connector)); - for (int i = 0; i < node->input_count; i++) + for (int i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; - for (i = 0; i < node->output_count; i++) + node->inputs[i].type = fValue; + } + for (i = 0; i < node->output_count; i++) { node->outputs[i].isConnected = nk_false; + node->outputs[i].type = fValue; + } + + // this should be in the node type-specific initializer + node->displayFunc = node_color_draw; node->color = col; node->bounds = bounds; @@ -249,14 +271,10 @@ node_editor_main(struct nk_context *ctx) updated = it; } - /* ================= NODE CONTENT =====================*/ - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_color(ctx, it->color); - it->color.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, it->color.r, 255, 1,1); - it->color.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, it->color.g, 255, 1,1); - it->color.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, it->color.b, 255, 1,1); - it->color.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, it->color.a, 255, 1,1); - /* ====================================================*/ + /* ================= NODE CONTENT ===================== */ + it->displayFunc(ctx, it); + /* ==================================================== */ + nk_group_end(ctx); } { diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c new file mode 100644 index 000000000..3bdb91d49 --- /dev/null +++ b/demo/common/nodeeditor/node_type_color.c @@ -0,0 +1,66 @@ +struct node_type_color { + struct node node; + float *inputVal; + struct nk_colorf *outputVal; + +}; + +/* +static void* node_color_get(struct node* self, int oIndex) +{ + struct node_type_color *node = ((struct node_type_color*)self); + for (int i = 0; i < self->input_count; i++) + { + if (self->inputs[i].isConnected) + { + /* + call getter func of connected node and assign to ((node_type_color*)self)->inputVal[i] + *//* + } + } + node->outputVal->r = node->inputVal[0]; + node->outputVal->g = node->inputVal[1]; + node->outputVal->b = node->inputVal[2]; + node->outputVal->a = node->inputVal[3]; + + struct nk_colorf *returnpointer = ((struct node_type_color*)self)->outputVal; + return (void*) returnpointer; +}*/ + + +static void node_color_draw(struct nk_context *ctx, struct node* node) +{ + /* ================= NODE CONTENT =====================*/ + nk_layout_row_dynamic(ctx, 25, 1); + nk_button_color(ctx, node->color); + node->color.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, node->color.r, 255, 1,1); + node->color.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, node->color.g, 255, 1,1); + node->color.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, node->color.b, 255, 1,1); + node->color.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, node->color.a, 255, 1,1); + /* ====================================================*/ +} + +/* +struct node* node_color_init() +{ + struct node_type_color *colornode = (struct node_type_color*)malloc(sizeof(struct node_type_color)); + colornode->node.input_count = 4; + colornode->node.output_count = 1; + + colornode->node.inputs = (struct node_connector*)malloc(colornode->node.input_count * sizeof(struct node_connector)); + for (int i = 0; i < colornode->node.input_count; i++) { + colornode->node.inputs[i].type = fValue; + } + colornode->inputVal = (float*)malloc(colornode->node.input_count * sizeof(float)); + + + colornode->node.outputs = (struct node_connector*)malloc(colornode->node.output_count * sizeof(struct node_connector)); + colornode->node.outputs->type = fColor; + colornode->outputVal = (struct nk_colorf*)malloc(colornode->node.input_count * sizeof(struct nk_colorf)); + + colornode->node.displayFunc = node_color_draw; + //colornode->node.evalFunc = get_nodetypes_color; + + return (struct node*)colornode; // does this need to return (node*)(&colornode->node) ?? +} +*/ From 52eff509b29ff61701bbad1031f262b51363441e Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Thu, 13 Apr 2023 07:02:29 +0300 Subject: [PATCH 07/28] Color node creation added --- demo/common/node_editor.c | 23 +++++++++++++++++------ demo/common/nodeeditor/node_type_color.c | 24 ++---------------------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index c2b1573b6..1c86a9ee3 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -72,6 +72,14 @@ struct node_editor { }; static struct node_editor nodeEditor; +/* === PROTOTYPES === */ + +static struct node* node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, + struct nk_color col, int in_count, int out_count); + +/* ================== */ + + #include "nodeeditor/node_type_color.c" static void @@ -133,7 +141,7 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ return NULL; } -static void +static struct node* node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, struct nk_color col, int in_count, int out_count) { @@ -179,6 +187,7 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou node->bounds = bounds; strcpy(node->name, name); node_editor_push(editor, node); + return node; } static void @@ -204,9 +213,9 @@ node_editor_init(struct node_editor *editor) memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; - node_editor_add(editor, "Source", nk_rect(40, 10, 180, 220), nk_rgb(255, 0, 0), 0, 1); - node_editor_add(editor, "Source", nk_rect(40, 260, 180, 220), nk_rgb(0, 255, 0), 0, 1); - node_editor_add(editor, "Combine", nk_rect(400, 100, 180, 220), nk_rgb(0,0,255), 2, 2); + node_editor_add(editor, "Dummy1", nk_rect(40, 10, 180, 220), nk_rgb(255, 0, 0), 0, 1); + node_editor_add(editor, "Dummy2", nk_rect(40, 260, 180, 220), nk_rgb(0, 255, 0), 0, 1); + node_editor_add(editor, "Dummy3", nk_rect(400, 100, 180, 220), nk_rgb(0,0,255), 2, 2); //node_editor_link(editor, node_editor_find(&nodeEditor, 0), 0, node_editor_find(&nodeEditor, 2), 0); //node_editor_link(editor, node_editor_find(&nodeEditor, 1), 0, node_editor_find(&nodeEditor, 2), 1); editor->show_grid = nk_true; @@ -407,12 +416,14 @@ node_editor_main(struct nk_context *ctx) } /* contextual menu */ - if (nk_contextual_begin(ctx, 0, nk_vec2(100, 220), nk_window_get_bounds(ctx))) { + if (nk_contextual_begin(ctx, 0, nk_vec2(150, 220), nk_window_get_bounds(ctx))) { const char *grid_option[] = {"Show Grid", "Hide Grid"}; nk_layout_row_dynamic(ctx, 25, 1); if (nk_contextual_item_label(ctx, "New", NK_TEXT_CENTERED)) - node_editor_add(nodedit, "New", nk_rect(400, 260, 180, 220), + node_editor_add(nodedit, "New", nk_rect(in->mouse.pos.x, in->mouse.pos.y, 180, 220), nk_rgb(255, 255, 255), 1, 2); + if (nk_contextual_item_label(ctx, "Add Color node", NK_TEXT_CENTERED)) + node_color_create(nodedit, in->mouse.pos); if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) nodedit->show_grid = !nodedit->show_grid; nk_contextual_end(ctx); diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 3bdb91d49..5b1973b2c 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -40,27 +40,7 @@ static void node_color_draw(struct nk_context *ctx, struct node* node) /* ====================================================*/ } -/* -struct node* node_color_init() +void node_color_create(struct node_editor* editor, struct nk_vec2 position) { - struct node_type_color *colornode = (struct node_type_color*)malloc(sizeof(struct node_type_color)); - colornode->node.input_count = 4; - colornode->node.output_count = 1; - - colornode->node.inputs = (struct node_connector*)malloc(colornode->node.input_count * sizeof(struct node_connector)); - for (int i = 0; i < colornode->node.input_count; i++) { - colornode->node.inputs[i].type = fValue; - } - colornode->inputVal = (float*)malloc(colornode->node.input_count * sizeof(float)); - - - colornode->node.outputs = (struct node_connector*)malloc(colornode->node.output_count * sizeof(struct node_connector)); - colornode->node.outputs->type = fColor; - colornode->outputVal = (struct nk_colorf*)malloc(colornode->node.input_count * sizeof(struct nk_colorf)); - - colornode->node.displayFunc = node_color_draw; - //colornode->node.evalFunc = get_nodetypes_color; - - return (struct node*)colornode; // does this need to return (node*)(&colornode->node) ?? + struct node *node = node_editor_add(editor, "Color", nk_rect(position.x, position.y, 180, 220), nk_rgb(255, 255, 255), 4, 1); } -*/ From e9e391ee322463dec46f4dfcdada92bb61e48df9 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Fri, 14 Apr 2023 06:47:48 +0300 Subject: [PATCH 08/28] Node connector positioning --- demo/common/node_editor.c | 38 ++++++++++++++---------- demo/common/nodeeditor/node_type_color.c | 4 +++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 1c86a9ee3..e19384947 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -32,6 +32,12 @@ struct node { int output_count; struct node_connector *inputs; /* These could be made into arrays to get rid of the allocation at node creation. */ struct node_connector *outputs; /* For this demo we probably only need a max of four inputs and one output. */ + struct { + float in_top; + float in_space; + float out_top; + float out_space; + } slot_spacing; /* not sure what to call this really... */ struct node *next; /* Z ordering only */ struct node *prev; /* Z ordering only */ @@ -163,7 +169,10 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou node->ID = IDs++; /* increment IDs and set as node ID */ node->value = 0; /* unused? */ - node->color = nk_rgb(255, 0, 0); + node->color = nk_rgb(255, 0, 0); /* to be removed */ + node->color = col; /* to be removed */ + + node->bounds = bounds; node->input_count = in_count; node->output_count = out_count; @@ -173,20 +182,24 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou for (int i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; - node->inputs[i].type = fValue; + node->inputs[i].type = fValue; } for (i = 0; i < node->output_count; i++) { node->outputs[i].isConnected = nk_false; node->outputs[i].type = fValue; } - // this should be in the node type-specific initializer - node->displayFunc = node_color_draw; - node->color = col; - node->bounds = bounds; + /* default connector spacing */ + node->slot_spacing.in_top = node->slot_spacing.in_space = node->bounds.h / (float)((node->input_count) + 1); + node->slot_spacing.out_top = node->slot_spacing.out_space = node->bounds.h / (float)((node->output_count) + 1); + strcpy(node->name, name); node_editor_push(editor, node); + + /* this should be in the node type-specific initializer */ + node->displayFunc = node_color_draw; + return node; } @@ -288,7 +301,6 @@ node_editor_main(struct nk_context *ctx) } { /* node connector and linking */ - float space; /* space between output circles */ struct nk_rect bounds; bounds = nk_layout_space_rect_to_local(ctx, nodePanel->bounds); bounds.x += nodedit->scrolling.x; @@ -296,13 +308,12 @@ node_editor_main(struct nk_context *ctx) it->bounds = bounds; /* output connector */ - space = nodePanel->bounds.h / (float)((it->output_count) + 1); /* (loop through outputs) */ for (n = 0; n < it->output_count; ++n) { struct nk_rect circle; circle.x = nodePanel->bounds.x + nodePanel->bounds.w-4; - circle.y = nodePanel->bounds.y + space * (float)(n+1); + circle.y = nodePanel->bounds.y + it->slot_spacing.out_top + it->slot_spacing.out_space * (float)n; circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); @@ -327,11 +338,10 @@ node_editor_main(struct nk_context *ctx) } /* input connector */ - space = nodePanel->bounds.h / (float)((it->input_count) + 1); for (n = 0; n < it->input_count; ++n) { struct nk_rect circle; circle.x = nodePanel->bounds.x-4; - circle.y = nodePanel->bounds.y + space * (float)(n+1); + circle.y = nodePanel->bounds.y + it->slot_spacing.in_top + it->slot_spacing.in_space * (float)n; circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); @@ -378,12 +388,10 @@ node_editor_main(struct nk_context *ctx) if (link->isActive == nk_true){ struct node *ni = link->input_node;//node_editor_find(nodedit, link->input_id); struct node *no = link->output_node;//node_editor_find(nodedit, link->output_id); - float spacei = nodePanel->bounds.h / (float)((ni->output_count) + 1); - float spaceo = nodePanel->bounds.h / (float)((no->input_count) + 1); struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, - nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + spacei * (float)(link->input_slot+1))); + nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + ni->slot_spacing.out_top + ni->slot_spacing.out_space * (float)(link->input_slot))); struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, - nk_vec2(no->bounds.x, 3.0f + no->bounds.y + spaceo * (float)(link->output_slot+1))); + nk_vec2(no->bounds.x, 3.0f + no->bounds.y + no->slot_spacing.in_top + no->slot_spacing.in_space * (float)(link->output_slot))); l0.x -= nodedit->scrolling.x; l0.y -= nodedit->scrolling.y; diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 5b1973b2c..206f7c819 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -43,4 +43,8 @@ static void node_color_draw(struct nk_context *ctx, struct node* node) void node_color_create(struct node_editor* editor, struct nk_vec2 position) { struct node *node = node_editor_add(editor, "Color", nk_rect(position.x, position.y, 180, 220), nk_rgb(255, 255, 255), 4, 1); + node->slot_spacing.in_top = 72.0f; + node->slot_spacing.in_space = 29.0f; + node->slot_spacing.out_top = 42.0f; + node->slot_spacing.out_space = 0.0f; } From f4369efc1aa6d82485443e3e784b32bdd972185c Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Fri, 14 Apr 2023 09:28:31 +0300 Subject: [PATCH 09/28] Color coded slots + only allow link to same type --- demo/common/node_editor.c | 14 ++++++++++++-- demo/common/nodeeditor/node_type_color.c | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index e19384947..65a6e2a1e 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -183,6 +183,7 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou for (int i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; node->inputs[i].type = fValue; + if (i == 0) node->inputs[i].type = fColor; /* for testing */ } for (i = 0; i < node->output_count; i++) { node->outputs[i].isConnected = nk_false; @@ -312,10 +313,14 @@ node_editor_main(struct nk_context *ctx) /* (loop through outputs) */ for (n = 0; n < it->output_count; ++n) { struct nk_rect circle; + struct nk_color color; circle.x = nodePanel->bounds.x + nodePanel->bounds.w-4; circle.y = nodePanel->bounds.y + it->slot_spacing.out_top + it->slot_spacing.out_space * (float)n; circle.w = 8; circle.h = 8; - nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); + if (it->outputs[n].type == fColor) + color = nk_rgb(200, 200, 0); + else color = nk_rgb(100, 100, 100); + nk_fill_circle(canvas, circle, color); /* start linking process */ /* (set linking active) */ @@ -340,10 +345,14 @@ node_editor_main(struct nk_context *ctx) /* input connector */ for (n = 0; n < it->input_count; ++n) { struct nk_rect circle; + struct nk_color color; circle.x = nodePanel->bounds.x-4; circle.y = nodePanel->bounds.y + it->slot_spacing.in_top + it->slot_spacing.in_space * (float)n; circle.w = 8; circle.h = 8; - nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); + if (it->inputs[n].type == fColor) + color = nk_rgb(200, 200, 0); + else color = nk_rgb(100, 100, 100); + nk_fill_circle(canvas, circle, color); /* Detach link */ if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true) && @@ -364,6 +373,7 @@ node_editor_main(struct nk_context *ctx) nk_input_is_mouse_hovering_rect(in, circle) && nodedit->linking.active && nodedit->linking.node != it && + it->inputs[n].type == nodedit->linking.node->outputs[nodedit->linking.input_slot].type && it->inputs[n].isConnected != nk_true) { nodedit->linking.active = nk_false; diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 206f7c819..5af42d657 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -47,4 +47,8 @@ void node_color_create(struct node_editor* editor, struct nk_vec2 position) node->slot_spacing.in_space = 29.0f; node->slot_spacing.out_top = 42.0f; node->slot_spacing.out_space = 0.0f; + + for (int i = 0; i < node->input_count; i++) + node->inputs[i].type = fValue; + node->outputs[0].type = fColor; } From 86388491afa5d67616e8e55bff71c56cba704f0d Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Mon, 17 Apr 2023 09:07:48 +0300 Subject: [PATCH 10/28] Color node creation and display, base Node now generic --- demo/common/node_editor.c | 47 ++++++--------------- demo/common/nodeeditor/node_type_color.c | 53 ++++++++++++++++-------- 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 65a6e2a1e..5821a6340 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -19,6 +19,8 @@ enum node_type {color, mix}; struct node_connector { enum node_connector_type type; nk_bool isConnected; + struct node* connectedNode; + int connectedSlot; }; struct node { @@ -64,7 +66,7 @@ struct node_linking { struct node_editor { int initialized; - struct node node_buf[32]; + struct node *node_buf[32]; struct node_link links[64]; struct node *begin; struct node *end; @@ -80,8 +82,8 @@ static struct node_editor nodeEditor; /* === PROTOTYPES === */ -static struct node* node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, - struct nk_color col, int in_count, int out_count); +static struct node* node_editor_add(struct node_editor *editor, struct node *node, const char *name, struct nk_rect bounds, + int in_count, int out_count); /* ================== */ @@ -148,29 +150,13 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ } static struct node* -node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bounds, - struct nk_color col, int in_count, int out_count) +node_editor_add(struct node_editor *editor, struct node *node, const char *name, struct nk_rect bounds, +int in_count, int out_count) { - - /* - - Handle generic node creation things such as: - - create panel - - create connectors - - add node to node tree - - This should probably be called by the node type-specific init function? - */ - static int IDs = 0; /* static duration */ - struct node *node; NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); - node = &editor->node_buf[editor->node_count++]; /* next node in buffer */ + editor->node_buf[editor->node_count++] = node; /* next node in buffer */ node->ID = IDs++; /* increment IDs and set as node ID */ - - node->value = 0; /* unused? */ - node->color = nk_rgb(255, 0, 0); /* to be removed */ - node->color = col; /* to be removed */ node->bounds = bounds; @@ -182,15 +168,13 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou for (int i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; - node->inputs[i].type = fValue; - if (i == 0) node->inputs[i].type = fColor; /* for testing */ + node->inputs[i].type = fValue; } for (i = 0; i < node->output_count; i++) { node->outputs[i].isConnected = nk_false; node->outputs[i].type = fValue; } - /* default connector spacing */ node->slot_spacing.in_top = node->slot_spacing.in_space = node->bounds.h / (float)((node->input_count) + 1); node->slot_spacing.out_top = node->slot_spacing.out_space = node->bounds.h / (float)((node->output_count) + 1); @@ -198,9 +182,6 @@ node_editor_add(struct node_editor *editor, const char *name, struct nk_rect bou strcpy(node->name, name); node_editor_push(editor, node); - /* this should be in the node type-specific initializer */ - node->displayFunc = node_color_draw; - return node; } @@ -227,11 +208,7 @@ node_editor_init(struct node_editor *editor) memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; - node_editor_add(editor, "Dummy1", nk_rect(40, 10, 180, 220), nk_rgb(255, 0, 0), 0, 1); - node_editor_add(editor, "Dummy2", nk_rect(40, 260, 180, 220), nk_rgb(0, 255, 0), 0, 1); - node_editor_add(editor, "Dummy3", nk_rect(400, 100, 180, 220), nk_rgb(0,0,255), 2, 2); - //node_editor_link(editor, node_editor_find(&nodeEditor, 0), 0, node_editor_find(&nodeEditor, 2), 0); - //node_editor_link(editor, node_editor_find(&nodeEditor, 1), 0, node_editor_find(&nodeEditor, 2), 1); + node_color_create(editor, (struct nk_vec2){40, 10}); editor->show_grid = nk_true; } @@ -437,9 +414,9 @@ node_editor_main(struct nk_context *ctx) if (nk_contextual_begin(ctx, 0, nk_vec2(150, 220), nk_window_get_bounds(ctx))) { const char *grid_option[] = {"Show Grid", "Hide Grid"}; nk_layout_row_dynamic(ctx, 25, 1); - if (nk_contextual_item_label(ctx, "New", NK_TEXT_CENTERED)) + /* if (nk_contextual_item_label(ctx, "New", NK_TEXT_CENTERED)) node_editor_add(nodedit, "New", nk_rect(in->mouse.pos.x, in->mouse.pos.y, 180, 220), - nk_rgb(255, 255, 255), 1, 2); + nk_rgb(255, 255, 255), 1, 2); */ if (nk_contextual_item_label(ctx, "Add Color node", NK_TEXT_CENTERED)) node_color_create(nodedit, in->mouse.pos); if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 5af42d657..e7b5ede4a 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -1,7 +1,7 @@ struct node_type_color { struct node node; - float *inputVal; - struct nk_colorf *outputVal; + float inputVal[4]; + struct nk_colorf outputVal; }; @@ -30,25 +30,44 @@ static void* node_color_get(struct node* self, int oIndex) static void node_color_draw(struct nk_context *ctx, struct node* node) { - /* ================= NODE CONTENT =====================*/ + struct node_type_color *colornode = (struct node_type_color*)node; nk_layout_row_dynamic(ctx, 25, 1); - nk_button_color(ctx, node->color); - node->color.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, node->color.r, 255, 1,1); - node->color.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, node->color.g, 255, 1,1); - node->color.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, node->color.b, 255, 1,1); - node->color.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, node->color.a, 255, 1,1); - /* ====================================================*/ + nk_button_color(ctx, nk_rgba_f(colornode->inputVal[0],colornode->inputVal[1],colornode->inputVal[2],colornode->inputVal[3])); + colornode->inputVal[0] = colornode->node.inputs[0].isConnected ? + nk_propertyf(ctx, "#R:", colornode->inputVal[0], colornode->inputVal[0], colornode->inputVal[0], 0.05f, 0.05f) : + nk_propertyf(ctx, "#R:", 0.0f, colornode->inputVal[0], 1.0f, 0.01f, 0.01f); + colornode->inputVal[1] = colornode->node.inputs[1].isConnected ? + nk_propertyf(ctx, "#G:", colornode->inputVal[1], colornode->inputVal[1], colornode->inputVal[1], 0.05f, 0.05f) : + nk_propertyf(ctx, "#G:", 0.0f, colornode->inputVal[1], 1.0f, 0.01f, 0.01f); + colornode->inputVal[2] = colornode->node.inputs[0].isConnected ? + nk_propertyf(ctx, "#B:", colornode->inputVal[2], colornode->inputVal[2], colornode->inputVal[2], 0.05f, 0.05f) : + nk_propertyf(ctx, "#B:", 0.0f, colornode->inputVal[2], 1.0f, 0.01f, 0.01f); + colornode->inputVal[3] = colornode->node.inputs[3].isConnected ? + nk_propertyf(ctx, "#A:", colornode->inputVal[3], colornode->inputVal[3], colornode->inputVal[3], 0.05f, 0.05f) : + nk_propertyf(ctx, "#A:", 0.0f, colornode->inputVal[3], 1.0f, 0.01f, 0.01f); } void node_color_create(struct node_editor* editor, struct nk_vec2 position) { - struct node *node = node_editor_add(editor, "Color", nk_rect(position.x, position.y, 180, 220), nk_rgb(255, 255, 255), 4, 1); - node->slot_spacing.in_top = 72.0f; - node->slot_spacing.in_space = 29.0f; - node->slot_spacing.out_top = 42.0f; - node->slot_spacing.out_space = 0.0f; + /* Not sure if this allocation should be in node_editor_add. Maybe just pass the size, and get the pointer back? */ + struct node_type_color *colornode = (struct node_type_color*)malloc(sizeof(struct node_type_color)); + + node_editor_add(editor, (struct node*)colornode, "Color", nk_rect(position.x, position.y, 180, 220), 4, 1); + colornode->node.slot_spacing.in_top = 72.0f; + colornode->node.slot_spacing.in_space = 29.0f; + colornode->node.slot_spacing.out_top = 42.0f; + colornode->node.slot_spacing.out_space = 0.0f; + + for (int i = 0; i < colornode->node.input_count; i++) + colornode->node.inputs[i].type = fValue; + colornode->node.outputs[0].type = fColor; - for (int i = 0; i < node->input_count; i++) - node->inputs[i].type = fValue; - node->outputs[0].type = fColor; + colornode->inputVal[0] = + colornode->inputVal[1] = + colornode->inputVal[2] = + colornode->inputVal[3] = 1.0f; + + colornode->outputVal = (struct nk_colorf){1.0f, 1.0f, 1.0f, 1.0f}; + + colornode->node.displayFunc = node_color_draw; } From 5f1e3efd29fe6870ca47f6c01c0d116fb1556c46 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Mon, 17 Apr 2023 15:00:09 +0300 Subject: [PATCH 11/28] Float and Output nodes, all mallocs into node_editor_add --- demo/common/node_editor.c | 18 +++++++++++------- demo/common/nodeeditor/node_type_color.c | 12 ++++-------- demo/common/nodeeditor/node_type_float.c | 17 +++++++++++++++++ demo/common/nodeeditor/node_type_output.c | 15 +++++++++++++++ 4 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 demo/common/nodeeditor/node_type_float.c create mode 100644 demo/common/nodeeditor/node_type_output.c diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 5821a6340..c2e87d6ba 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -27,9 +27,7 @@ struct node { int ID; char name[32]; struct nk_rect bounds; - enum node_type type; - float value; /* unused */ - struct nk_color color; + /* enum node_type type; */ int input_count; int output_count; struct node_connector *inputs; /* These could be made into arrays to get rid of the allocation at node creation. */ @@ -82,13 +80,15 @@ static struct node_editor nodeEditor; /* === PROTOTYPES === */ -static struct node* node_editor_add(struct node_editor *editor, struct node *node, const char *name, struct nk_rect bounds, +static struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count); /* ================== */ #include "nodeeditor/node_type_color.c" +#include "nodeeditor/node_type_float.c" +#include "nodeeditor/node_type_output.c" static void node_editor_push(struct node_editor *editor, struct node *node) @@ -150,11 +150,12 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ } static struct node* -node_editor_add(struct node_editor *editor, struct node *node, const char *name, struct nk_rect bounds, +node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count) { static int IDs = 0; /* static duration */ NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); + struct node *node = malloc(nodeSize); editor->node_buf[editor->node_count++] = node; /* next node in buffer */ node->ID = IDs++; /* increment IDs and set as node ID */ @@ -163,8 +164,8 @@ int in_count, int out_count) node->input_count = in_count; node->output_count = out_count; - node->inputs = (struct node_connector*)malloc(node->input_count * sizeof(struct node_connector)); - node->outputs = (struct node_connector*)malloc(node->output_count * sizeof(struct node_connector)); + node->inputs = malloc(node->input_count * sizeof(struct node_connector)); + node->outputs = malloc(node->output_count * sizeof(struct node_connector)); for (int i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; @@ -209,6 +210,7 @@ node_editor_init(struct node_editor *editor) editor->begin = NULL; editor->end = NULL; node_color_create(editor, (struct nk_vec2){40, 10}); + node_output_create(editor, (struct nk_vec2){200, 200}); editor->show_grid = nk_true; } @@ -419,6 +421,8 @@ node_editor_main(struct nk_context *ctx) nk_rgb(255, 255, 255), 1, 2); */ if (nk_contextual_item_label(ctx, "Add Color node", NK_TEXT_CENTERED)) node_color_create(nodedit, in->mouse.pos); + if (nk_contextual_item_label(ctx, "Add Float node", NK_TEXT_CENTERED)) + node_float_create(nodedit, in->mouse.pos); if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) nodedit->show_grid = !nodedit->show_grid; nk_contextual_end(ctx); diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index e7b5ede4a..62df8d653 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -2,7 +2,6 @@ struct node_type_color { struct node node; float inputVal[4]; struct nk_colorf outputVal; - }; /* @@ -28,7 +27,7 @@ static void* node_color_get(struct node* self, int oIndex) }*/ -static void node_color_draw(struct nk_context *ctx, struct node* node) +static void node_color_draw(struct nk_context *ctx, struct node *node) { struct node_type_color *colornode = (struct node_type_color*)node; nk_layout_row_dynamic(ctx, 25, 1); @@ -39,7 +38,7 @@ static void node_color_draw(struct nk_context *ctx, struct node* node) colornode->inputVal[1] = colornode->node.inputs[1].isConnected ? nk_propertyf(ctx, "#G:", colornode->inputVal[1], colornode->inputVal[1], colornode->inputVal[1], 0.05f, 0.05f) : nk_propertyf(ctx, "#G:", 0.0f, colornode->inputVal[1], 1.0f, 0.01f, 0.01f); - colornode->inputVal[2] = colornode->node.inputs[0].isConnected ? + colornode->inputVal[2] = colornode->node.inputs[2].isConnected ? nk_propertyf(ctx, "#B:", colornode->inputVal[2], colornode->inputVal[2], colornode->inputVal[2], 0.05f, 0.05f) : nk_propertyf(ctx, "#B:", 0.0f, colornode->inputVal[2], 1.0f, 0.01f, 0.01f); colornode->inputVal[3] = colornode->node.inputs[3].isConnected ? @@ -47,12 +46,9 @@ static void node_color_draw(struct nk_context *ctx, struct node* node) nk_propertyf(ctx, "#A:", 0.0f, colornode->inputVal[3], 1.0f, 0.01f, 0.01f); } -void node_color_create(struct node_editor* editor, struct nk_vec2 position) +void node_color_create(struct node_editor *editor, struct nk_vec2 position) { - /* Not sure if this allocation should be in node_editor_add. Maybe just pass the size, and get the pointer back? */ - struct node_type_color *colornode = (struct node_type_color*)malloc(sizeof(struct node_type_color)); - - node_editor_add(editor, (struct node*)colornode, "Color", nk_rect(position.x, position.y, 180, 220), 4, 1); + struct node_type_color *colornode = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 220), 4, 1); colornode->node.slot_spacing.in_top = 72.0f; colornode->node.slot_spacing.in_space = 29.0f; colornode->node.slot_spacing.out_top = 42.0f; diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c new file mode 100644 index 000000000..facc2caad --- /dev/null +++ b/demo/common/nodeeditor/node_type_float.c @@ -0,0 +1,17 @@ +struct node_type_float { + struct node node; + float outputVal; +}; + +static void node_float_draw(struct nk_context *ctx, struct node *node) { + struct node_type_float *floatnode = (struct node_type_float*)node; + nk_layout_row_dynamic(ctx, 25, 1); + floatnode->outputVal = nk_propertyf(ctx, "#Value:", 0.0f, floatnode->outputVal, 1.0f, 0.01f, 0.01f); +} + +void node_float_create(struct node_editor *editor, struct nk_vec2 position) { + struct node_type_float *floatnode = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 100), 0, 1); + + floatnode->outputVal = 1.0f; + floatnode->node.displayFunc = node_float_draw; +} \ No newline at end of file diff --git a/demo/common/nodeeditor/node_type_output.c b/demo/common/nodeeditor/node_type_output.c new file mode 100644 index 000000000..e4a13ddc7 --- /dev/null +++ b/demo/common/nodeeditor/node_type_output.c @@ -0,0 +1,15 @@ +struct node_type_output { + struct node node; + struct nk_color inputVal; +}; + +static void node_output_display(struct nk_context *ctx, struct node *node) { + +} + +void node_output_create(struct node_editor *editor, struct nk_vec2 position) { + struct node_type_output *outputNode = (struct node_type_output*)node_editor_add(editor, sizeof(struct node_type_output), "Output", nk_rect(position.x, position.y, 100, 100), 1, 0); + + outputNode->node.inputs[0].type = fColor; + outputNode->node.displayFunc = node_output_display; +} \ No newline at end of file From f165244c8e015cb6369ad61d2ac70a31ef6b7ba5 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 19 Apr 2023 19:38:58 +0300 Subject: [PATCH 12/28] Node eval functions --- demo/common/node_editor.c | 8 +++- demo/common/nodeeditor/node_type_color.c | 56 ++++++++++------------- demo/common/nodeeditor/node_type_float.c | 7 +++ demo/common/nodeeditor/node_type_output.c | 11 +++-- 4 files changed, 46 insertions(+), 36 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index c2e87d6ba..75306ab11 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -66,6 +66,7 @@ struct node_editor { int initialized; struct node *node_buf[32]; struct node_link links[64]; + struct node *outputNode; struct node *begin; struct node *end; int node_count; @@ -196,6 +197,9 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, link = &editor->links[editor->link_count++]; out_node->inputs[out_slot].isConnected = nk_true; in_node->outputs[in_slot].isConnected = nk_true; + out_node->inputs[out_slot].connectedNode = in_node; + out_node->inputs[out_slot].connectedSlot = in_slot; + link->input_node = in_node; link->input_slot = in_slot; link->output_node = out_node; @@ -209,8 +213,10 @@ node_editor_init(struct node_editor *editor) memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; + + editor->outputNode = node_output_create(editor, (struct nk_vec2){600, 400}); + node_color_create(editor, (struct nk_vec2){40, 10}); - node_output_create(editor, (struct nk_vec2){200, 200}); editor->show_grid = nk_true; } diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 62df8d653..6fc674d88 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -4,46 +4,37 @@ struct node_type_color { struct nk_colorf outputVal; }; -/* -static void* node_color_get(struct node* self, int oIndex) +static struct nk_colorf *node_color_eval(struct node* node, int oIndex) { - struct node_type_color *node = ((struct node_type_color*)self); - for (int i = 0; i < self->input_count; i++) - { - if (self->inputs[i].isConnected) - { - /* - call getter func of connected node and assign to ((node_type_color*)self)->inputVal[i] - *//* - } - } - node->outputVal->r = node->inputVal[0]; - node->outputVal->g = node->inputVal[1]; - node->outputVal->b = node->inputVal[2]; - node->outputVal->a = node->inputVal[3]; + NK_ASSERT(oIndex == 0); /* only one output node */ + struct node_type_color *colornode = (struct node_type_color*)node; - struct nk_colorf *returnpointer = ((struct node_type_color*)self)->outputVal; - return (void*) returnpointer; -}*/ + return &colornode->outputVal; +} static void node_color_draw(struct nk_context *ctx, struct node *node) { struct node_type_color *colornode = (struct node_type_color*)node; + float evalResult; /* Get the values from connected nodes into this so the inputs revert on disconnect */ + char* labels[4] = {"#R:","#G:","B:","A:"}; + float colorVals[4]; /* Because we can't just loop through the struct... */ nk_layout_row_dynamic(ctx, 25, 1); - nk_button_color(ctx, nk_rgba_f(colornode->inputVal[0],colornode->inputVal[1],colornode->inputVal[2],colornode->inputVal[3])); - colornode->inputVal[0] = colornode->node.inputs[0].isConnected ? - nk_propertyf(ctx, "#R:", colornode->inputVal[0], colornode->inputVal[0], colornode->inputVal[0], 0.05f, 0.05f) : - nk_propertyf(ctx, "#R:", 0.0f, colornode->inputVal[0], 1.0f, 0.01f, 0.01f); - colornode->inputVal[1] = colornode->node.inputs[1].isConnected ? - nk_propertyf(ctx, "#G:", colornode->inputVal[1], colornode->inputVal[1], colornode->inputVal[1], 0.05f, 0.05f) : - nk_propertyf(ctx, "#G:", 0.0f, colornode->inputVal[1], 1.0f, 0.01f, 0.01f); - colornode->inputVal[2] = colornode->node.inputs[2].isConnected ? - nk_propertyf(ctx, "#B:", colornode->inputVal[2], colornode->inputVal[2], colornode->inputVal[2], 0.05f, 0.05f) : - nk_propertyf(ctx, "#B:", 0.0f, colornode->inputVal[2], 1.0f, 0.01f, 0.01f); - colornode->inputVal[3] = colornode->node.inputs[3].isConnected ? - nk_propertyf(ctx, "#A:", colornode->inputVal[3], colornode->inputVal[3], colornode->inputVal[3], 0.05f, 0.05f) : - nk_propertyf(ctx, "#A:", 0.0f, colornode->inputVal[3], 1.0f, 0.01f, 0.01f); + nk_button_color(ctx, nk_rgba_cf(colornode->outputVal)); + + for (int i = 0; i < 4; i++) { + if (colornode->node.inputs[i].isConnected) { + evalResult = *(float*)node->inputs[i].connectedNode->evalFunc(node->inputs[i].connectedNode, node->inputs[i].connectedSlot); + evalResult = nk_propertyf(ctx, labels[i], evalResult, evalResult, evalResult, 0.05f, 0.05f); + colorVals[i] = evalResult; + } + else { + colornode->inputVal[i] = nk_propertyf(ctx, labels[i], 0.0f, colornode->inputVal[i], 1.0f, 0.05f, 0.05f); + colorVals[i] = colornode->inputVal[i]; + } + } + + colornode->outputVal = (struct nk_colorf){colorVals[0],colorVals[1],colorVals[2],colorVals[3]}; } void node_color_create(struct node_editor *editor, struct nk_vec2 position) @@ -66,4 +57,5 @@ void node_color_create(struct node_editor *editor, struct nk_vec2 position) colornode->outputVal = (struct nk_colorf){1.0f, 1.0f, 1.0f, 1.0f}; colornode->node.displayFunc = node_color_draw; + colornode->node.evalFunc = node_color_eval; } diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c index facc2caad..6cb8fcb9d 100644 --- a/demo/common/nodeeditor/node_type_float.c +++ b/demo/common/nodeeditor/node_type_float.c @@ -3,6 +3,12 @@ struct node_type_float { float outputVal; }; +static float *node_float_eval(struct node* node, int oIndex) { + NK_ASSERT(oIndex == 0); + struct node_type_float *floatnode = (struct node_type_float*)node; + return &floatnode->outputVal; +} + static void node_float_draw(struct nk_context *ctx, struct node *node) { struct node_type_float *floatnode = (struct node_type_float*)node; nk_layout_row_dynamic(ctx, 25, 1); @@ -14,4 +20,5 @@ void node_float_create(struct node_editor *editor, struct nk_vec2 position) { floatnode->outputVal = 1.0f; floatnode->node.displayFunc = node_float_draw; + floatnode->node.evalFunc = node_float_eval; } \ No newline at end of file diff --git a/demo/common/nodeeditor/node_type_output.c b/demo/common/nodeeditor/node_type_output.c index e4a13ddc7..5a3ac94fd 100644 --- a/demo/common/nodeeditor/node_type_output.c +++ b/demo/common/nodeeditor/node_type_output.c @@ -1,15 +1,20 @@ struct node_type_output { struct node node; - struct nk_color inputVal; + struct nk_colorf inputVal; }; static void node_output_display(struct nk_context *ctx, struct node *node) { - + if (node->inputs[0].isConnected) { + struct nk_colorf inputVal = *(struct nk_colorf*)(node->inputs[0].connectedNode->evalFunc(node->inputs[0].connectedNode, node->inputs[0].connectedSlot)); + nk_layout_row_dynamic(ctx, 25, 1); + nk_button_color(ctx, nk_rgba_cf(inputVal)); + } } -void node_output_create(struct node_editor *editor, struct nk_vec2 position) { +struct node* node_output_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_output *outputNode = (struct node_type_output*)node_editor_add(editor, sizeof(struct node_type_output), "Output", nk_rect(position.x, position.y, 100, 100), 1, 0); outputNode->node.inputs[0].type = fColor; outputNode->node.displayFunc = node_output_display; + return outputNode; } \ No newline at end of file From 4c8c3e3fa03d41ce98f70eaaa3e03e9eeee2198f Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Mon, 24 Apr 2023 11:26:38 +0300 Subject: [PATCH 13/28] Comment clean up + add node_editor_eval_connected & node_output_get --- demo/common/node_editor.c | 41 +++++++++++------------ demo/common/nodeeditor/node_type_color.c | 10 +++--- demo/common/nodeeditor/node_type_float.c | 6 ++-- demo/common/nodeeditor/node_type_output.c | 14 ++++++-- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 75306ab11..8b55cacb8 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -27,17 +27,16 @@ struct node { int ID; char name[32]; struct nk_rect bounds; - /* enum node_type type; */ int input_count; int output_count; - struct node_connector *inputs; /* These could be made into arrays to get rid of the allocation at node creation. */ - struct node_connector *outputs; /* For this demo we probably only need a max of four inputs and one output. */ + struct node_connector *inputs; + struct node_connector *outputs; struct { float in_top; float in_space; float out_top; float out_space; - } slot_spacing; /* not sure what to call this really... */ + } slot_spacing; /* Maybe this should be called "node_layout" and include the bounds? */ struct node *next; /* Z ordering only */ struct node *prev; /* Z ordering only */ @@ -51,8 +50,6 @@ struct node_link { struct node* output_node; int output_slot; nk_bool isActive; - /* struct nk_vec2 in; - struct nk_vec2 out; */ }; struct node_linking { @@ -80,13 +77,12 @@ struct node_editor { static struct node_editor nodeEditor; /* === PROTOTYPES === */ - -static struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, +/* These should go in a header file along with the node struct */ +struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count); - +void* node_editor_eval_connected(struct node *node, int inputSlot); /* ================== */ - #include "nodeeditor/node_type_color.c" #include "nodeeditor/node_type_float.c" #include "nodeeditor/node_type_output.c" @@ -150,15 +146,15 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ return NULL; } -static struct node* +struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count) { - static int IDs = 0; /* static duration */ + static int IDs = 0; NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); struct node *node = malloc(nodeSize); - editor->node_buf[editor->node_count++] = node; /* next node in buffer */ - node->ID = IDs++; /* increment IDs and set as node ID */ + editor->node_buf[editor->node_count++] = node; + node->ID = IDs++; node->bounds = bounds; @@ -170,11 +166,11 @@ int in_count, int out_count) for (int i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; - node->inputs[i].type = fValue; + node->inputs[i].type = fValue; /* default connector type */ } for (i = 0; i < node->output_count; i++) { node->outputs[i].isConnected = nk_false; - node->outputs[i].type = fValue; + node->outputs[i].type = fValue; /* default connector type */ } /* default connector spacing */ @@ -187,6 +183,12 @@ int in_count, int out_count) return node; } +void * +node_editor_eval_connected(struct node* node, int inputSlot) { + NK_ASSERT(node->inputs[inputSlot].isConnected); + return node->inputs[inputSlot].connectedNode->evalFunc(node->inputs[inputSlot].connectedNode, node->inputs[inputSlot].connectedSlot); +} + static void node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, struct node *out_node, int out_slot) @@ -381,8 +383,8 @@ node_editor_main(struct nk_context *ctx) for (n = 0; n < nodedit->link_count; ++n) { struct node_link *link = &nodedit->links[n]; if (link->isActive == nk_true){ - struct node *ni = link->input_node;//node_editor_find(nodedit, link->input_id); - struct node *no = link->output_node;//node_editor_find(nodedit, link->output_id); + struct node *ni = link->input_node; + struct node *no = link->output_node; struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + ni->slot_spacing.out_top + ni->slot_spacing.out_space * (float)(link->input_slot))); struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, @@ -422,9 +424,6 @@ node_editor_main(struct nk_context *ctx) if (nk_contextual_begin(ctx, 0, nk_vec2(150, 220), nk_window_get_bounds(ctx))) { const char *grid_option[] = {"Show Grid", "Hide Grid"}; nk_layout_row_dynamic(ctx, 25, 1); - /* if (nk_contextual_item_label(ctx, "New", NK_TEXT_CENTERED)) - node_editor_add(nodedit, "New", nk_rect(in->mouse.pos.x, in->mouse.pos.y, 180, 220), - nk_rgb(255, 255, 255), 1, 2); */ if (nk_contextual_item_label(ctx, "Add Color node", NK_TEXT_CENTERED)) node_color_create(nodedit, in->mouse.pos); if (nk_contextual_item_label(ctx, "Add Float node", NK_TEXT_CENTERED)) diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 6fc674d88..5349cfe70 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -6,7 +6,7 @@ struct node_type_color { static struct nk_colorf *node_color_eval(struct node* node, int oIndex) { - NK_ASSERT(oIndex == 0); /* only one output node */ + NK_ASSERT(oIndex == 0); /* only one output connector */ struct node_type_color *colornode = (struct node_type_color*)node; return &colornode->outputVal; @@ -24,12 +24,12 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) for (int i = 0; i < 4; i++) { if (colornode->node.inputs[i].isConnected) { - evalResult = *(float*)node->inputs[i].connectedNode->evalFunc(node->inputs[i].connectedNode, node->inputs[i].connectedSlot); - evalResult = nk_propertyf(ctx, labels[i], evalResult, evalResult, evalResult, 0.05f, 0.05f); + evalResult = *(float*)node_editor_eval_connected(node, i); + evalResult = nk_propertyf(ctx, labels[i], evalResult, evalResult, evalResult, 0.01f, 0.01f); colorVals[i] = evalResult; } else { - colornode->inputVal[i] = nk_propertyf(ctx, labels[i], 0.0f, colornode->inputVal[i], 1.0f, 0.05f, 0.05f); + colornode->inputVal[i] = nk_propertyf(ctx, labels[i], 0.0f, colornode->inputVal[i], 1.0f, 0.01f, 0.01f); colorVals[i] = colornode->inputVal[i]; } } @@ -39,7 +39,7 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) void node_color_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_color *colornode = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 220), 4, 1); + struct node_type_color *colornode = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 190), 4, 1); colornode->node.slot_spacing.in_top = 72.0f; colornode->node.slot_spacing.in_space = 29.0f; colornode->node.slot_spacing.out_top = 42.0f; diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c index 6cb8fcb9d..008b3a0ca 100644 --- a/demo/common/nodeeditor/node_type_float.c +++ b/demo/common/nodeeditor/node_type_float.c @@ -1,3 +1,5 @@ +#include + struct node_type_float { struct node node; float outputVal; @@ -12,11 +14,11 @@ static float *node_float_eval(struct node* node, int oIndex) { static void node_float_draw(struct nk_context *ctx, struct node *node) { struct node_type_float *floatnode = (struct node_type_float*)node; nk_layout_row_dynamic(ctx, 25, 1); - floatnode->outputVal = nk_propertyf(ctx, "#Value:", 0.0f, floatnode->outputVal, 1.0f, 0.01f, 0.01f); + floatnode->outputVal = nk_propertyf(ctx, "#Value:", -FLT_MAX, floatnode->outputVal, FLT_MAX, 0.01f, 0.01f); } void node_float_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_float *floatnode = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 100), 0, 1); + struct node_type_float *floatnode = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 75), 0, 1); floatnode->outputVal = 1.0f; floatnode->node.displayFunc = node_float_draw; diff --git a/demo/common/nodeeditor/node_type_output.c b/demo/common/nodeeditor/node_type_output.c index 5a3ac94fd..f4bdf36ef 100644 --- a/demo/common/nodeeditor/node_type_output.c +++ b/demo/common/nodeeditor/node_type_output.c @@ -3,11 +3,19 @@ struct node_type_output { struct nk_colorf inputVal; }; +struct nk_colorf *node_output_get(struct node* node) { + struct node_type_output *outputnode = (struct node_type_output*)node; + if (!node->inputs[0].isConnected) + outputnode->inputVal = (struct nk_colorf){0.0f, 0.0f, 0.0f, 0.0f}; + return &outputnode->inputVal; +} + static void node_output_display(struct nk_context *ctx, struct node *node) { if (node->inputs[0].isConnected) { - struct nk_colorf inputVal = *(struct nk_colorf*)(node->inputs[0].connectedNode->evalFunc(node->inputs[0].connectedNode, node->inputs[0].connectedSlot)); - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_color(ctx, nk_rgba_cf(inputVal)); + struct node_type_output *outputnode = (struct node_type_output*)node; + outputnode->inputVal = *(struct nk_colorf*)node_editor_eval_connected(node, 0); + nk_layout_row_dynamic(ctx, 60, 1); + nk_button_color(ctx, nk_rgba_cf(outputnode->inputVal)); } } From e6a82fe454170aa3f4e02841c309e439036efdab Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 26 Apr 2023 12:17:59 +0300 Subject: [PATCH 14/28] Node deletion --- demo/common/node_editor.c | 66 +++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 8b55cacb8..3991db796 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -146,6 +146,21 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ return NULL; } +static struct node_link* +node_editor_find_link_by_input(struct node_editor *editor, struct node *input_node, int node_output_connector) +{ + for (int i = 0; i < editor->link_count; i++) + { + if (editor->links[i].input_node == input_node && + editor->links[i].input_slot == node_output_connector && + editor->links[i].isActive == nk_true) + { + return &editor->links[i]; + } + } + return NULL; +} + struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count) @@ -267,8 +282,12 @@ node_editor_main(struct nk_context *ctx) nk_layout_space_push(ctx, nk_rect(it->bounds.x - nodedit->scrolling.x, it->bounds.y - nodedit->scrolling.y, it->bounds.w, it->bounds.h)); + /* Output node window should not have a close button */ + nk_flags nodePanel_flags = NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE; + if (it != nodeEditor.outputNode) nodePanel_flags |= NK_WINDOW_CLOSABLE; + /* execute node window */ - if (nk_group_begin(ctx, it->name, NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE)) + if (nk_group_begin(ctx, it->name, nodePanel_flags)) { /* always have last selected node on top */ @@ -281,12 +300,43 @@ node_editor_main(struct nk_context *ctx) updated = it; } - /* ================= NODE CONTENT ===================== */ - it->displayFunc(ctx, it); - /* ==================================================== */ - + if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) { /* Node close button has not been clicked */ + /* ================= NODE CONTENT ===================== */ + it->displayFunc(ctx, it); + /* ==================================================== */ + } + else { + /* Delete node */ + node_editor_pop(nodedit, it); + struct node_link *link_remove; + for (n = 0; n < it->input_count; n++) + { + if ((link_remove = node_editor_find_link_by_output(nodedit, it, n))) + { + link_remove->isActive = nk_false; + link_remove->input_node->outputs[link_remove->input_slot].isConnected = nk_false; + link_remove->output_node->inputs[link_remove->output_slot].isConnected = nk_false; + } + } + for (n = 0; n < it -> output_count; n++) + { + while((link_remove = node_editor_find_link_by_input(nodedit, it, n))) + { + link_remove->isActive = nk_false; + link_remove->input_node->outputs[link_remove->input_slot].isConnected = nk_false; + link_remove->output_node->inputs[link_remove->output_slot].isConnected = nk_false; + } + } + NK_ASSERT(nodedit->node_buf[it->ID] == it); + nodedit->node_buf[it->ID] = 0; + free(it->inputs); + free(it->outputs); + free(it); + } + nk_group_end(ctx); } + if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) { /* node connector and linking */ struct nk_rect bounds; @@ -295,9 +345,7 @@ node_editor_main(struct nk_context *ctx) bounds.y += nodedit->scrolling.y; it->bounds = bounds; - /* output connector */ - - /* (loop through outputs) */ + /* output connectors */ for (n = 0; n < it->output_count; ++n) { struct nk_rect circle; struct nk_color color; @@ -329,7 +377,7 @@ node_editor_main(struct nk_context *ctx) } } - /* input connector */ + /* input connectors */ for (n = 0; n < it->input_count; ++n) { struct nk_rect circle; struct nk_color color; From 9e9310c53ba25339bc9946d3e0c11aeb5dc3ced4 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Tue, 2 May 2023 08:33:35 +0300 Subject: [PATCH 15/28] node_editor_delete_link + C89 compliance --- demo/common/node_editor.c | 80 ++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 3991db796..82e65c539 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -77,7 +77,7 @@ struct node_editor { static struct node_editor nodeEditor; /* === PROTOTYPES === */ -/* These should go in a header file along with the node struct */ +/* These could/should go in a header file along with the node and node_connector structs and be #included with every node type */ struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count); void* node_editor_eval_connected(struct node *node, int inputSlot); @@ -134,7 +134,8 @@ node_editor_find(struct node_editor *editor, int ID) static struct node_link* node_editor_find_link_by_output(struct node_editor *editor, struct node *output_node, int node_input_connector) { - for (int i = 0; i < editor->link_count; i++) + int i; + for (i = 0; i < editor->link_count; i++) { if (editor->links[i].output_node == output_node && editor->links[i].output_slot == node_input_connector && @@ -149,7 +150,8 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ static struct node_link* node_editor_find_link_by_input(struct node_editor *editor, struct node *input_node, int node_output_connector) { - for (int i = 0; i < editor->link_count; i++) + int i; + for (i = 0; i < editor->link_count; i++) { if (editor->links[i].input_node == input_node && editor->links[i].input_slot == node_output_connector && @@ -161,15 +163,43 @@ node_editor_find_link_by_input(struct node_editor *editor, struct node *input_no return NULL; } +static void +node_editor_delete_link(struct node_link *link) +{ + link->isActive = nk_false; + link->input_node->outputs[link->input_slot].isConnected = nk_false; + link->output_node->inputs[link->output_slot].isConnected = nk_false; +} + struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count) { + int i; static int IDs = 0; - NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); - struct node *node = malloc(nodeSize); - editor->node_buf[editor->node_count++] = node; - node->ID = IDs++; + struct node *node = NULL; + /* NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); */ + if ((nk_size)editor->node_count < NK_LEN(editor->node_buf)) + { + node = malloc(nodeSize); + editor->node_buf[editor->node_count++] = node; + node->ID = IDs++; + } + else { + for (i = 0; i < editor->node_count; i++) + { + if (editor->node_buf[i] == NULL) { + node = malloc(nodeSize); + editor->node_buf[i] = node; + node->ID = i; + break; + } + } + } + if (node == NULL) { + printf("Node creation failed\n"); + return NULL; + } node->bounds = bounds; @@ -179,7 +209,7 @@ int in_count, int out_count) node->inputs = malloc(node->input_count * sizeof(struct node_connector)); node->outputs = malloc(node->output_count * sizeof(struct node_connector)); - for (int i = 0; i < node->input_count; i++) { + for (i = 0; i < node->input_count; i++) { node->inputs[i].isConnected = nk_false; node->inputs[i].type = fValue; /* default connector type */ } @@ -227,13 +257,14 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, static void node_editor_init(struct node_editor *editor) { + struct nk_vec2 outputNode_position = {600, 400}; + struct nk_vec2 colorNode_position = {40, 10}; memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; - editor->outputNode = node_output_create(editor, (struct nk_vec2){600, 400}); - - node_color_create(editor, (struct nk_vec2){40, 10}); + editor->outputNode = node_output_create(editor, outputNode_position); + node_color_create(editor, colorNode_position); editor->show_grid = nk_true; } @@ -278,14 +309,15 @@ node_editor_main(struct nk_context *ctx) /* execute each node as a movable group */ /* (loop through nodes) */ while (it) { + /* Output node window should not have a close button */ + nk_flags nodePanel_flags = NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE; + if (it != nodeEditor.outputNode) + nodePanel_flags |= NK_WINDOW_CLOSABLE; + /* calculate scrolled node window position and size */ nk_layout_space_push(ctx, nk_rect(it->bounds.x - nodedit->scrolling.x, it->bounds.y - nodedit->scrolling.y, it->bounds.w, it->bounds.h)); - /* Output node window should not have a close button */ - nk_flags nodePanel_flags = NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE; - if (it != nodeEditor.outputNode) nodePanel_flags |= NK_WINDOW_CLOSABLE; - /* execute node window */ if (nk_group_begin(ctx, it->name, nodePanel_flags)) { @@ -307,28 +339,24 @@ node_editor_main(struct nk_context *ctx) } else { /* Delete node */ - node_editor_pop(nodedit, it); struct node_link *link_remove; + node_editor_pop(nodedit, it); for (n = 0; n < it->input_count; n++) { if ((link_remove = node_editor_find_link_by_output(nodedit, it, n))) { - link_remove->isActive = nk_false; - link_remove->input_node->outputs[link_remove->input_slot].isConnected = nk_false; - link_remove->output_node->inputs[link_remove->output_slot].isConnected = nk_false; + node_editor_delete_link(link_remove); } } for (n = 0; n < it -> output_count; n++) { while((link_remove = node_editor_find_link_by_input(nodedit, it, n))) { - link_remove->isActive = nk_false; - link_remove->input_node->outputs[link_remove->input_slot].isConnected = nk_false; - link_remove->output_node->inputs[link_remove->output_slot].isConnected = nk_false; + node_editor_delete_link(link_remove); } } NK_ASSERT(nodedit->node_buf[it->ID] == it); - nodedit->node_buf[it->ID] = 0; + nodedit->node_buf[it->ID] = NULL; free(it->inputs); free(it->outputs); free(it); @@ -393,14 +421,12 @@ node_editor_main(struct nk_context *ctx) if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true) && nodedit->linking.active == nk_false && it->inputs[n].isConnected == nk_true) { - nodedit->linking.active = nk_true; struct node_link *node_relink = node_editor_find_link_by_output(nodedit, it, n); + nodedit->linking.active = nk_true; nodedit->linking.node = node_relink->input_node; nodedit->linking.input_id = node_relink->input_node->ID; nodedit->linking.input_slot = node_relink->input_slot; - node_relink->isActive = nk_false; - it->inputs[n].isConnected = nk_false; - node_relink->input_node->inputs[node_relink->input_slot].isConnected = nk_false; + node_editor_delete_link(node_relink); } /* (Create link) */ From dc4e3f1cf435398c93788a665f95acceaf65ba0c Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Tue, 2 May 2023 08:33:58 +0300 Subject: [PATCH 16/28] Clean up warnings + C89 compliance --- demo/common/nodeeditor/node_type_color.c | 47 ++++++++++++++--------- demo/common/nodeeditor/node_type_float.c | 14 ++++--- demo/common/nodeeditor/node_type_output.c | 17 ++++---- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 5349cfe70..3012e3187 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -6,8 +6,8 @@ struct node_type_color { static struct nk_colorf *node_color_eval(struct node* node, int oIndex) { - NK_ASSERT(oIndex == 0); /* only one output connector */ struct node_type_color *colornode = (struct node_type_color*)node; + NK_ASSERT(oIndex == 0); /* only one output connector */ return &colornode->outputVal; } @@ -19,10 +19,11 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) float evalResult; /* Get the values from connected nodes into this so the inputs revert on disconnect */ char* labels[4] = {"#R:","#G:","B:","A:"}; float colorVals[4]; /* Because we can't just loop through the struct... */ + int i; nk_layout_row_dynamic(ctx, 25, 1); nk_button_color(ctx, nk_rgba_cf(colornode->outputVal)); - for (int i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { if (colornode->node.inputs[i].isConnected) { evalResult = *(float*)node_editor_eval_connected(node, i); evalResult = nk_propertyf(ctx, labels[i], evalResult, evalResult, evalResult, 0.01f, 0.01f); @@ -34,28 +35,36 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) } } - colornode->outputVal = (struct nk_colorf){colorVals[0],colorVals[1],colorVals[2],colorVals[3]}; + colornode->outputVal.r = colorVals[0]; + colornode->outputVal.g = colorVals[1]; + colornode->outputVal.b = colorVals[2]; + colornode->outputVal.a = colorVals[3]; } void node_color_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_color *colornode = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 190), 4, 1); - colornode->node.slot_spacing.in_top = 72.0f; - colornode->node.slot_spacing.in_space = 29.0f; - colornode->node.slot_spacing.out_top = 42.0f; - colornode->node.slot_spacing.out_space = 0.0f; - - for (int i = 0; i < colornode->node.input_count; i++) - colornode->node.inputs[i].type = fValue; - colornode->node.outputs[0].type = fColor; - - colornode->inputVal[0] = - colornode->inputVal[1] = - colornode->inputVal[2] = - colornode->inputVal[3] = 1.0f; + if (colornode) + { + int i; + struct nk_colorf white = {1.0f, 1.0f, 1.0f, 1.0f}; + colornode->node.slot_spacing.in_top = 72.0f; + colornode->node.slot_spacing.in_space = 29.0f; + colornode->node.slot_spacing.out_top = 42.0f; + colornode->node.slot_spacing.out_space = 0.0f; - colornode->outputVal = (struct nk_colorf){1.0f, 1.0f, 1.0f, 1.0f}; + for (i = 0; i < colornode->node.input_count; i++) + colornode->node.inputs[i].type = fValue; + colornode->node.outputs[0].type = fColor; + + colornode->inputVal[0] = + colornode->inputVal[1] = + colornode->inputVal[2] = + colornode->inputVal[3] = 1.0f; - colornode->node.displayFunc = node_color_draw; - colornode->node.evalFunc = node_color_eval; + colornode->outputVal = white; + + colornode->node.displayFunc = node_color_draw; + colornode->node.evalFunc = (void*(*)(struct node*, int)) node_color_eval; + } } diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c index 008b3a0ca..54d1a06e7 100644 --- a/demo/common/nodeeditor/node_type_float.c +++ b/demo/common/nodeeditor/node_type_float.c @@ -6,8 +6,8 @@ struct node_type_float { }; static float *node_float_eval(struct node* node, int oIndex) { - NK_ASSERT(oIndex == 0); struct node_type_float *floatnode = (struct node_type_float*)node; + NK_ASSERT(oIndex == 0); return &floatnode->outputVal; } @@ -19,8 +19,10 @@ static void node_float_draw(struct nk_context *ctx, struct node *node) { void node_float_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_float *floatnode = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 75), 0, 1); - - floatnode->outputVal = 1.0f; - floatnode->node.displayFunc = node_float_draw; - floatnode->node.evalFunc = node_float_eval; -} \ No newline at end of file + if (floatnode) + { + floatnode->outputVal = 1.0f; + floatnode->node.displayFunc = node_float_draw; + floatnode->node.evalFunc = (void*(*)(struct node*, int)) node_float_eval; + } +} diff --git a/demo/common/nodeeditor/node_type_output.c b/demo/common/nodeeditor/node_type_output.c index f4bdf36ef..5ba792c99 100644 --- a/demo/common/nodeeditor/node_type_output.c +++ b/demo/common/nodeeditor/node_type_output.c @@ -5,8 +5,10 @@ struct node_type_output { struct nk_colorf *node_output_get(struct node* node) { struct node_type_output *outputnode = (struct node_type_output*)node; - if (!node->inputs[0].isConnected) - outputnode->inputVal = (struct nk_colorf){0.0f, 0.0f, 0.0f, 0.0f}; + if (!node->inputs[0].isConnected) { + struct nk_colorf black = {0.0f, 0.0f, 0.0f, 0.0f}; + outputnode->inputVal = black; + } return &outputnode->inputVal; } @@ -21,8 +23,9 @@ static void node_output_display(struct nk_context *ctx, struct node *node) { struct node* node_output_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_output *outputNode = (struct node_type_output*)node_editor_add(editor, sizeof(struct node_type_output), "Output", nk_rect(position.x, position.y, 100, 100), 1, 0); - - outputNode->node.inputs[0].type = fColor; - outputNode->node.displayFunc = node_output_display; - return outputNode; -} \ No newline at end of file + if (outputNode){ + outputNode->node.inputs[0].type = fColor; + outputNode->node.displayFunc = node_output_display; + } + return (struct node*)outputNode; +} From fb9d7d6c05c1ab8b5a29bde9dfe13afa1472ae43 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Tue, 2 May 2023 09:23:05 +0300 Subject: [PATCH 17/28] Link buffer reuse / "memory management" --- demo/common/node_editor.c | 43 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 82e65c539..94a8474d3 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -178,7 +178,7 @@ int in_count, int out_count) int i; static int IDs = 0; struct node *node = NULL; - /* NK_ASSERT((nk_size)editor->node_count < NK_LEN(editor->node_buf)); */ + if ((nk_size)editor->node_count < NK_LEN(editor->node_buf)) { node = malloc(nodeSize); @@ -197,7 +197,7 @@ int in_count, int out_count) } } if (node == NULL) { - printf("Node creation failed\n"); + fprintf(stdout, "Node creation failed\n"); return NULL; } @@ -239,19 +239,34 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, struct node *out_node, int out_slot) { /* Confusingly, in and out nodes/slots here refer to the inputs and outputs OF THE LINK ITSELF, not the nodes */ - struct node_link *link; - NK_ASSERT((nk_size)editor->link_count < NK_LEN(editor->links)); - link = &editor->links[editor->link_count++]; - out_node->inputs[out_slot].isConnected = nk_true; - in_node->outputs[in_slot].isConnected = nk_true; - out_node->inputs[out_slot].connectedNode = in_node; - out_node->inputs[out_slot].connectedSlot = in_slot; + struct node_link *link = NULL; - link->input_node = in_node; - link->input_slot = in_slot; - link->output_node = out_node; - link->output_slot = out_slot; - link->isActive = nk_true; + if ((nk_size)editor->link_count < NK_LEN(editor->links)) + link = &editor->links[editor->link_count++]; + else { + int i; + for (i = 0; i < (int)NK_LEN(editor->links); i++) + { + if (editor->links[i].isActive == nk_false) { + link = &editor->links[i]; + break; + } + } + } + if (link) { + out_node->inputs[out_slot].isConnected = nk_true; + in_node->outputs[in_slot].isConnected = nk_true; + out_node->inputs[out_slot].connectedNode = in_node; + out_node->inputs[out_slot].connectedSlot = in_slot; + + link->input_node = in_node; + link->input_slot = in_slot; + link->output_node = out_node; + link->output_slot = out_slot; + link->isActive = nk_true; + } + else + fprintf(stdout, "Too many links\n"); } static void From 593a51fe8e58045f68f07aed55ddc12d4fa83e4c Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 3 May 2023 08:40:05 +0300 Subject: [PATCH 18/28] Bug fix --- demo/common/nodeeditor/node_type_color.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 3012e3187..305a92ba5 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -17,7 +17,7 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) { struct node_type_color *colornode = (struct node_type_color*)node; float evalResult; /* Get the values from connected nodes into this so the inputs revert on disconnect */ - char* labels[4] = {"#R:","#G:","B:","A:"}; + const char* labels[4] = {"#R:","#G:","#B:","#A:"}; float colorVals[4]; /* Because we can't just loop through the struct... */ int i; nk_layout_row_dynamic(ctx, 25, 1); @@ -47,7 +47,8 @@ void node_color_create(struct node_editor *editor, struct nk_vec2 position) if (colornode) { int i; - struct nk_colorf white = {1.0f, 1.0f, 1.0f, 1.0f}; + const struct nk_colorf white = {1.0f, 1.0f, 1.0f, 1.0f}; + colornode->node.slot_spacing.in_top = 72.0f; colornode->node.slot_spacing.in_space = 29.0f; colornode->node.slot_spacing.out_top = 42.0f; From a27fba8cb677b1a17a377b3a101c309f5b95648c Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 3 May 2023 08:41:16 +0300 Subject: [PATCH 19/28] Made float node min/max 0.0/1.0 for simplicity --- demo/common/nodeeditor/node_type_float.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c index 54d1a06e7..469197d22 100644 --- a/demo/common/nodeeditor/node_type_float.c +++ b/demo/common/nodeeditor/node_type_float.c @@ -1,5 +1,3 @@ -#include - struct node_type_float { struct node node; float outputVal; @@ -14,7 +12,7 @@ static float *node_float_eval(struct node* node, int oIndex) { static void node_float_draw(struct nk_context *ctx, struct node *node) { struct node_type_float *floatnode = (struct node_type_float*)node; nk_layout_row_dynamic(ctx, 25, 1); - floatnode->outputVal = nk_propertyf(ctx, "#Value:", -FLT_MAX, floatnode->outputVal, FLT_MAX, 0.01f, 0.01f); + floatnode->outputVal = nk_propertyf(ctx, "#Value:", 0.0f, floatnode->outputVal, 1.0f, 0.01f, 0.01f); } void node_float_create(struct node_editor *editor, struct nk_vec2 position) { From 151ed01f6905f6f3eebf96b793ee8a7e99bc42a6 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 3 May 2023 08:52:53 +0300 Subject: [PATCH 20/28] Blend nodes added --- demo/common/node_editor.c | 12 +++- demo/common/nodeeditor/node_type_blend.c | 73 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 demo/common/nodeeditor/node_type_blend.c diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 94a8474d3..57eb66e24 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -86,6 +86,7 @@ void* node_editor_eval_connected(struct node *node, int inputSlot); #include "nodeeditor/node_type_color.c" #include "nodeeditor/node_type_float.c" #include "nodeeditor/node_type_output.c" +#include "nodeeditor/node_type_blend.c" static void node_editor_push(struct node_editor *editor, struct node *node) @@ -180,12 +181,14 @@ int in_count, int out_count) struct node *node = NULL; if ((nk_size)editor->node_count < NK_LEN(editor->node_buf)) - { + { + /* node_buf has unused slots */ node = malloc(nodeSize); editor->node_buf[editor->node_count++] = node; node->ID = IDs++; } else { + /* check for freed up slots in node_buf */ for (i = 0; i < editor->node_count; i++) { if (editor->node_buf[i] == NULL) { @@ -229,7 +232,8 @@ int in_count, int out_count) } void * -node_editor_eval_connected(struct node* node, int inputSlot) { +node_editor_eval_connected(struct node* node, int inputSlot) +{ NK_ASSERT(node->inputs[inputSlot].isConnected); return node->inputs[inputSlot].connectedNode->evalFunc(node->inputs[inputSlot].connectedNode, node->inputs[inputSlot].connectedSlot); } @@ -240,7 +244,7 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, { /* Confusingly, in and out nodes/slots here refer to the inputs and outputs OF THE LINK ITSELF, not the nodes */ struct node_link *link = NULL; - + if ((nk_size)editor->link_count < NK_LEN(editor->links)) link = &editor->links[editor->link_count++]; else { @@ -517,6 +521,8 @@ node_editor_main(struct nk_context *ctx) node_color_create(nodedit, in->mouse.pos); if (nk_contextual_item_label(ctx, "Add Float node", NK_TEXT_CENTERED)) node_float_create(nodedit, in->mouse.pos); + if (nk_contextual_item_label(ctx, "Add Blend Node", NK_TEXT_CENTERED)) + node_blend_create(nodedit, in->mouse.pos); if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) nodedit->show_grid = !nodedit->show_grid; nk_contextual_end(ctx); diff --git a/demo/common/nodeeditor/node_type_blend.c b/demo/common/nodeeditor/node_type_blend.c new file mode 100644 index 000000000..f46242d0b --- /dev/null +++ b/demo/common/nodeeditor/node_type_blend.c @@ -0,0 +1,73 @@ +struct node_type_blend { + struct node node; + struct nk_colorf inputVal[2]; + struct nk_colorf outputVal; + float blendVal; +}; + +static struct nk_colorf *node_blend_eval(struct node *node, int oIndex) { + struct node_type_blend* blendNode = (struct node_type_blend*)node; + return &blendNode->outputVal; +} + +static void node_blend_display(struct nk_context *ctx, struct node *node) { + struct node_type_blend *blendNode = (struct node_type_blend*)node; + const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; + float blendAmnt; + int i; + + nk_layout_row_dynamic(ctx, 25, 1); + for (i = 0; i < (int)NK_LEN(blendNode->inputVal); i++){ + if(node->inputs[i].isConnected) { + blendNode->inputVal[i] = *(struct nk_colorf*)node_editor_eval_connected(node, i); + } + else { + blendNode->inputVal[i] = blank; + } + nk_button_color(ctx, nk_rgba_cf(blendNode->inputVal[i])); + } + + if (node->inputs[2].isConnected) { + blendAmnt = *(float*)node_editor_eval_connected(node, 2); + blendAmnt = nk_propertyf(ctx, "#Blend", blendAmnt, blendAmnt, blendAmnt, 0.01f, 0.01f); + } + else { + blendNode->blendVal = nk_propertyf(ctx, "#Blend", 0.0f, blendNode->blendVal, 1.0f, 0.01f, 0.01f); + blendAmnt = blendNode->blendVal; + } + + + if(node->inputs[0].isConnected && node->inputs[1].isConnected) { + blendNode->outputVal.r = blendNode->inputVal[0].r * blendAmnt + blendNode->inputVal[1].r * (1.0f-blendAmnt); + blendNode->outputVal.g = blendNode->inputVal[0].g * blendAmnt + blendNode->inputVal[1].g * (1.0f-blendAmnt); + blendNode->outputVal.b = blendNode->inputVal[0].b * blendAmnt + blendNode->inputVal[1].b * (1.0f-blendAmnt); + blendNode->outputVal.a = blendNode->inputVal[0].a * blendAmnt + blendNode->inputVal[1].a * (1.0f-blendAmnt); + } + else { + blendNode->outputVal = blank; + } +} + +void node_blend_create(struct node_editor *editor, struct nk_vec2 position) { + struct node_type_blend* blendNode = (struct node_type_blend*)node_editor_add(editor, sizeof(struct node_type_blend), "Blend", nk_rect(position.x, position.y, 180, 130), 3, 1); + if (blendNode) { + const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; + int i; + for (i = 0; i < (int)NK_LEN(blendNode->inputVal); i++) + blendNode->node.inputs[i].type = fColor; + blendNode->node.outputs[0].type = fColor; + + blendNode->node.slot_spacing.in_top = 42.0f; + blendNode->node.slot_spacing.in_space = 29.0f; + + for (i = 0; i < (int)NK_LEN(blendNode->inputVal); i++) + blendNode->inputVal[i] = blank; + blendNode->outputVal = blank; + + blendNode->blendVal = 0.5f; + + blendNode->node.displayFunc = node_blend_display; + blendNode->node.evalFunc = (void*(*)(struct node*, int)) node_blend_eval; + + } +} From 3f6cd310f52f24a67bc4c268984a2a7e99959e33 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Sun, 28 May 2023 12:17:21 +0300 Subject: [PATCH 21/28] camelCase -> snake_case, as in the rest of Nuklear --- demo/common/node_editor.c | 227 +++++++++++----------- demo/common/nodeeditor/node_type_blend.c | 72 +++---- demo/common/nodeeditor/node_type_color.c | 71 +++---- demo/common/nodeeditor/node_type_float.c | 20 +- demo/common/nodeeditor/node_type_output.c | 28 +-- 5 files changed, 209 insertions(+), 209 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 57eb66e24..8a59ff0c7 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -1,26 +1,24 @@ -/* nuklear - v1.00 - public domain */ -/* This is a simple node editor just to show a simple implementation and that - * it is possible to achieve it with this library. While all nodes inside this - * example use a simple color modifier as content you could change them - * to have your custom content depending on the node time. - * Biggest difference to most usual implementation is that this example does - * not have connectors on the right position of the property that it links. - * This is mainly done out of laziness and could be implemented as well but - * requires calculating the position of all rows and add connectors. - * In addition adding and removing nodes is quite limited at the - * moment since it is based on a simple fixed array. If this is to be converted - * into something more serious it is probably best to extend it.*/ - - -enum node_connector_type {fValue, fColor}; -enum node_type {color, mix}; - +/* +A basic node-based UI built with Nuklear. +Builds on the node editor example included in Nuklear v1.00, with the aim of +being used as a prototype for implementing a functioning node editor. + +Features: +- Nodes of different types. Currently their implementations are #included in + the main file, but they could easily be turned into eg. a plugin system. +- Connectors/slots of different types -- currently float values and colors. +- Adding and removing nodes. +- Linking nodes, with validation (one link per input, only link similar connectors). +- Detaching and moving links. +- Evaluation of output values of connected nodes. +- Memory management based on fixed size arrays for links and node pointers +*/ struct node_connector { - enum node_connector_type type; - nk_bool isConnected; - struct node* connectedNode; - int connectedSlot; + enum {fValue, fColor} type; + nk_bool is_connected; + struct node* connected_node; + int connected_slot; }; struct node { @@ -40,8 +38,8 @@ struct node { struct node *next; /* Z ordering only */ struct node *prev; /* Z ordering only */ - void* (*evalFunc)(struct node*, int oIndex); - void (*displayFunc)(struct nk_context*, struct node*); + void* (*eval_func)(struct node*, int oIndex); + void (*display_func)(struct nk_context*, struct node*); }; struct node_link { @@ -49,7 +47,7 @@ struct node_link { int input_slot; struct node* output_node; int output_slot; - nk_bool isActive; + nk_bool is_active; }; struct node_linking { @@ -63,7 +61,7 @@ struct node_editor { int initialized; struct node *node_buf[32]; struct node_link links[64]; - struct node *outputNode; + struct node *output_node; struct node *begin; struct node *end; int node_count; @@ -74,19 +72,20 @@ struct node_editor { struct nk_vec2 scrolling; struct node_linking linking; }; -static struct node_editor nodeEditor; +static struct node_editor node_editor; /* === PROTOTYPES === */ -/* These could/should go in a header file along with the node and node_connector structs and be #included with every node type */ +/* Each type of node needs these two functions. */ +/* These could/should go in a header file along with the node and node_connector structs and be #included in the node implementations */ struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count); void* node_editor_eval_connected(struct node *node, int inputSlot); /* ================== */ -#include "nodeeditor/node_type_color.c" #include "nodeeditor/node_type_float.c" -#include "nodeeditor/node_type_output.c" +#include "nodeeditor/node_type_color.c" #include "nodeeditor/node_type_blend.c" +#include "nodeeditor/node_type_output.c" static void node_editor_push(struct node_editor *editor, struct node *node) @@ -140,7 +139,7 @@ node_editor_find_link_by_output(struct node_editor *editor, struct node *output_ { if (editor->links[i].output_node == output_node && editor->links[i].output_slot == node_input_connector && - editor->links[i].isActive == nk_true) + editor->links[i].is_active == nk_true) { return &editor->links[i]; } @@ -156,7 +155,7 @@ node_editor_find_link_by_input(struct node_editor *editor, struct node *input_no { if (editor->links[i].input_node == input_node && editor->links[i].input_slot == node_output_connector && - editor->links[i].isActive == nk_true) + editor->links[i].is_active == nk_true) { return &editor->links[i]; } @@ -167,9 +166,9 @@ node_editor_find_link_by_input(struct node_editor *editor, struct node *input_no static void node_editor_delete_link(struct node_link *link) { - link->isActive = nk_false; - link->input_node->outputs[link->input_slot].isConnected = nk_false; - link->output_node->inputs[link->output_slot].isConnected = nk_false; + link->is_active = nk_false; + link->input_node->outputs[link->input_slot].is_connected = nk_false; + link->output_node->inputs[link->output_slot].is_connected = nk_false; } struct node* @@ -213,11 +212,11 @@ int in_count, int out_count) node->outputs = malloc(node->output_count * sizeof(struct node_connector)); for (i = 0; i < node->input_count; i++) { - node->inputs[i].isConnected = nk_false; + node->inputs[i].is_connected = nk_false; node->inputs[i].type = fValue; /* default connector type */ } for (i = 0; i < node->output_count; i++) { - node->outputs[i].isConnected = nk_false; + node->outputs[i].is_connected = nk_false; node->outputs[i].type = fValue; /* default connector type */ } @@ -234,8 +233,8 @@ int in_count, int out_count) void * node_editor_eval_connected(struct node* node, int inputSlot) { - NK_ASSERT(node->inputs[inputSlot].isConnected); - return node->inputs[inputSlot].connectedNode->evalFunc(node->inputs[inputSlot].connectedNode, node->inputs[inputSlot].connectedSlot); + NK_ASSERT(node->inputs[inputSlot].is_connected); + return node->inputs[inputSlot].connected_node->eval_func(node->inputs[inputSlot].connected_node, node->inputs[inputSlot].connected_slot); } static void @@ -251,23 +250,23 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, int i; for (i = 0; i < (int)NK_LEN(editor->links); i++) { - if (editor->links[i].isActive == nk_false) { + if (editor->links[i].is_active == nk_false) { link = &editor->links[i]; break; } } } if (link) { - out_node->inputs[out_slot].isConnected = nk_true; - in_node->outputs[in_slot].isConnected = nk_true; - out_node->inputs[out_slot].connectedNode = in_node; - out_node->inputs[out_slot].connectedSlot = in_slot; + out_node->inputs[out_slot].is_connected = nk_true; + in_node->outputs[in_slot].is_connected = nk_true; + out_node->inputs[out_slot].connected_node = in_node; + out_node->inputs[out_slot].connected_slot = in_slot; link->input_node = in_node; link->input_slot = in_slot; link->output_node = out_node; link->output_slot = out_slot; - link->isActive = nk_true; + link->is_active = nk_true; } else fprintf(stdout, "Too many links\n"); @@ -276,14 +275,14 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, static void node_editor_init(struct node_editor *editor) { - struct nk_vec2 outputNode_position = {600, 400}; - struct nk_vec2 colorNode_position = {40, 10}; + struct nk_vec2 output_node_position = {600, 400}; + struct nk_vec2 color_node_position = {40, 10}; memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; - editor->outputNode = node_output_create(editor, outputNode_position); - node_color_create(editor, colorNode_position); + editor->output_node = node_output_create(editor, output_node_position); + node_color_create(editor, color_node_position); editor->show_grid = nk_true; } @@ -295,11 +294,11 @@ node_editor_main(struct nk_context *ctx) const struct nk_input *in = &ctx->input; struct nk_command_buffer *canvas; struct node *updated = 0; - struct node_editor *nodedit = &nodeEditor; + struct node_editor *editor = &node_editor; - if (!nodeEditor.initialized) { - node_editor_init(&nodeEditor); - nodeEditor.initialized = 1; + if (!node_editor.initialized) { + node_editor_init(&node_editor); + node_editor.initialized = 1; } if (nk_begin(ctx, "NodeEdit", nk_rect(0, 0, 800, 600), @@ -308,20 +307,20 @@ node_editor_main(struct nk_context *ctx) /* allocate complete window space */ canvas = nk_window_get_canvas(ctx); total_space = nk_window_get_content_region(ctx); - nk_layout_space_begin(ctx, NK_STATIC, total_space.h, nodedit->node_count); + nk_layout_space_begin(ctx, NK_STATIC, total_space.h, editor->node_count); { - struct node *it = nodedit->begin; + struct node *it = editor->begin; struct nk_rect size = nk_layout_space_bounds(ctx); struct nk_panel *nodePanel = 0; - if (nodedit->show_grid) { + if (editor->show_grid) { /* display grid */ float x, y; const float grid_size = 32.0f; const struct nk_color grid_color = nk_rgb(50, 50, 50); - for (x = (float)fmod(size.x - nodedit->scrolling.x, grid_size); x < size.w; x += grid_size) + for (x = (float)fmod(size.x - editor->scrolling.x, grid_size); x < size.w; x += grid_size) nk_stroke_line(canvas, x+size.x, size.y, x+size.x, size.y+size.h, 1.0f, grid_color); - for (y = (float)fmod(size.y - nodedit->scrolling.y, grid_size); y < size.h; y += grid_size) + for (y = (float)fmod(size.y - editor->scrolling.y, grid_size); y < size.h; y += grid_size) nk_stroke_line(canvas, size.x, y+size.y, size.x+size.w, y+size.y, 1.0f, grid_color); } @@ -330,12 +329,12 @@ node_editor_main(struct nk_context *ctx) while (it) { /* Output node window should not have a close button */ nk_flags nodePanel_flags = NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE; - if (it != nodeEditor.outputNode) + if (it != editor->output_node) nodePanel_flags |= NK_WINDOW_CLOSABLE; /* calculate scrolled node window position and size */ - nk_layout_space_push(ctx, nk_rect(it->bounds.x - nodedit->scrolling.x, - it->bounds.y - nodedit->scrolling.y, it->bounds.w, it->bounds.h)); + nk_layout_space_push(ctx, nk_rect(it->bounds.x - editor->scrolling.x, + it->bounds.y - editor->scrolling.y, it->bounds.w, it->bounds.h)); /* execute node window */ if (nk_group_begin(ctx, it->name, nodePanel_flags)) @@ -346,36 +345,36 @@ node_editor_main(struct nk_context *ctx) if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nodePanel->bounds) && (!(it->prev && nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nk_layout_space_rect_to_screen(ctx, nodePanel->bounds)))) && - nodedit->end != it) + editor->end != it) { updated = it; } if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) { /* Node close button has not been clicked */ /* ================= NODE CONTENT ===================== */ - it->displayFunc(ctx, it); + it->display_func(ctx, it); /* ==================================================== */ } else { /* Delete node */ struct node_link *link_remove; - node_editor_pop(nodedit, it); + node_editor_pop(editor, it); for (n = 0; n < it->input_count; n++) { - if ((link_remove = node_editor_find_link_by_output(nodedit, it, n))) + if ((link_remove = node_editor_find_link_by_output(editor, it, n))) { node_editor_delete_link(link_remove); } } for (n = 0; n < it -> output_count; n++) { - while((link_remove = node_editor_find_link_by_input(nodedit, it, n))) + while((link_remove = node_editor_find_link_by_input(editor, it, n))) { node_editor_delete_link(link_remove); } } - NK_ASSERT(nodedit->node_buf[it->ID] == it); - nodedit->node_buf[it->ID] = NULL; + NK_ASSERT(editor->node_buf[it->ID] == it); + editor->node_buf[it->ID] = NULL; free(it->inputs); free(it->outputs); free(it); @@ -388,8 +387,8 @@ node_editor_main(struct nk_context *ctx) /* node connector and linking */ struct nk_rect bounds; bounds = nk_layout_space_rect_to_local(ctx, nodePanel->bounds); - bounds.x += nodedit->scrolling.x; - bounds.y += nodedit->scrolling.y; + bounds.x += editor->scrolling.x; + bounds.y += editor->scrolling.y; it->bounds = bounds; /* output connectors */ @@ -407,16 +406,16 @@ node_editor_main(struct nk_context *ctx) /* start linking process */ /* (set linking active) */ if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true)) { - nodedit->linking.active = nk_true; - nodedit->linking.node = it; - nodedit->linking.input_id = it->ID; - nodedit->linking.input_slot = n; + editor->linking.active = nk_true; + editor->linking.node = it; + editor->linking.input_id = it->ID; + editor->linking.input_slot = n; } /* draw curve from linked node slot to mouse position */ /* (if linking active) */ - if (nodedit->linking.active && nodedit->linking.node == it && - nodedit->linking.input_slot == n) { + if (editor->linking.active && editor->linking.node == it && + editor->linking.input_slot == n) { struct nk_vec2 l0 = nk_vec2(circle.x + 3, circle.y + 3); struct nk_vec2 l1 = in->mouse.pos; nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, @@ -438,27 +437,27 @@ node_editor_main(struct nk_context *ctx) /* Detach link */ if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true) && - nodedit->linking.active == nk_false && - it->inputs[n].isConnected == nk_true) { - struct node_link *node_relink = node_editor_find_link_by_output(nodedit, it, n); - nodedit->linking.active = nk_true; - nodedit->linking.node = node_relink->input_node; - nodedit->linking.input_id = node_relink->input_node->ID; - nodedit->linking.input_slot = node_relink->input_slot; + editor->linking.active == nk_false && + it->inputs[n].is_connected == nk_true) { + struct node_link *node_relink = node_editor_find_link_by_output(editor, it, n); + editor->linking.active = nk_true; + editor->linking.node = node_relink->input_node; + editor->linking.input_id = node_relink->input_node->ID; + editor->linking.input_slot = node_relink->input_slot; node_editor_delete_link(node_relink); } /* (Create link) */ if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && - nodedit->linking.active && - nodedit->linking.node != it && - it->inputs[n].type == nodedit->linking.node->outputs[nodedit->linking.input_slot].type && - it->inputs[n].isConnected != nk_true) { - nodedit->linking.active = nk_false; + editor->linking.active && + editor->linking.node != it && + it->inputs[n].type == editor->linking.node->outputs[editor->linking.input_slot].type && + it->inputs[n].is_connected != nk_true) { + editor->linking.active = nk_false; - node_editor_link(nodedit, nodedit->linking.node, - nodedit->linking.input_slot, it, n); + node_editor_link(editor, editor->linking.node, + editor->linking.input_slot, it, n); } } } @@ -466,16 +465,16 @@ node_editor_main(struct nk_context *ctx) } /* reset linking connection */ - if (nodedit->linking.active && nk_input_is_mouse_released(in, NK_BUTTON_LEFT)) { - nodedit->linking.active = nk_false; - nodedit->linking.node = NULL; + if (editor->linking.active && nk_input_is_mouse_released(in, NK_BUTTON_LEFT)) { + editor->linking.active = nk_false; + editor->linking.node = NULL; fprintf(stdout, "linking failed\n"); } /* draw each link */ - for (n = 0; n < nodedit->link_count; ++n) { - struct node_link *link = &nodedit->links[n]; - if (link->isActive == nk_true){ + for (n = 0; n < editor->link_count; ++n) { + struct node_link *link = &editor->links[n]; + if (link->is_active == nk_true){ struct node *ni = link->input_node; struct node *no = link->output_node; struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, @@ -483,10 +482,10 @@ node_editor_main(struct nk_context *ctx) struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, nk_vec2(no->bounds.x, 3.0f + no->bounds.y + no->slot_spacing.in_top + no->slot_spacing.in_space * (float)(link->output_slot))); - l0.x -= nodedit->scrolling.x; - l0.y -= nodedit->scrolling.y; - l1.x -= nodedit->scrolling.x; - l1.y -= nodedit->scrolling.y; + l0.x -= editor->scrolling.x; + l0.y -= editor->scrolling.y; + l1.x -= editor->scrolling.x; + l1.y -= editor->scrolling.y; nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); } @@ -494,21 +493,21 @@ node_editor_main(struct nk_context *ctx) if (updated) { /* reshuffle nodes to have least recently selected node on top */ - node_editor_pop(nodedit, updated); - node_editor_push(nodedit, updated); + node_editor_pop(editor, updated); + node_editor_push(editor, updated); } /* node selection */ if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nk_layout_space_bounds(ctx))) { - it = nodedit->begin; - nodedit->selected = NULL; - nodedit->bounds = nk_rect(in->mouse.pos.x, in->mouse.pos.y, 100, 200); + it = editor->begin; + editor->selected = NULL; + editor->bounds = nk_rect(in->mouse.pos.x, in->mouse.pos.y, 100, 200); while (it) { struct nk_rect b = nk_layout_space_rect_to_screen(ctx, it->bounds); - b.x -= nodedit->scrolling.x; - b.y -= nodedit->scrolling.y; + b.x -= editor->scrolling.x; + b.y -= editor->scrolling.y; if (nk_input_is_mouse_hovering_rect(in, b)) - nodedit->selected = it; + editor->selected = it; it = it->next; } } @@ -518,13 +517,13 @@ node_editor_main(struct nk_context *ctx) const char *grid_option[] = {"Show Grid", "Hide Grid"}; nk_layout_row_dynamic(ctx, 25, 1); if (nk_contextual_item_label(ctx, "Add Color node", NK_TEXT_CENTERED)) - node_color_create(nodedit, in->mouse.pos); + node_color_create(editor, in->mouse.pos); if (nk_contextual_item_label(ctx, "Add Float node", NK_TEXT_CENTERED)) - node_float_create(nodedit, in->mouse.pos); + node_float_create(editor, in->mouse.pos); if (nk_contextual_item_label(ctx, "Add Blend Node", NK_TEXT_CENTERED)) - node_blend_create(nodedit, in->mouse.pos); - if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) - nodedit->show_grid = !nodedit->show_grid; + node_blend_create(editor, in->mouse.pos); + if (nk_contextual_item_label(ctx, grid_option[editor->show_grid],NK_TEXT_CENTERED)) + editor->show_grid = !editor->show_grid; nk_contextual_end(ctx); } } @@ -533,8 +532,8 @@ node_editor_main(struct nk_context *ctx) /* window content scrolling */ if (nk_input_is_mouse_hovering_rect(in, nk_window_get_bounds(ctx)) && nk_input_is_mouse_down(in, NK_BUTTON_MIDDLE)) { - nodedit->scrolling.x += in->mouse.delta.x; - nodedit->scrolling.y += in->mouse.delta.y; + editor->scrolling.x += in->mouse.delta.x; + editor->scrolling.y += in->mouse.delta.y; } } nk_end(ctx); diff --git a/demo/common/nodeeditor/node_type_blend.c b/demo/common/nodeeditor/node_type_blend.c index f46242d0b..217389337 100644 --- a/demo/common/nodeeditor/node_type_blend.c +++ b/demo/common/nodeeditor/node_type_blend.c @@ -1,73 +1,73 @@ struct node_type_blend { struct node node; - struct nk_colorf inputVal[2]; - struct nk_colorf outputVal; - float blendVal; + struct nk_colorf input_val[2]; + struct nk_colorf output_val; + float blend_val; }; static struct nk_colorf *node_blend_eval(struct node *node, int oIndex) { - struct node_type_blend* blendNode = (struct node_type_blend*)node; - return &blendNode->outputVal; + struct node_type_blend* blend_node = (struct node_type_blend*)node; + return &blend_node->output_val; } static void node_blend_display(struct nk_context *ctx, struct node *node) { - struct node_type_blend *blendNode = (struct node_type_blend*)node; + struct node_type_blend *blend_node = (struct node_type_blend*)node; const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; - float blendAmnt; + float blend_amnt; int i; nk_layout_row_dynamic(ctx, 25, 1); - for (i = 0; i < (int)NK_LEN(blendNode->inputVal); i++){ - if(node->inputs[i].isConnected) { - blendNode->inputVal[i] = *(struct nk_colorf*)node_editor_eval_connected(node, i); + for (i = 0; i < (int)NK_LEN(blend_node->input_val); i++){ + if(node->inputs[i].is_connected) { + blend_node->input_val[i] = *(struct nk_colorf*)node_editor_eval_connected(node, i); } else { - blendNode->inputVal[i] = blank; + blend_node->input_val[i] = blank; } - nk_button_color(ctx, nk_rgba_cf(blendNode->inputVal[i])); + nk_button_color(ctx, nk_rgba_cf(blend_node->input_val[i])); } - if (node->inputs[2].isConnected) { - blendAmnt = *(float*)node_editor_eval_connected(node, 2); - blendAmnt = nk_propertyf(ctx, "#Blend", blendAmnt, blendAmnt, blendAmnt, 0.01f, 0.01f); + if (node->inputs[2].is_connected) { + blend_amnt = *(float*)node_editor_eval_connected(node, 2); + blend_amnt = nk_propertyf(ctx, "#Blend", blend_amnt, blend_amnt, blend_amnt, 0.01f, 0.01f); } else { - blendNode->blendVal = nk_propertyf(ctx, "#Blend", 0.0f, blendNode->blendVal, 1.0f, 0.01f, 0.01f); - blendAmnt = blendNode->blendVal; + blend_node->blend_val = nk_propertyf(ctx, "#Blend", 0.0f, blend_node->blend_val, 1.0f, 0.01f, 0.01f); + blend_amnt = blend_node->blend_val; } - if(node->inputs[0].isConnected && node->inputs[1].isConnected) { - blendNode->outputVal.r = blendNode->inputVal[0].r * blendAmnt + blendNode->inputVal[1].r * (1.0f-blendAmnt); - blendNode->outputVal.g = blendNode->inputVal[0].g * blendAmnt + blendNode->inputVal[1].g * (1.0f-blendAmnt); - blendNode->outputVal.b = blendNode->inputVal[0].b * blendAmnt + blendNode->inputVal[1].b * (1.0f-blendAmnt); - blendNode->outputVal.a = blendNode->inputVal[0].a * blendAmnt + blendNode->inputVal[1].a * (1.0f-blendAmnt); + if(node->inputs[0].is_connected && node->inputs[1].is_connected) { + blend_node->output_val.r = blend_node->input_val[0].r * blend_amnt + blend_node->input_val[1].r * (1.0f-blend_amnt); + blend_node->output_val.g = blend_node->input_val[0].g * blend_amnt + blend_node->input_val[1].g * (1.0f-blend_amnt); + blend_node->output_val.b = blend_node->input_val[0].b * blend_amnt + blend_node->input_val[1].b * (1.0f-blend_amnt); + blend_node->output_val.a = blend_node->input_val[0].a * blend_amnt + blend_node->input_val[1].a * (1.0f-blend_amnt); } else { - blendNode->outputVal = blank; + blend_node->output_val = blank; } } void node_blend_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_blend* blendNode = (struct node_type_blend*)node_editor_add(editor, sizeof(struct node_type_blend), "Blend", nk_rect(position.x, position.y, 180, 130), 3, 1); - if (blendNode) { + struct node_type_blend* blend_node = (struct node_type_blend*)node_editor_add(editor, sizeof(struct node_type_blend), "Blend", nk_rect(position.x, position.y, 180, 130), 3, 1); + if (blend_node) { const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; int i; - for (i = 0; i < (int)NK_LEN(blendNode->inputVal); i++) - blendNode->node.inputs[i].type = fColor; - blendNode->node.outputs[0].type = fColor; + for (i = 0; i < (int)NK_LEN(blend_node->input_val); i++) + blend_node->node.inputs[i].type = fColor; + blend_node->node.outputs[0].type = fColor; - blendNode->node.slot_spacing.in_top = 42.0f; - blendNode->node.slot_spacing.in_space = 29.0f; + blend_node->node.slot_spacing.in_top = 42.0f; + blend_node->node.slot_spacing.in_space = 29.0f; - for (i = 0; i < (int)NK_LEN(blendNode->inputVal); i++) - blendNode->inputVal[i] = blank; - blendNode->outputVal = blank; + for (i = 0; i < (int)NK_LEN(blend_node->input_val); i++) + blend_node->input_val[i] = blank; + blend_node->output_val = blank; - blendNode->blendVal = 0.5f; + blend_node->blend_val = 0.5f; - blendNode->node.displayFunc = node_blend_display; - blendNode->node.evalFunc = (void*(*)(struct node*, int)) node_blend_eval; + blend_node->node.display_func = node_blend_display; + blend_node->node.eval_func = (void*(*)(struct node*, int)) node_blend_eval; } } diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 305a92ba5..35809c004 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -1,71 +1,72 @@ struct node_type_color { struct node node; - float inputVal[4]; - struct nk_colorf outputVal; + float input_val[4]; + struct nk_colorf output_val; }; static struct nk_colorf *node_color_eval(struct node* node, int oIndex) { - struct node_type_color *colornode = (struct node_type_color*)node; + struct node_type_color *color_node = (struct node_type_color*)node; NK_ASSERT(oIndex == 0); /* only one output connector */ - return &colornode->outputVal; + return &color_node->output_val; } static void node_color_draw(struct nk_context *ctx, struct node *node) { - struct node_type_color *colornode = (struct node_type_color*)node; - float evalResult; /* Get the values from connected nodes into this so the inputs revert on disconnect */ + struct node_type_color *color_node = (struct node_type_color*)node; + float eval_result; /* Get the values from connected nodes into this so the inputs revert on disconnect */ const char* labels[4] = {"#R:","#G:","#B:","#A:"}; - float colorVals[4]; /* Because we can't just loop through the struct... */ + float color_val[4]; /* Because we can't just loop through the struct... */ int i; nk_layout_row_dynamic(ctx, 25, 1); - nk_button_color(ctx, nk_rgba_cf(colornode->outputVal)); + nk_button_color(ctx, nk_rgba_cf(color_node->output_val)); - for (i = 0; i < 4; i++) { - if (colornode->node.inputs[i].isConnected) { - evalResult = *(float*)node_editor_eval_connected(node, i); - evalResult = nk_propertyf(ctx, labels[i], evalResult, evalResult, evalResult, 0.01f, 0.01f); - colorVals[i] = evalResult; + for (i = 0; i < 4; i++) + { + if (color_node->node.inputs[i].is_connected) { + eval_result = *(float*)node_editor_eval_connected(node, i); + eval_result = nk_propertyf(ctx, labels[i], eval_result, eval_result, eval_result, 0.01f, 0.01f); + color_val[i] = eval_result; } else { - colornode->inputVal[i] = nk_propertyf(ctx, labels[i], 0.0f, colornode->inputVal[i], 1.0f, 0.01f, 0.01f); - colorVals[i] = colornode->inputVal[i]; + color_node->input_val[i] = nk_propertyf(ctx, labels[i], 0.0f, color_node->input_val[i], 1.0f, 0.01f, 0.01f); + color_val[i] = color_node->input_val[i]; } } - colornode->outputVal.r = colorVals[0]; - colornode->outputVal.g = colorVals[1]; - colornode->outputVal.b = colorVals[2]; - colornode->outputVal.a = colorVals[3]; + color_node->output_val.r = color_val[0]; + color_node->output_val.g = color_val[1]; + color_node->output_val.b = color_val[2]; + color_node->output_val.a = color_val[3]; } void node_color_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_color *colornode = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 190), 4, 1); - if (colornode) + struct node_type_color *color_node = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 190), 4, 1); + if (color_node) { int i; const struct nk_colorf white = {1.0f, 1.0f, 1.0f, 1.0f}; - colornode->node.slot_spacing.in_top = 72.0f; - colornode->node.slot_spacing.in_space = 29.0f; - colornode->node.slot_spacing.out_top = 42.0f; - colornode->node.slot_spacing.out_space = 0.0f; + color_node->node.slot_spacing.in_top = 72.0f; + color_node->node.slot_spacing.in_space = 29.0f; + color_node->node.slot_spacing.out_top = 42.0f; + color_node->node.slot_spacing.out_space = 0.0f; - for (i = 0; i < colornode->node.input_count; i++) - colornode->node.inputs[i].type = fValue; - colornode->node.outputs[0].type = fColor; + for (i = 0; i < color_node->node.input_count; i++) + color_node->node.inputs[i].type = fValue; + color_node->node.outputs[0].type = fColor; - colornode->inputVal[0] = - colornode->inputVal[1] = - colornode->inputVal[2] = - colornode->inputVal[3] = 1.0f; + color_node->input_val[0] = + color_node->input_val[1] = + color_node->input_val[2] = + color_node->input_val[3] = 1.0f; - colornode->outputVal = white; + color_node->output_val = white; - colornode->node.displayFunc = node_color_draw; - colornode->node.evalFunc = (void*(*)(struct node*, int)) node_color_eval; + color_node->node.display_func = node_color_draw; + color_node->node.eval_func = (void*(*)(struct node*, int)) node_color_eval; } } diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c index 469197d22..608632797 100644 --- a/demo/common/nodeeditor/node_type_float.c +++ b/demo/common/nodeeditor/node_type_float.c @@ -1,26 +1,26 @@ struct node_type_float { struct node node; - float outputVal; + float output_val; }; static float *node_float_eval(struct node* node, int oIndex) { - struct node_type_float *floatnode = (struct node_type_float*)node; + struct node_type_float *float_node = (struct node_type_float*)node; NK_ASSERT(oIndex == 0); - return &floatnode->outputVal; + return &float_node->output_val; } static void node_float_draw(struct nk_context *ctx, struct node *node) { - struct node_type_float *floatnode = (struct node_type_float*)node; + struct node_type_float *float_node = (struct node_type_float*)node; nk_layout_row_dynamic(ctx, 25, 1); - floatnode->outputVal = nk_propertyf(ctx, "#Value:", 0.0f, floatnode->outputVal, 1.0f, 0.01f, 0.01f); + float_node->output_val = nk_propertyf(ctx, "#Value:", 0.0f, float_node->output_val, 1.0f, 0.01f, 0.01f); } void node_float_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_float *floatnode = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 75), 0, 1); - if (floatnode) + struct node_type_float *float_node = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 75), 0, 1); + if (float_node) { - floatnode->outputVal = 1.0f; - floatnode->node.displayFunc = node_float_draw; - floatnode->node.evalFunc = (void*(*)(struct node*, int)) node_float_eval; + float_node->output_val = 1.0f; + float_node->node.display_func = node_float_draw; + float_node->node.eval_func = (void*(*)(struct node*, int)) node_float_eval; } } diff --git a/demo/common/nodeeditor/node_type_output.c b/demo/common/nodeeditor/node_type_output.c index 5ba792c99..aa135fa0a 100644 --- a/demo/common/nodeeditor/node_type_output.c +++ b/demo/common/nodeeditor/node_type_output.c @@ -1,31 +1,31 @@ struct node_type_output { struct node node; - struct nk_colorf inputVal; + struct nk_colorf input_val; }; struct nk_colorf *node_output_get(struct node* node) { - struct node_type_output *outputnode = (struct node_type_output*)node; - if (!node->inputs[0].isConnected) { + struct node_type_output *output_node = (struct node_type_output*)node; + if (!node->inputs[0].is_connected) { struct nk_colorf black = {0.0f, 0.0f, 0.0f, 0.0f}; - outputnode->inputVal = black; + output_node->input_val = black; } - return &outputnode->inputVal; + return &output_node->input_val; } static void node_output_display(struct nk_context *ctx, struct node *node) { - if (node->inputs[0].isConnected) { - struct node_type_output *outputnode = (struct node_type_output*)node; - outputnode->inputVal = *(struct nk_colorf*)node_editor_eval_connected(node, 0); + if (node->inputs[0].is_connected) { + struct node_type_output *output_node = (struct node_type_output*)node; + output_node->input_val = *(struct nk_colorf*)node_editor_eval_connected(node, 0); nk_layout_row_dynamic(ctx, 60, 1); - nk_button_color(ctx, nk_rgba_cf(outputnode->inputVal)); + nk_button_color(ctx, nk_rgba_cf(output_node->input_val)); } } struct node* node_output_create(struct node_editor *editor, struct nk_vec2 position) { - struct node_type_output *outputNode = (struct node_type_output*)node_editor_add(editor, sizeof(struct node_type_output), "Output", nk_rect(position.x, position.y, 100, 100), 1, 0); - if (outputNode){ - outputNode->node.inputs[0].type = fColor; - outputNode->node.displayFunc = node_output_display; + struct node_type_output *output_node = (struct node_type_output*)node_editor_add(editor, sizeof(struct node_type_output), "Output", nk_rect(position.x, position.y, 100, 100), 1, 0); + if (output_node){ + output_node->node.inputs[0].type = fColor; + output_node->node.display_func = node_output_display; } - return (struct node*)outputNode; + return (struct node*)output_node; } From b2c7c1b093ff0e7d931d2446d96bb7767afbf447 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Sun, 28 May 2023 13:03:34 +0300 Subject: [PATCH 22/28] Renamed node_editor_main back to node_editor --- demo/common/node_editor.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 8a59ff0c7..8f1a9c55f 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -72,7 +72,7 @@ struct node_editor { struct nk_vec2 scrolling; struct node_linking linking; }; -static struct node_editor node_editor; +static struct node_editor nodeEditor; /* === PROTOTYPES === */ /* Each type of node needs these two functions. */ @@ -287,18 +287,18 @@ node_editor_init(struct node_editor *editor) } static int -node_editor_main(struct nk_context *ctx) +node_editor(struct nk_context *ctx) { int n = 0; struct nk_rect total_space; const struct nk_input *in = &ctx->input; struct nk_command_buffer *canvas; struct node *updated = 0; - struct node_editor *editor = &node_editor; + struct node_editor *editor = &nodeEditor; - if (!node_editor.initialized) { - node_editor_init(&node_editor); - node_editor.initialized = 1; + if (!nodeEditor.initialized) { + node_editor_init(&nodeEditor); + nodeEditor.initialized = 1; } if (nk_begin(ctx, "NodeEdit", nk_rect(0, 0, 800, 600), From de72f94a854c91eb7d6c03c352c94e4c07db33ec Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 31 May 2023 11:39:03 +0300 Subject: [PATCH 23/28] Minor cleanups --- demo/common/node_editor.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 8f1a9c55f..4821ed687 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -75,17 +75,21 @@ struct node_editor { static struct node_editor nodeEditor; /* === PROTOTYPES === */ -/* Each type of node needs these two functions. */ +/* The node implementations need these two functions. */ /* These could/should go in a header file along with the node and node_connector structs and be #included in the node implementations */ + struct node* node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count); void* node_editor_eval_connected(struct node *node, int inputSlot); /* ================== */ +/* === NODE TYPE IMPLEMENTATIONS === */ + #include "nodeeditor/node_type_float.c" #include "nodeeditor/node_type_color.c" #include "nodeeditor/node_type_blend.c" #include "nodeeditor/node_type_output.c" +/* ================================= */ static void node_editor_push(struct node_editor *editor, struct node *node) @@ -350,12 +354,8 @@ node_editor(struct nk_context *ctx) updated = it; } - if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) { /* Node close button has not been clicked */ - /* ================= NODE CONTENT ===================== */ - it->display_func(ctx, it); - /* ==================================================== */ - } - else { + if ((nodePanel->flags & NK_WINDOW_HIDDEN)) /* Node close button has been clicked */ + { /* Delete node */ struct node_link *link_remove; node_editor_pop(editor, it); @@ -373,14 +373,23 @@ node_editor(struct nk_context *ctx) node_editor_delete_link(link_remove); } } - NK_ASSERT(editor->node_buf[it->ID] == it); - editor->node_buf[it->ID] = NULL; - free(it->inputs); - free(it->outputs); - free(it); + NK_ASSERT(editor->node_buf[it->ID] == it); + editor->node_buf[it->ID] = NULL; + free(it->inputs); + free(it->outputs); + free(it); } + else { + /* ================= NODE CONTENT ===================== */ + + it->display_func(ctx, it); + + /* ==================================================== */ + + } nk_group_end(ctx); + } if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) { From 25e2a0b8e421db2359097506f365ec7e2693bdbf Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 31 May 2023 11:48:43 +0300 Subject: [PATCH 24/28] Restore main.c from master --- demo/glfw_opengl3/main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/demo/glfw_opengl3/main.c b/demo/glfw_opengl3/main.c index 364632358..8eb749de4 100644 --- a/demo/glfw_opengl3/main.c +++ b/demo/glfw_opengl3/main.c @@ -9,8 +9,7 @@ #include #include -#define GL_SILENCE_DEPRECATION -/* #include */ +#include #include #define NK_INCLUDE_FIXED_TYPES @@ -43,8 +42,8 @@ /*#define INCLUDE_STYLE */ /*#define INCLUDE_CALCULATOR */ /*#define INCLUDE_CANVAS */ -/*#define INCLUDE_OVERVIEW */ -#define INCLUDE_NODE_EDITOR */ +#define INCLUDE_OVERVIEW +/*#define INCLUDE_NODE_EDITOR */ #ifdef INCLUDE_ALL #define INCLUDE_STYLE @@ -105,11 +104,11 @@ int main(void) /* OpenGL */ glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); - /*glewExperimental = 1; + glewExperimental = 1; if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to setup GLEW\n"); exit(1); - }*/ + } ctx = nk_glfw3_init(&glfw, win, NK_GLFW3_INSTALL_CALLBACKS); /* Load Fonts: if none of these are loaded a default font will be used */ @@ -192,7 +191,7 @@ int main(void) overview(ctx); #endif #ifdef INCLUDE_NODE_EDITOR - node_editor_main(ctx); + node_editor(ctx); #endif /* ----------------------------------------- */ From 2af99553b2b0e337504c92fe5afe12cb1d931a52 Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 31 May 2023 12:45:43 +0300 Subject: [PATCH 25/28] Fix blend node out color inverted vs inputs --- demo/common/nodeeditor/node_type_blend.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/common/nodeeditor/node_type_blend.c b/demo/common/nodeeditor/node_type_blend.c index 217389337..5c4ff590c 100644 --- a/demo/common/nodeeditor/node_type_blend.c +++ b/demo/common/nodeeditor/node_type_blend.c @@ -38,10 +38,10 @@ static void node_blend_display(struct nk_context *ctx, struct node *node) { if(node->inputs[0].is_connected && node->inputs[1].is_connected) { - blend_node->output_val.r = blend_node->input_val[0].r * blend_amnt + blend_node->input_val[1].r * (1.0f-blend_amnt); - blend_node->output_val.g = blend_node->input_val[0].g * blend_amnt + blend_node->input_val[1].g * (1.0f-blend_amnt); - blend_node->output_val.b = blend_node->input_val[0].b * blend_amnt + blend_node->input_val[1].b * (1.0f-blend_amnt); - blend_node->output_val.a = blend_node->input_val[0].a * blend_amnt + blend_node->input_val[1].a * (1.0f-blend_amnt); + blend_node->output_val.r = blend_node->input_val[0].r * (1.0f-blend_amnt) + blend_node->input_val[1].r * blend_amnt; + blend_node->output_val.g = blend_node->input_val[0].g * (1.0f-blend_amnt) + blend_node->input_val[1].g * blend_amnt; + blend_node->output_val.b = blend_node->input_val[0].b * (1.0f-blend_amnt) + blend_node->input_val[1].b * blend_amnt; + blend_node->output_val.a = blend_node->input_val[0].a * (1.0f-blend_amnt) + blend_node->input_val[1].a * blend_amnt; } else { blend_node->output_val = blank; From 7b637bcc713a7bd450aa3bac8d033e7e2bbba7ea Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Wed, 31 May 2023 12:45:43 +0300 Subject: [PATCH 26/28] Fix blend node out color inverted vs inputs --- demo/common/nodeeditor/node_type_blend.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/common/nodeeditor/node_type_blend.c b/demo/common/nodeeditor/node_type_blend.c index 217389337..9f20e45cb 100644 --- a/demo/common/nodeeditor/node_type_blend.c +++ b/demo/common/nodeeditor/node_type_blend.c @@ -17,7 +17,7 @@ static void node_blend_display(struct nk_context *ctx, struct node *node) { int i; nk_layout_row_dynamic(ctx, 25, 1); - for (i = 0; i < (int)NK_LEN(blend_node->input_val); i++){ + for (i = 0; i < 2; i++){ if(node->inputs[i].is_connected) { blend_node->input_val[i] = *(struct nk_colorf*)node_editor_eval_connected(node, i); } @@ -38,10 +38,10 @@ static void node_blend_display(struct nk_context *ctx, struct node *node) { if(node->inputs[0].is_connected && node->inputs[1].is_connected) { - blend_node->output_val.r = blend_node->input_val[0].r * blend_amnt + blend_node->input_val[1].r * (1.0f-blend_amnt); - blend_node->output_val.g = blend_node->input_val[0].g * blend_amnt + blend_node->input_val[1].g * (1.0f-blend_amnt); - blend_node->output_val.b = blend_node->input_val[0].b * blend_amnt + blend_node->input_val[1].b * (1.0f-blend_amnt); - blend_node->output_val.a = blend_node->input_val[0].a * blend_amnt + blend_node->input_val[1].a * (1.0f-blend_amnt); + blend_node->output_val.r = blend_node->input_val[0].r * (1.0f-blend_amnt) + blend_node->input_val[1].r * blend_amnt; + blend_node->output_val.g = blend_node->input_val[0].g * (1.0f-blend_amnt) + blend_node->input_val[1].g * blend_amnt; + blend_node->output_val.b = blend_node->input_val[0].b * (1.0f-blend_amnt) + blend_node->input_val[1].b * blend_amnt; + blend_node->output_val.a = blend_node->input_val[0].a * (1.0f-blend_amnt) + blend_node->input_val[1].a * blend_amnt; } else { blend_node->output_val = blank; From 862405f8be9da44b5b96b9e50f5f0d09ddaf728f Mon Sep 17 00:00:00 2001 From: Peter Schulman Date: Mon, 11 Dec 2023 19:45:37 +0200 Subject: [PATCH 27/28] Added link between Color and Output nodes in initial state of node editor demo --- demo/common/node_editor.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 4821ed687..075911adc 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -279,14 +279,15 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, static void node_editor_init(struct node_editor *editor) { - struct nk_vec2 output_node_position = {600, 400}; - struct nk_vec2 color_node_position = {40, 10}; + struct nk_vec2 output_node_position = {500, 300}; + struct nk_vec2 color_node_position = {200, 200}; memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; editor->output_node = node_output_create(editor, output_node_position); node_color_create(editor, color_node_position); + node_editor_link(editor, editor->node_buf[1], 0, editor->output_node, 0); editor->show_grid = nk_true; } From 8e0e80b516920fc514f9ee84e08a3a776bb4bdd7 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 5 Sep 2024 11:27:30 -0400 Subject: [PATCH 28/28] demo: Add node editor example --- demo/common/node_editor.c | 68 ++++++++++++++++-------- demo/common/nodeeditor/node_type_blend.c | 10 ++-- demo/common/nodeeditor/node_type_color.c | 17 +++--- demo/common/nodeeditor/node_type_float.c | 3 +- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/demo/common/node_editor.c b/demo/common/node_editor.c index 075911adc..fc3da7b05 100644 --- a/demo/common/node_editor.c +++ b/demo/common/node_editor.c @@ -1,6 +1,6 @@ /* -A basic node-based UI built with Nuklear. -Builds on the node editor example included in Nuklear v1.00, with the aim of +A basic node-based UI built with Nuklear. +Builds on the node editor example included in Nuklear v1.00, with the aim of being used as a prototype for implementing a functioning node editor. Features: @@ -176,7 +176,7 @@ node_editor_delete_link(struct node_link *link) } struct node* -node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, +node_editor_add(struct node_editor *editor, size_t nodeSize, const char *name, struct nk_rect bounds, int in_count, int out_count) { int i; @@ -208,7 +208,7 @@ int in_count, int out_count) } node->bounds = bounds; - + node->input_count = in_count; node->output_count = out_count; @@ -224,7 +224,7 @@ int in_count, int out_count) node->outputs[i].type = fValue; /* default connector type */ } - /* default connector spacing */ + /* default connector spacing */ node->slot_spacing.in_top = node->slot_spacing.in_space = node->bounds.h / (float)((node->input_count) + 1); node->slot_spacing.out_top = node->slot_spacing.out_space = node->bounds.h / (float)((node->output_count) + 1); @@ -235,7 +235,7 @@ int in_count, int out_count) } void * -node_editor_eval_connected(struct node* node, int inputSlot) +node_editor_eval_connected(struct node* node, int inputSlot) { NK_ASSERT(node->inputs[inputSlot].is_connected); return node->inputs[inputSlot].connected_node->eval_func(node->inputs[inputSlot].connected_node, node->inputs[inputSlot].connected_slot); @@ -265,7 +265,7 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, in_node->outputs[in_slot].is_connected = nk_true; out_node->inputs[out_slot].connected_node = in_node; out_node->inputs[out_slot].connected_slot = in_slot; - + link->input_node = in_node; link->input_slot = in_slot; link->output_node = out_node; @@ -279,15 +279,37 @@ node_editor_link(struct node_editor *editor, struct node *in_node, int in_slot, static void node_editor_init(struct node_editor *editor) { - struct nk_vec2 output_node_position = {500, 300}; - struct nk_vec2 color_node_position = {200, 200}; + struct nk_vec2 color_node_position = {40, 10}; + struct nk_vec2 color2_node_position = {40, 260}; + struct nk_vec2 blend_node_position = {300, 140}; + struct nk_vec2 output_node_position = {540, 154}; + struct node_type_color *color1; + struct node_type_color *color2; + struct node *blend; memset(editor, 0, sizeof(*editor)); editor->begin = NULL; editor->end = NULL; + /* Create the nodes */ editor->output_node = node_output_create(editor, output_node_position); - node_color_create(editor, color_node_position); - node_editor_link(editor, editor->node_buf[1], 0, editor->output_node, 0); + color1 = node_color_create(editor, color_node_position); + color2 = node_color_create(editor, color2_node_position); + blend = (struct node *)node_blend_create(editor, blend_node_position); + + /* Set the color values */ + color1->input_val[0] = 1.0f; + color1->input_val[1] = 0.0f; + color1->input_val[2] = 0.0f; + + color2->input_val[0] = 0.0f; + color2->input_val[1] = 0.0f; + color2->input_val[2] = 1.0f; + + /* Link the nodes */ + node_editor_link(editor, (struct node*)color1, 0, blend, 0); + node_editor_link(editor, (struct node*)color2, 0, blend, 1); + node_editor_link(editor, blend, 0, editor->output_node, 0); + editor->show_grid = nk_true; } @@ -330,13 +352,13 @@ node_editor(struct nk_context *ctx) } /* execute each node as a movable group */ - /* (loop through nodes) */ + /* (loop through nodes) */ while (it) { /* Output node window should not have a close button */ nk_flags nodePanel_flags = NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE; - if (it != editor->output_node) + if (it != editor->output_node) nodePanel_flags |= NK_WINDOW_CLOSABLE; - + /* calculate scrolled node window position and size */ nk_layout_space_push(ctx, nk_rect(it->bounds.x - editor->scrolling.x, it->bounds.y - editor->scrolling.y, it->bounds.w, it->bounds.h)); @@ -356,7 +378,7 @@ node_editor(struct nk_context *ctx) } if ((nodePanel->flags & NK_WINDOW_HIDDEN)) /* Node close button has been clicked */ - { + { /* Delete node */ struct node_link *link_remove; node_editor_pop(editor, it); @@ -383,16 +405,16 @@ node_editor(struct nk_context *ctx) else { /* ================= NODE CONTENT ===================== */ - + it->display_func(ctx, it); - + /* ==================================================== */ - + } nk_group_end(ctx); } - if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) + if (!(nodePanel->flags & NK_WINDOW_HIDDEN)) { /* node connector and linking */ struct nk_rect bounds; @@ -416,7 +438,7 @@ node_editor(struct nk_context *ctx) /* start linking process */ /* (set linking active) */ if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true)) { - editor->linking.active = nk_true; + editor->linking.active = nk_true; editor->linking.node = it; editor->linking.input_id = it->ID; editor->linking.input_slot = n; @@ -450,7 +472,7 @@ node_editor(struct nk_context *ctx) editor->linking.active == nk_false && it->inputs[n].is_connected == nk_true) { struct node_link *node_relink = node_editor_find_link_by_output(editor, it, n); - editor->linking.active = nk_true; + editor->linking.active = nk_true; editor->linking.node = node_relink->input_node; editor->linking.input_id = node_relink->input_node->ID; editor->linking.input_slot = node_relink->input_slot; @@ -460,12 +482,12 @@ node_editor(struct nk_context *ctx) /* (Create link) */ if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && - editor->linking.active && + editor->linking.active && editor->linking.node != it && it->inputs[n].type == editor->linking.node->outputs[editor->linking.input_slot].type && it->inputs[n].is_connected != nk_true) { editor->linking.active = nk_false; - + node_editor_link(editor, editor->linking.node, editor->linking.input_slot, it, n); } diff --git a/demo/common/nodeeditor/node_type_blend.c b/demo/common/nodeeditor/node_type_blend.c index 9f20e45cb..48d39a13a 100644 --- a/demo/common/nodeeditor/node_type_blend.c +++ b/demo/common/nodeeditor/node_type_blend.c @@ -7,6 +7,7 @@ struct node_type_blend { static struct nk_colorf *node_blend_eval(struct node *node, int oIndex) { struct node_type_blend* blend_node = (struct node_type_blend*)node; + NK_UNUSED(oIndex); return &blend_node->output_val; } @@ -35,8 +36,8 @@ static void node_blend_display(struct nk_context *ctx, struct node *node) { blend_node->blend_val = nk_propertyf(ctx, "#Blend", 0.0f, blend_node->blend_val, 1.0f, 0.01f, 0.01f); blend_amnt = blend_node->blend_val; } - - + + if(node->inputs[0].is_connected && node->inputs[1].is_connected) { blend_node->output_val.r = blend_node->input_val[0].r * (1.0f-blend_amnt) + blend_node->input_val[1].r * blend_amnt; blend_node->output_val.g = blend_node->input_val[0].g * (1.0f-blend_amnt) + blend_node->input_val[1].g * blend_amnt; @@ -48,7 +49,7 @@ static void node_blend_display(struct nk_context *ctx, struct node *node) { } } -void node_blend_create(struct node_editor *editor, struct nk_vec2 position) { +struct node_type_blend* node_blend_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_blend* blend_node = (struct node_type_blend*)node_editor_add(editor, sizeof(struct node_type_blend), "Blend", nk_rect(position.x, position.y, 180, 130), 3, 1); if (blend_node) { const struct nk_colorf blank = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -68,6 +69,7 @@ void node_blend_create(struct node_editor *editor, struct nk_vec2 position) { blend_node->node.display_func = node_blend_display; blend_node->node.eval_func = (void*(*)(struct node*, int)) node_blend_eval; - } + + return blend_node; } diff --git a/demo/common/nodeeditor/node_type_color.c b/demo/common/nodeeditor/node_type_color.c index 35809c004..4daa1723c 100644 --- a/demo/common/nodeeditor/node_type_color.c +++ b/demo/common/nodeeditor/node_type_color.c @@ -22,8 +22,8 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) int i; nk_layout_row_dynamic(ctx, 25, 1); nk_button_color(ctx, nk_rgba_cf(color_node->output_val)); - - for (i = 0; i < 4; i++) + + for (i = 0; i < 4; i++) { if (color_node->node.inputs[i].is_connected) { eval_result = *(float*)node_editor_eval_connected(node, i); @@ -42,14 +42,14 @@ static void node_color_draw(struct nk_context *ctx, struct node *node) color_node->output_val.a = color_val[3]; } -void node_color_create(struct node_editor *editor, struct nk_vec2 position) +struct node_type_color * node_color_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_color *color_node = (struct node_type_color*)node_editor_add(editor, sizeof(struct node_type_color), "Color", nk_rect(position.x, position.y, 180, 190), 4, 1); if (color_node) { int i; const struct nk_colorf white = {1.0f, 1.0f, 1.0f, 1.0f}; - + color_node->node.slot_spacing.in_top = 72.0f; color_node->node.slot_spacing.in_space = 29.0f; color_node->node.slot_spacing.out_top = 42.0f; @@ -58,10 +58,10 @@ void node_color_create(struct node_editor *editor, struct nk_vec2 position) for (i = 0; i < color_node->node.input_count; i++) color_node->node.inputs[i].type = fValue; color_node->node.outputs[0].type = fColor; - - color_node->input_val[0] = - color_node->input_val[1] = - color_node->input_val[2] = + + color_node->input_val[0] = + color_node->input_val[1] = + color_node->input_val[2] = color_node->input_val[3] = 1.0f; color_node->output_val = white; @@ -69,4 +69,5 @@ void node_color_create(struct node_editor *editor, struct nk_vec2 position) color_node->node.display_func = node_color_draw; color_node->node.eval_func = (void*(*)(struct node*, int)) node_color_eval; } + return color_node; } diff --git a/demo/common/nodeeditor/node_type_float.c b/demo/common/nodeeditor/node_type_float.c index 608632797..c3087e935 100644 --- a/demo/common/nodeeditor/node_type_float.c +++ b/demo/common/nodeeditor/node_type_float.c @@ -15,7 +15,7 @@ static void node_float_draw(struct nk_context *ctx, struct node *node) { float_node->output_val = nk_propertyf(ctx, "#Value:", 0.0f, float_node->output_val, 1.0f, 0.01f, 0.01f); } -void node_float_create(struct node_editor *editor, struct nk_vec2 position) { +struct node_type_float *node_float_create(struct node_editor *editor, struct nk_vec2 position) { struct node_type_float *float_node = (struct node_type_float*)node_editor_add(editor, sizeof(struct node_type_float), "Float", nk_rect(position.x, position.y, 180, 75), 0, 1); if (float_node) { @@ -23,4 +23,5 @@ void node_float_create(struct node_editor *editor, struct nk_vec2 position) { float_node->node.display_func = node_float_draw; float_node->node.eval_func = (void*(*)(struct node*, int)) node_float_eval; } + return float_node; }