Code Monkey home page Code Monkey logo

imnodes's Introduction

imnodes

A small, dependency-free node editor extension for dear imgui.

Build Status

Imnodes aims to provide a simple, immediate-mode interface for creating a node editor within an ImGui window. Imnodes provides simple, customizable building blocks that a user needs to build their node editor.

Features:

  • Create nodes, links, and pins in an immediate-mode style. The user controls all the state.
  • Nest ImGui widgets inside nodes
  • Simple distribution, just copy-paste imnodes.h, imnodes_internal.h, and imnodes.cpp into your project along side ImGui.

Examples

This repository includes a few example files, under example/. They are intended as simple examples giving you an idea of what you can build with imnodes.

If you need to build the examples, you can use the provided CMake script to do so.

# Initialize the vcpkg submodule
$ git submodule update --init
# Run the generation step and build
$ cmake -B build-release/ -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake
$ cmake --build build-release -- -j

Note that this has not been tested on Linux and is likely to fail on the platform.

A brief tour

Here is a small overview of how the extension is used. For more information on example usage, scroll to the bottom of the README.

Before anything can be done, the library must be initialized. This can be done at the same time as dear imgui initialization.

ImGui::CreateContext();
ImNodes::CreateContext();

// elsewhere in the code...
ImNodes::DestroyContext();
ImGui::DestroyContext();

The node editor is a workspace which contains nodes. The node editor must be instantiated within a window, like any other UI element.

ImGui::Begin("node editor");

ImNodes::BeginNodeEditor();
ImNodes::EndNodeEditor();

ImGui::End();

Now you should have a workspace with a grid visible in the window. An empty node can now be instantiated:

const int hardcoded_node_id = 1;

ImNodes::BeginNodeEditor();

ImNodes::BeginNode(hardcoded_node_id);
ImGui::Dummy(ImVec2(80.0f, 45.0f));
ImNodes::EndNode();

ImNodes::EndNodeEditor();

Nodes, like windows in dear imgui must be uniquely identified. But we can't use the node titles for identification, because it should be possible to have many nodes of the same name in the workspace. Instead, you just use integers for identification.

Attributes are the UI content of the node. An attribute will have a pin (the little circle) on either side of the node. There are two types of attributes: input, and output attributes. Input attribute pins are on the left side of the node, and output attribute pins are on the right. Like nodes, pins must be uniquely identified.

ImNodes::BeginNode(hardcoded_node_id);

const int output_attr_id = 2;
ImNodes::BeginOutputAttribute(output_attr_id);
// in between Begin|EndAttribute calls, you can call ImGui
// UI functions
ImGui::Text("output pin");
ImNodes::EndOutputAttribute();

ImNodes::EndNode();

The extension doesn't really care what is in the attribute. It just renders the pin for the attribute, and allows the user to create links between pins.

A title bar can be added to the node using BeginNodeTitleBar and EndNodeTitleBar. Like attributes, you place your title bar's content between the function calls. Note that these functions have to be called before adding attributes or other dear imgui UI elements to the node, since the node's layout is built in order, top-to-bottom.

ImNodes::BeginNode(hardcoded_node_id);

ImNodes::BeginNodeTitleBar();
ImGui::TextUnformatted("output node");
ImNodes::EndNodeTitleBar();

// pins and other node UI content omitted...

ImNodes::EndNode();

The user has to render their own links between nodes as well. A link is a curve which connects two attributes. A link is just a pair of attribute ids. And like nodes and attributes, links too have to be identified by unique integer values:

std::vector<std::pair<int, int>> links;
// elsewhere in the code...
for (int i = 0; i < links.size(); ++i)
{
  const std::pair<int, int> p = links[i];
  // in this case, we just use the array index of the link
  // as the unique identifier
  ImNodes::Link(i, p.first, p.second);
}

After EndNodeEditor has been called, you can check if a link was created during the frame with the function call IsLinkCreated:

int start_attr, end_attr;
if (ImNodes::IsLinkCreated(&start_attr, &end_attr))
{
  links.push_back(std::make_pair(start_attr, end_attr));
}

In addition to checking for new links, you can also check whether UI elements are being hovered over by the mouse cursor:

