{"id":15032214,"url":"https://github.com/nelarius/imnodes","last_synced_at":"2025-05-15T04:06:07.702Z","repository":{"id":37821669,"uuid":"149870661","full_name":"Nelarius/imnodes","owner":"Nelarius","description":"A small, dependency-free node editor for dear imgui","archived":false,"fork":false,"pushed_at":"2024-07-12T09:00:58.000Z","size":4088,"stargazers_count":2225,"open_issues_count":60,"forks_count":272,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-05-15T04:05:57.279Z","etag":null,"topics":["cpp","gamedev","imgui","node-editor","tool","ui"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Nelarius.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-22T11:27:12.000Z","updated_at":"2025-05-14T19:41:38.000Z","dependencies_parsed_at":"2023-01-23T18:16:09.664Z","dependency_job_id":"5795dd89-f0ef-42bd-8fab-99ca3ea7d851","html_url":"https://github.com/Nelarius/imnodes","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nelarius%2Fimnodes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nelarius%2Fimnodes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nelarius%2Fimnodes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nelarius%2Fimnodes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nelarius","download_url":"https://codeload.github.com/Nelarius/imnodes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254270646,"owners_count":22042859,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","gamedev","imgui","node-editor","tool","ui"],"created_at":"2024-09-24T20:17:45.637Z","updated_at":"2025-05-15T04:06:02.687Z","avatar_url":"https://github.com/Nelarius.png","language":"C++","readme":"\u003ch1 align=\"center\"\u003eimnodes\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eA small, dependency-free node editor extension for \u003ca href=\"https://github.com/ocornut/imgui\"\u003edear imgui\u003c/a\u003e.\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/Nelarius/imnodes/master/img/imnodes.gif?token=ADH_jEpqbBrw0nH-BUmOip490dyO2CnRks5cVZllwA%3D%3D\"\u003e\n\u003c/p\u003e\n\n[![Build Status](https://github.com/nelarius/imnodes/workflows/Build/badge.svg)](https://github.com/nelarius/imnodes/actions?workflow=Build)\n\nImnodes 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.\n\nFeatures:\n\n* Create nodes, links, and pins in an immediate-mode style. The user controls all the state.\n* Nest ImGui widgets inside nodes\n* Simple distribution, just copy-paste `imnodes.h`, `imnodes_internal.h`, and `imnodes.cpp` into your project along side ImGui.\n\n## Examples\n\nThis 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.\n\nIf you need to build the examples, you can use the provided CMake script to do so.\n\n```bash\n# Initialize the vcpkg submodule\n$ git submodule update --init\n# Run the generation step and build\n$ cmake -B build-release/ -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake\n$ cmake --build build-release -- -j\n```\n\nNote that this has not been tested on Linux and is likely to fail on the platform.\n\n## A brief tour\n\nHere is a small overview of how the extension is used. For more information on example usage, scroll to the bottom of the README.\n\nBefore anything can be done, the library must be initialized. This can be done at the same time as `dear imgui` initialization.\n\n```cpp\nImGui::CreateContext();\nImNodes::CreateContext();\n\n// elsewhere in the code...\nImNodes::DestroyContext();\nImGui::DestroyContext();\n```\n\nThe node editor is a workspace which contains nodes. The node editor must be instantiated within a window, like any other UI element.\n\n```cpp\nImGui::Begin(\"node editor\");\n\nImNodes::BeginNodeEditor();\nImNodes::EndNodeEditor();\n\nImGui::End();\n```\n\nNow you should have a workspace with a grid visible in the window. An empty node can now be instantiated:\n\n```cpp\nconst int hardcoded_node_id = 1;\n\nImNodes::BeginNodeEditor();\n\nImNodes::BeginNode(hardcoded_node_id);\nImGui::Dummy(ImVec2(80.0f, 45.0f));\nImNodes::EndNode();\n\nImNodes::EndNodeEditor();\n```\n\nNodes, 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.\n\nAttributes 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.\n\n```cpp\nImNodes::BeginNode(hardcoded_node_id);\n\nconst int output_attr_id = 2;\nImNodes::BeginOutputAttribute(output_attr_id);\n// in between Begin|EndAttribute calls, you can call ImGui\n// UI functions\nImGui::Text(\"output pin\");\nImNodes::EndOutputAttribute();\n\nImNodes::EndNode();\n```\n\nThe 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.\n\nA 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.\n\n```cpp\nImNodes::BeginNode(hardcoded_node_id);\n\nImNodes::BeginNodeTitleBar();\nImGui::TextUnformatted(\"output node\");\nImNodes::EndNodeTitleBar();\n\n// pins and other node UI content omitted...\n\nImNodes::EndNode();\n```\n\nThe 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:\n\n```cpp\nstd::vector\u003cstd::pair\u003cint, int\u003e\u003e links;\n// elsewhere in the code...\nfor (int i = 0; i \u003c links.size(); ++i)\n{\n  const std::pair\u003cint, int\u003e p = links[i];\n  // in this case, we just use the array index of the link\n  // as the unique identifier\n  ImNodes::Link(i, p.first, p.second);\n}\n```\n\nAfter `EndNodeEditor` has been called, you can check if a link was created during the frame with the function call `IsLinkCreated`:\n\n```cpp\nint start_attr, end_attr;\nif (ImNodes::IsLinkCreated(\u0026start_attr, \u0026end_attr))\n{\n  links.push_back(std::make_pair(start_attr, end_attr));\n}\n```\n\nIn addition to checking for new links, you can also check whether UI elements are being hovered over by the mouse cursor:\n\n```cpp\nint node_id;\nif (ImNodes::IsNodeHovered(\u0026node_id))\n{\n  node_hovered = node_id;\n}\n```\n\nYou 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.\n\n```cpp\n// Note that since many nodes can be selected at once, we first need to query the number of\n// selected nodes before getting them.\nconst int num_selected_nodes = ImNodes::NumSelectedNodes();\nif (num_selected_nodes \u003e 0)\n{\n  std::vector\u003cint\u003e selected_nodes;\n  selected_nodes.resize(num_selected_nodes);\n  ImNodes::GetSelectedNodes(selected_nodes.data());\n}\n```\n\nSee `imnodes.h` for more UI event-related functions.\n\nLike `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`.\n\n```cpp\n// set the titlebar color of an individual node\nImNodes::PushColorStyle(\n  ImNodesCol_TitleBar, IM_COL32(11, 109, 191, 255));\nImNodes::PushColorStyle(\n  ImNodesCol_TitleBarSelected, IM_COL32(81, 148, 204, 255));\n\nImNodes::BeginNode(hardcoded_node_id);\n// node internals here...\nImNodes::EndNode();\n\nImNodes::PopColorStyle();\nImNodes::PopColorStyle();\n```\n\nIf 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.\n\n```cpp\n// set the titlebar color for all nodes\nImNodesStyle\u0026 style = ImNodes::GetStyle();\nstyle.colors[ImNodesCol_TitleBar] = IM_COL32(232, 27, 86, 255);\nstyle.colors[ImNodesCol_TitleBarSelected] = IM_COL32(241, 108, 146, 255);\n```\n\nTo 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.\n\n```cpp\nImGui::Begin(\"node editor\");\n\nImNodes::BeginNodeEditor();\n\n// add nodes...\n\n// must be called right before EndNodeEditor\nImNodes::MiniMap();\nImNodes::EndNodeEditor();\n\nImGui::End();\n```\n\nThe relative sizing and corner location of the mini-map in the editor space can be specified like so:\n\n```cpp\n// MiniMap is a square region with a side length that is 20% the largest editor canvas dimension\n// See ImNodesMiniMapLocation_ for other corner locations\nImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight);\n```\n\nThe mini-map also supports limited node hovering customization through a user-defined callback.\n```cpp\n// User callback\nvoid mini_map_node_hovering_callback(int node_id, void* user_data)\n{\n  ImGui::SetTooltip(\"This is node %d\", node_id);\n}\n\n// Later on...\nImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight, mini_map_node_hovering_callback, custom_user_data);\n\n// 'custom_user_data' can be used to supply extra information needed for drawing within the callback\n```\n\n## Customizing ImNodes\n\nImNodes can be customized by providing an `imnodes_config.h` header and specifying defining `IMNODES_USER_CONFIG=imnodes_config.h` when compiling.\n\nIt is currently possible to override the type of the minimap hovering callback function. This is useful when generating bindings for another language.\n\nHere's an example imnodes_config.h, which generates a pybind wrapper for the callback.\n```cpp\n#pragma once\n\n#include \u003cpybind11/functional.h\u003e\n\nnamespace pybind11 {\n\ninline bool PyWrapper_Check(PyObject *o) { return true; }\n\nclass wrapper : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(wrapper, object, PyWrapper_Check)\n    wrapper(void* x) { m_ptr = (PyObject*)x; }\n    explicit operator bool() const { return m_ptr != nullptr \u0026\u0026 m_ptr != Py_None; }\n};\n\n} //namespace pybind11\n\nnamespace py = pybind11;\n\n#define ImNodesMiniMapNodeHoveringCallback py::wrapper\n\n#define ImNodesMiniMapNodeHoveringCallbackUserData py::wrapper\n```\n\n## Known issues\n\n* `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.\n\n## Further information\n\nSee the `examples/` directory to see library usage in greater detail.\n\n* simple.cpp is a simple hello-world style program which displays two nodes\n* 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\n* color_node_editor.cpp is a more complete example, which shows how a simple node editor is implemented with a graph.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnelarius%2Fimnodes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnelarius%2Fimnodes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnelarius%2Fimnodes/lists"}