Skip to content
A small, dependency-free node editor for dear imgui
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
example Bring the other examples up to date Jan 14, 2019
gl3w
img Add example gif Jan 19, 2019
imgui Initial commit Sep 22, 2018
.clang-format Update formatting settings Sep 30, 2018
.gitignore Update .gitignore Jan 27, 2019
LICENSE.md
README.md Update README.md Jan 27, 2019
imnodes.cpp Silence MSVC warning about operator precedence Feb 19, 2019
imnodes.h Add functions to detect when an attribute is active Feb 18, 2019
premake5.lua Add initial framework for color node editor example Dec 9, 2018

README.md

imnodes

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

Features:

  • The only dependency is dear imgui itself.
  • dear imgui-inspired immediate mode API.
  • Single header file, and single source file. Just copy-paste imnodes.h and imnodes.cpp into your project.
  • Written in the same style of C++ as dear imgui itself -- no modern C++ used.

This is an initial release of the library -- more features and fixes will be added as required!

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::Initialize();
imnodes::Initialize();

// elsewhere in the code...
imnodes::Shutdown();
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);
imnodes::Name("empty node");
imnodes::EndNode();

imnode::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);
imnodes::Name("output node");

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");
ImGui::EndAttribute();

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.

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 test if a link was created during the frame with the function call IsLinkCreated:

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

In addition to testing for new links, you can also test for whether UI elements are being hovered over or selected (clicked).

int node_id;
if (IsNodeSelected(&node_id))
{
  node_selected = node_id;
}

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(
  imnodes::ColorStyle_TitleBar, IM_COL32(11, 109, 191, 255));
imnodes::PushColorStyle(
  imnodes::ColorStyle_TitleBarSelected, IM_COL32(81, 148, 204, 255));

imnodes::BeginNode(hardcoded_node_id);
imnodes::Name("colorful node");
// 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
Style& style = imnodes::GetStyle();
style.colors[imnodes::ColorStyle_TitleBar] = IM_COL32(232, 27, 86, 255);
style.colors[imnodes::ColorStyle_TitleBarSelected] = IM_COL32(241, 108, 146, 255);

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.
You can’t perform that action at this time.