int node_id;
if (ImNodes::IsNodeHovered(&node_id))
{
  node_hovered = node_id;
}

You can also check to see if any node has been selected. Nodes can be clicked on, or they can be selected by clicking and dragging the box selector over them.

// Note that since many nodes can be selected at once, we first need to query the number of
// selected nodes before getting them.
const int num_selected_nodes = ImNodes::NumSelectedNodes();
if (num_selected_nodes > 0)
{
  std::vector<int> selected_nodes;
  selected_nodes.resize(num_selected_nodes);
  ImNodes::GetSelectedNodes(selected_nodes.data());
}

See imnodes.h for more UI event-related functions.

Like dear imgui, the style of the UI can be changed. You can set the color style of individual nodes, pins, and links mid-frame by calling ImNodes::PushColorStyle and ImNodes::PopColorStyle.

// set the titlebar color of an individual node
ImNodes::PushColorStyle(
  ImNodesCol_TitleBar, IM_COL32(11, 109, 191, 255));
ImNodes::PushColorStyle(
  ImNodesCol_TitleBarSelected, IM_COL32(81, 148, 204, 255));

ImNodes::BeginNode(hardcoded_node_id);
// node internals here...
ImNodes::EndNode();

ImNodes::PopColorStyle();
ImNodes::PopColorStyle();

If the style is not being set mid-frame, ImNodes::GetStyle can be called instead, and the values can be set into the style array directly.

// set the titlebar color for all nodes
ImNodesStyle& style = ImNodes::GetStyle();
style.colors[ImNodesCol_TitleBar] = IM_COL32(232, 27, 86, 255);
style.colors[ImNodesCol_TitleBarSelected] = IM_COL32(241, 108, 146, 255);

To handle quicker navigation of large graphs you can use an interactive mini-map overlay. The mini-map can be zoomed and scrolled. Editor nodes will track the panning of the mini-map accordingly.

ImGui::Begin("node editor");

ImNodes::BeginNodeEditor();

// add nodes...

// must be called right before EndNodeEditor
ImNodes::MiniMap();
ImNodes::EndNodeEditor();

ImGui::End();

The relative sizing and corner location of the mini-map in the editor space can be specified like so:

// MiniMap is a square region with a side length that is 20% the largest editor canvas dimension
// See ImNodesMiniMapLocation_ for other corner locations
ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight);

The mini-map also supports limited node hovering customization through a user-defined callback.

// User callback
void mini_map_node_hovering_callback(int node_id, void* user_data)
{
  ImGui::SetTooltip("This is node %d", node_id);
}

// Later on...
ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight, mini_map_node_hovering_callback, custom_user_data);

// 'custom_user_data' can be used to supply extra information needed for drawing within the callback

Customizing ImNodes

ImNodes can be customized by providing an imnodes_config.h header and specifying defining IMNODES_USER_CONFIG=imnodes_config.h when compiling.

It is currently possible to override the type of the minimap hovering callback function. This is useful when generating bindings for another language.

Here's an example imnodes_config.h, which generates a pybind wrapper for the callback.

#pragma once

#include <pybind11/functional.h>

namespace pybind11 {

inline bool PyWrapper_Check(PyObject *o) { return true; }

class wrapper : public object {
public:
    PYBIND11_OBJECT_DEFAULT(wrapper, object, PyWrapper_Check)
    wrapper(void* x) { m_ptr = (PyObject*)x; }
    explicit operator bool() const { return m_ptr != nullptr && m_ptr != Py_None; }
};

} //namespace pybind11

namespace py = pybind11;

#define ImNodesMiniMapNodeHoveringCallback py::wrapper

#define ImNodesMiniMapNodeHoveringCallbackUserData py::wrapper

Known issues

  • ImGui::Separator() spans the current window span. As a result, using a separator inside a node will result in the separator spilling out of the node into the node editor grid.

Further information

See the examples/ directory to see library usage in greater detail.

  • simple.cpp is a simple hello-world style program which displays two nodes
  • save_load.cpp is enables you to add and remove nodes and links, and serializes/deserializes them, so that the program state is retained between restarting the program
  • color_node_editor.cpp is a more complete example, which shows how a simple node editor is implemented with a graph.

imnodes's People

Contributors

auburn avatar bootzin avatar briancairl avatar brukted avatar debaetsd avatar ekcoh avatar julesfouchy avatar ketoo avatar kfields avatar mathisloge avatar mrmodez avatar nelarius avatar ousttrue avatar potrepka avatar richardhozak avatar smilediver avatar sonoro1234 avatar spiderkeys avatar web-eworks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imnodes's Issues

Zooming in/out

Any plans in the future for zooming in and out? Would be really useful. Love your work, cheers!

g.Windows.Size != g.WindowsTempSortBuffer.Size

Running the code at the end in a plugin of my application causes the following exception to be thrown. I'm totally lost as to why this would happen.

    // This usually assert if there is a mismatch between the ImGuiWindowFlags_ChildWindow / ParentWindow values and DC.ChildWindows[] in parents, aka we've done something wrong.
    IM_ASSERT(g.Windows.Size == g.WindowsTempSortBuffer.Size);
	static bool init = false;
	if (!init) {
		imnodes::Initialize();
		init = true;
	}
	
	ImGui::Begin("simple node editor");

	imnodes::BeginNodeEditor();
	imnodes::EndNodeEditor();

	ImGui::End();

[BUG] Invalid selected nodes

Recently I tried a node editor that is able to delete selected nodes. The problem is that imnodes uses the node index to keep track of selected nodes which causes from assertion fails to invalid nodes being reported as selected. The solution I took was to clear the selection every time I deleted a selected node. I can make a pr if you like the solution.

Input / Output Attribute or input/output pins at same height

This imgui node library is really nice!

In my setup, i have need to make an "input & output" attribute, where i give a label to something coming in to the node, which also then goes out of the node.

Alternately, if i could give a label to the input and none to the output, but have the pins show at the same height, that would solve my problem as well.

Is there a way to do this currently?

If not, does anyone have thoughts on how the code could be modified to do this?

Thanks!

Deleted nodes and links remain selected

When a node is selected by clicking it or by drawing a selection box, we can know about it by calling GetSelectedNodes and finding its id in an array of NumSelectedNodes elements. I noticed that, if the node is deleted while selected, those functions still return its id until a new click interaction is performed by the user. While this is not a big problem, I found it out because it generated a little issue for me.

I tried to implement locally a temporary fix, but before sending a PR I would like to have some feedback about the issue itself and the need to solve it. For now I thought it might be useful to simply show here the fix I just tried and wait for people's opinion.

Since NumSelectedNodes must be called after EndNodeEditor, in EndNodeEditor I inserted the following code, starting from line 2175, after pools update and before the call to draw_list_sort_channels_by_depth

//for each selected node
for (int selection_idx = 0; selection_idx < editor.selected_node_indices.Size;
     selection_idx++)
{
    //check if the node is currently in use
    int *node_id_ptr = &editor.selected_node_indices[selection_idx];
    if (!editor.nodes.in_use[*node_id_ptr])
    {
        //if it is not used, then from now on it is also not selected
        editor.selected_node_indices.erase_unsorted(node_id_ptr);
    }
}

Something very similar follows to handle the same issue for the selected links.

Crash on object_pool_update line 874 when cleaning a node editor and then adding a node.

Hi,

I have a crash that I can reproduce in 3 frames. First you need to draw two nodes in a editor. Then draw none and finally draw one.
The application will assert on line 874 in the function object_pool_update.

Here is a code exemple:

                ImGui::Begin("test");
		imnodes::BeginNodeEditor();
		if (i == 0) { // frame 1

			imnodes::BeginNode(0);
			imnodes::EndNode();
			imnodes::BeginNode(1);
			imnodes::EndNode();

			i++;
		} else if (i == 1) { // frame 2

			i++;
		} else if (i == 2) { // frame 3

			imnodes::BeginNode(0);
			imnodes::EndNode();
			i++;
		}
		imnodes::EndNodeEditor();
		ImGui::End();

You don't need anything more than that. The crash doesn't happen if on frame 3 the node use another id so it is maybe an intended crash ? If that's the case I still think that at least the error reporting is sub-par but still I don't see why this couldn't work.

I do admit that I'm not familiar with imnodes so I might be missing something, I hope that you have all the informations you need.

Node in the front won't move if a node containing an ImGui widget with is behind it.

If the editor contains two nodes, clicking and dragging on the one in the front won't be possible if an imgui widget is behind your mouse cursor, and you will be interacting with that widget instead, even if you cannot see it. I noticed it when playing around with sliders. You can also still interact with the pins of the node behind the one shown. Perhaps it is related to the changes in this commit? fd96ac2

Add an attribute flag to create/destroy links when visually snapping

When creating a link the bezier curve visually snaps to nearby attributes, IsLinkedCreated/Destroyed could be based on this visual snapping instead of the mouse click. It would show the effects of the link you are creating as you drag it over different attributes, which is good feedback for the user.

Hopefully you understand what I'm envisioning, I think this would work well alongside the AttributeFlags_EnableLinkDetachWithDragClick flag. Thanks for this great node graph editor!

memory leak

While debugging in visual studio, I noticed that after adding a bunch of nodes the memory use would continually grow.
I think just adding onw node is doing the same thing, but the behavior is more noticeable with many nodes.
I'm not 100% sure, but Intel Inspector says it's coming from here
image

Any plans on zooming?

Hi, are there any plans on implementing zooming? Asking if I should look into it myself.

Support for deselecting a node, or not selecting a node when an input becomes active

Currently, having an active attribute selects the node, which prevents users from dragging things in an attribute, because it drags the node instead. For example, focusing an input field in an attribute will prevent the user from dragging to select text within the field, and if its multiline the scrollbar cannot be dragged with the mouse.

To solve this, a flag could be added to attributes to prevent them from selecting the node when becoming active, or a method could be added to deselect a node, and that could be called when IsAnyAttributeActive returns true.

edit: If you end up adding the method to deselect the node (or all nodes), it could also be used to, e.g., deselect all nodes after deleting them. That is, if I delete all selected nodes, it would be nice if imnodes didn't still return those IDs in the next GetSelectedNodes call

Clicking in other windows deselects nodes

I have a property panel that shows info for the selected node, but whenever i click on the property panel, the selected nodes are cleared due to this code in EndNodeEditor() (like 1343)

    // check to see if the mouse was near any node
    if (g.node_hovered == INVALID_INDEX)
    {
        if (is_mouse_clicked)
        {
            editor.selected_nodes.clear();
        }
    }

Changing the if to this fixes my issue. Is this correct / should i submit a pull request?

    // check to see if the mouse was near any node
    if (g.node_hovered == INVALID_INDEX && ImGui::IsWindowHovered())
    {
        if (is_mouse_clicked)
        {
            editor.selected_nodes.clear();
        }
    }

Issue with dlls

Would it be possible to add a public method similar to the one below?

void SetImGuiContext(ImGuiContext* ctx) {
    ImGui::SetCurrentContext(ctx);
}

The reason behind this is that globals are not shared between dlls, so when compiling imgui into a dll and imnodes into another, the context is not shared, and I end up getting access violations

You can read more about this here

I can also submit a PR to this if you wish, but I'm not exactly familiar with c++, although it does seems like an easy change

How to draw a rectangle between the background and nodes.

Hi,

I'd like to draw a rectangle with color by "ImGui::GetWindowDrawList()-AddRectFilled", and the layout of the rectangle should between the background and nodes.

Why do this?

Sometimes, we want to group some nodes as one group, to let the user know it clear, we would draw a background rectangle for these nodes.

May I know how to do that?

Thanks

Node remains selected after click and drag

Disclaimer: Not sure if this is a bug or a feature, but it's not consistent with other node editors I've used.

Create a node editor and put two nodes in it. Click and drag one of them to move it. Now click and drag the other one. The first one remained selected so they both move when you try to move the second one.

I expected to be able to move each node individually without having to deselect each after moving them.

Node overlap rendering is not correct

When dragging nodes over each other, the rendering is glitchy due to all node frames being rendered in a loop in EndNodeEditor. It would be better to render the frame after EndNode is called so that the node frame and ImGui UI are at least rendered in the same order.

node_overlap_rendering_problem

Feature request: Zoom

A zoom feature would be really useful for large node graphs. Are you planning to implement this? Or maybe some other option for faster navigation through the graph?

Troubleshooting user interaction doesn't seem trivial

Where to find / how to understand the default user interaction commands?
I just started exploring imnodes and successfully used IsLinkCreated to create links with drag and drop from one pin to an other one, but on the other side, I don't find a way to make IsLinkDestroyed return true. I tried to push the DELETE key selecting the link and also to drag the link away from a pin without success. I don't know how to proceed in order to understand if I am not pushing the right key or if in my software the event is not triggered because of an issue or misconfiguration.

BUG: Crash on link creation

If I were to set up my node editor such that I draw a node, then a link, and then more nodes, like in the pseudo-code below, creating a second link, and only a second link, causes an assert - crashing the whole app. I have found 2 solutions to this issue which are also below.

The Problem

I store links within my nodes, so to simplify things I wrote something like below:

for (auto node : nodes)
{
	imnodes::BeginNode(node.id);
  // draw node things
	imnodes::EndNode();

	for (auto links : node.links)
	{
		// draw link
		imnodes::Link(link.id, link.start_id, link.end_id);
	}
}

However, because I intertwine nodes and links I get,
crash

The solution(s)

  1. Don't intertwine nodes and links (ie. draw all nodes, and then draw all links)
  2. Change the following line in imnodes.cpp's click_interaction_update function, and under the link creation case
if (snapping_pin_changed && g.snap_link_idx.has_value())

to

if (snapping_pin_changed && g.snap_link_idx.has_value()
    && editor.click_interaction_state.link_creation.end_pin_idx.has_value())

About the Pin's shape and Node's icon

Now we PushColorStyle function to change the color for node and pin.

How about adding a way to support to change the shape of Pin? We could get a good result if we can change the shape when using the node system with some of the basic shapes listed below:

PinShape
{
CIRCLE,
TRIANGLE,
SQUARE,
PENTAGON,
STAR,
SEMICIRCLE,
HEX,
CROSS,
RING,
ARROW,
QUATREFOIL,
RHOMBUS,
HEART,
OCTAGON,
};

Besides, it would be great if there have a way to change the node's icon like this:

How do you detect that a link should be destroyed/disconnected?

In the README, there's a section about checking for new links where you instruct users to call imnodes::IsLinkCreated().

Is there an equivalent function for detecting that a link should be destroyed? In Blender, when you click and drag one of the endpoints of an existing link, it disconnects the two nodes and the link follows the mouse until you reconnect it somewhere or let go of the mouse button and it disappears. Is similar functionality possible with imnodes?

Multiple nodes can be selected by left-clicking

Multi-node selection is half-baked at the moment: multiple nodes can be selected by left-clicking. The intention is to be able to click-select multiple nodes with a modifier pressed, e.g. shift.

multinode_selection

Box selection triggers when moving the ImGui window that contains the node editor

Create a window and put a node editor inside. Run the program. If you click in the window top bar then drag it up and left, a selection box appears inside the node editor. I didn't expect a box selection tool when I clicked and dragged somewhere outside the node editor.

Edit: this also happens if you click and drag somewhere outside the ImGui window. For example, click and drag from just outside the right side of the window up to just above the top of the window. A selection box will appear in the node editor.

node id oddities

Perhaps I might be doing something very wrong.

Using visual studio 2019.

In the hello.cpp example project;

Create a second node (by copy-pasting the first node).
Starting from 0, id the node and attributes in ascending order.

You'll get this odd effect:
node

Start from 1, and things will work as expected.

If I make the first node's ID larger than the attribute ID (similar way to colornode), I get this assertion error:
assert(node_idx_depth_order.Size == g.node_idx_submission_order.Size); in imnodes.cpp

It also appears that I get this assertion error again with arbitrary values, so it's probably not tied with the attribute id values.

I've had to go into the graph.h file and make the return values start from 1 and adjust when the node id is determined to get my node editor to create new nodes.

Reusing freed memory?

First, thank you for this library!

However, IMHO, The find_or_create_new function in ObjectPool can lead to a memory error. Indeed, this function allocates memory to grow memory for internal container objects (Using the ImVector::resize function). But many structures store NodeData, PinData or NodeData pointer directly.

In my tests if the number of PinData grows (from 8, to 12, then 16), a random error occured in ImVec2 get_screen_space_pin_coordinates(const PinData& pin) with random data in PinData.
To quickly fix it, I add the following reserve in EditorContext constructor but this is not a real solution.

EditorContext()
    : nodes(), pins(), links(), panning(0.f, 0.f), link_dragged(),
      box_selector()
{
  nodes.pool.reserve(1024);
  nodes.in_use.reserve(1024);
  nodes.free_list.reserve(1024);
  nodes.id_map.Data.reserve(1024);

  pins.pool.reserve(1024);
  pins.in_use.reserve(1024);
  pins.free_list.reserve(1024);
  pins.id_map.Data.reserve(1024);

  links.pool.reserve(1024);
  links.in_use.reserve(1024);
  links.free_list.reserve(1024);
  links.id_map.Data.reserve(1024);
}

Typo in README tutorial

In the README, I think there's a typo. In the section about creating an output attribute, you have the following code snippet:

...
ImGui::Text("output pin");
ImGui::EndAttribute();

imnodes::EndNode();
...

I believe it should be:

...
ImGui::Text("output pin");
imnodes::EndAttribute();   // this should be imnodes, not ImGui

imnodes::EndNode();
...

Separators overflow node width

When using ImGui::Separator() within a node, its width isn't respected and the separator appears to continue infinitely.

connecting two edges to one input crashes color_node_editor evaluator

assert(value_stack.size() == 3ull); fails if you connect two wires to one input. It leaves an extra value on the stack.

One possible recreation is to create 3 boxes: sine, sine and output. and connect both sine outputs to the 'r' input of 'output'. But any other connection of two outputs to an input failed for me as well.

Linking Errors

I'm getting the below linking errors when I attempt to include imnodes in my project. I can include the files and it recognizes the functions but won't compile them. ImGui works fine when I don't attempt to use imnodes. Any thoughts.

Thanks!

VisualState.obj : error LNK2019: unresolved external symbol "void __cdecl imnodes::Initialize(void)" (?Initialize@imnodes@@YAXXZ) referenced in function "public: void __cdecl VisualState::VisualZone(void)" (?VisualZone@VisualState@@QEAAXXZ) 1>VisualState.obj : error LNK2019: unresolved external symbol "void __cdecl imnodes::Shutdown(void)" (?Shutdown@imnodes@@YAXXZ) referenced in function "public: void __cdecl VisualState::VisualZone(void)" (?VisualZone@VisualState@@QEAAXXZ) 1>VisualState.obj : error LNK2019: unresolved external symbol "void __cdecl imnodes::BeginNode(int)" (?BeginNode@imnodes@@YAXH@Z) referenced in function "public: void __cdecl VisualState::VisualZone(void)" (?VisualZone@VisualState@@QEAAXXZ) 1>VisualState.obj : error LNK2019: unresolved external symbol "void __cdecl imnodes::EndNode(void)" (?EndNode@imnodes@@YAXXZ) referenced in function "public: void __cdecl VisualState::VisualZone(void)" (?VisualZone@VisualState@@QEAAXXZ) 1>VisualState.obj : error LNK2019: unresolved external symbol "void __cdecl imnodes::BeginOutputAttribute(int,enum imnodes::PinShape)" (?BeginOutputAttribute@imnodes@@YAXHW4PinShape@1@@Z) referenced in function "public: void __cdecl VisualState::VisualZone(void)" (?VisualZone@VisualState@@QEAAXXZ) 1>VisualState.obj : error LNK2019: unresolved external symbol "void __cdecl imnodes::EndAttribute(void)" (?EndAttribute@imnodes@@YAXXZ) referenced in function "public: void __cdecl VisualState::VisualZone(void)" (?VisualZone@VisualState@@QEAAXXZ)

Screen only renders in lower left corner

I've tried to compile & run this app on macOS but unfortunately it looks like this:
image
As you can see, the display is only shown on the lower left corner as if it was the entire screen, and dragging/resizing any window outside that quarter is impossible (it disappears as if I was moving the window outside the visible screen). However the mouse input detects the entire screen, which makes it rather difficult to interact with the imgui windows, as I have to click and drag where there's nothing.

My guess is that the high-dpi screen affects the rendering somehow.
Hope to get this fixed soon! The library looks awesome, good job!

always come with link error

3>imnodes.obj : error LNK2001: unresolved external symbol "public: static char const * const ImGuiTextBuffer::EmptyString" (?EmptyString@ImGuiTextBuffer@@2QBDB)
3>F:\Cpp\Falcor\Bin\x64\Release\MultiPassPostProcess.exe : fatal error LNK1120: 1 unresolved externals
I have try to switch many different projects,and it turns out every of them has the same link issue.I spend 2 hours on it ,didn't find anything wrong.

Overlapping node selection

I noticed some wierd selection behaviour if two nodes overlap:
overlapping nodes
The node in the foreground is not selected but rather the node that was first created (with the lower id I guess).

Crashes when selecting a link overlapping a node

When clicking on a link that is above a node the assert assert(editor.click_interaction_type == ClickInteractionType_None); fails.

Steps to repoduce

Add three nodes. Connect two. Then move the third under the link and click on the link.
grafik
Note the sizes of are off because i use a 32pt font.

How to set the canvas's position as (0,0)

Hi,
I'd like to integrate this library as a part of my blueprint framework as it looks simple and easy to use. In the blueprint design window, I'd like to let the user reset the position of the canvas if we have many nodes on the canvas and do not know where are we now.

I didn't found the function via the source code, may I know how to do that?

Thanks

Box Selection when window is not focused/hovered

When the window with the node editor is covered by another window and the other window gets dragged, a box selection appears in the node editor window.
One might add a check for ImGui::IsWindowHovered().
This code in EndNodeEditor() fixes this behavior:

const bool is_mouse_clicked_in_canvas =
           is_mouse_clicked &&
           ImGui::IsWindowHovered() &&
           g.canvas_rect_screen_space.Contains(ImGui::GetMousePos());

Option to render nodes over top of links.

When rendering a complex node graph, the links will often be in the way of editing the nodes. If there was an option to render the links under everything else it would fix many problems I am having when changing node attributes.

I know this might be too hard to implement because of the immediate nature of imgui.

Add ability to disconnect a link by clicking and dragging

In Blender it's possible to click and drag a link to disconnect it from a node, which is a very convenient feature.

Current plans:

  • Left-click and drag to detach link (link detaching signalled via the IsLinkDestroyed function)
  • Add some kind of option for enabling/disabling "click and drag to detach"
  • Modifier + left-click over link to snap link wire to mouse cursor and detach link
  • Option for enabling/disabling "snap wire to mouse cursor"

building problem SDL

Hi,
I am trying to build the project on Linux using premake5 gmake

When I do the make, I obtain the following error:

==== Building imgui (debug) ====
imgui_impl_sdl.cpp
../../imgui/imgui_impl_sdl.cpp:47:10: fatal error: SDL.h: No such file or directory
 #include <SDL.h>
          ^~~~~~~
compilation terminated.
imgui.make:141: recipe for target 'obj/Debug/imgui/imgui_impl_sdl.o' failed
make[1]: *** [obj/Debug/imgui/imgui_impl_sdl.o] Error 1
Makefile:40: recipe for target 'imgui' failed
make: *** [imgui] Error 2

I tried to manually modify the imgui.make file to add -I/usr/include/SDL to the path but I only add many errors.

I never used premake before, so it's totally probable that i'm doing something wrong here.

issues with example/save_load.cpp?

Thanks for sharing this nice project!

  1. object_pool_update clears the in_use flag to false for all nodes. At exit, none of the node positions are saved to save_load.ini, since the SaveEditorStateToIniString checks for in_use.
    Commenting out this check makes it work. Why was that check there?

  2. I had to move the node creation (released key A) right after BeginNodeEditor and before the rendering of all nodes, otherwise some assert triggered in EndNodeEditor. This happens when you start with an empty editor (no nodes, no ini file) and press 'a'. The assert was this one:

void draw_list_activate_node_background(const int node_idx)
{
    const int submission_idx =
        g.node_idx_to_submission_idx.GetInt(static_cast<ImGuiID>(node_idx), -1);
    assert(submission_idx != -1);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.