親愛なる imgui のための、依存関係のない小さなノード エディタ拡張機能。
Imnodes は、ImGui ウィンドウ内でノード エディタを作成するためのシンプルな即時モード インターフェイスを提供することを目的としています。 Imnodes は、ユーザーがノード エディターを構築するために必要な、シンプルでカスタマイズ可能なビルディング ブロックを提供します。
特徴:
imnodes.h
、 imnodes_internal.h
、およびimnodes.cpp
をコピーしてプロジェクトに ImGui と一緒に貼り付けるだけです。 このリポジトリには、 example/
下にいくつかのサンプル ファイルが含まれています。これらは、imnode で何を構築できるかを示す簡単な例を目的としています。
サンプルをビルドする必要がある場合は、提供されている CMake スクリプトを使用してビルドできます。
# 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
これは Linux ではテストされていないため、プラットフォームでは失敗する可能性があることに注意してください。
ここでは、拡張機能の使用方法の簡単な概要を示します。使用例の詳細については、README の一番下までスクロールしてください。
何かを行う前に、ライブラリを初期化する必要があります。これはdear imgui
初期化と同時に行うことができます。
ImGui::CreateContext ();
ImNodes::CreateContext ();
// elsewhere in the code...
ImNodes::DestroyContext ();
ImGui::DestroyContext ();
ノード エディターは、ノードを含むワークスペースです。ノード エディターは、他の UI 要素と同様に、ウィンドウ内でインスタンス化する必要があります。
ImGui::Begin ( " node editor " );
ImNodes::BeginNodeEditor ();
ImNodes::EndNodeEditor ();
ImGui::End ();
これで、ウィンドウにグリッドが表示されたワークスペースが表示されるはずです。空のノードをインスタンス化できるようになりました。
const int hardcoded_node_id = 1 ;
ImNodes::BeginNodeEditor ();
ImNodes::BeginNode (hardcoded_node_id);
ImGui::Dummy (ImVec2( 80 . 0f , 45 . 0f ));
ImNodes::EndNode ();
ImNodes::EndNodeEditor ();
dear imgui
のウィンドウなどのノードは一意に識別される必要があります。ただし、ワークスペース内に同じ名前のノードが多数存在する可能性があるため、識別にノード タイトルを使用することはできません。代わりに、識別には整数を使用するだけです。
属性はノードの UI コンテンツです。アトリビュートには、ノードの両側にピン (小さな円) があります。属性には、入力属性と出力属性の 2 種類があります。入力属性ピンはノードの左側にあり、出力属性ピンは右側にあります。ノードと同様に、ピンも一意に識別される必要があります。
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 ();
拡張機能は属性の内容をあまり気にしません。これは属性のピンをレンダリングするだけで、ユーザーがピン間のリンクを作成できるようになります。
タイトル バーは、 BeginNodeTitleBar
およびEndNodeTitleBar
使用してノードに追加できます。属性と同様に、タイトル バーのコンテンツを関数呼び出しの間に配置します。ノードのレイアウトは上から下の順序で構築されるため、これらの関数は属性やその他のdear imgui
UI 要素をノードに追加する前に呼び出す必要があることに注意してください。
ImNodes::BeginNode (hardcoded_node_id);
ImNodes::BeginNodeTitleBar ();
ImGui::TextUnformatted ( " output node " );
ImNodes::EndNodeTitleBar ();
// pins and other node UI content omitted...
ImNodes::EndNode ();
ユーザーはノード間の独自のリンクもレンダリングする必要があります。リンクは 2 つの属性を接続する曲線です。リンクは単なる属性 ID のペアです。また、ノードや属性と同様に、リンクも一意の整数値で識別する必要があります。
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 );
}
EndNodeEditor
が呼び出された後、関数呼び出しIsLinkCreated
を使用して、フレーム中にリンクが作成されたかどうかを確認できます。
int start_attr, end_attr;
if (ImNodes::IsLinkCreated(&start_attr, &end_attr))
{
links. push_back ( std::make_pair (start_attr, end_attr));
}
新しいリンクをチェックするだけでなく、UI 要素にマウス カーソルが置かれているかどうかもチェックできます。
int node_id;
if (ImNodes::IsNodeHovered(&node_id))
{
node_hovered = node_id;
}
ノードが選択されているかどうかを確認することもできます。ノードをクリックすることも、ボックス セレクターをクリックしてノード上にドラッグすることによって選択することもできます。
// 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 ());
}
UI イベント関連の関数の詳細については、 imnodes.h
参照してください。
dear imgui
と同様に、UI のスタイルを変更できます。 ImNodes::PushColorStyle
および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 ();
スタイルがフレームの途中で設定されていない場合は、代わりにImNodes::GetStyle
を呼び出し、値をスタイル配列に直接設定できます。
// 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 );
大きなグラフの迅速なナビゲーションを処理するには、インタラクティブなミニマップ オーバーレイを使用できます。ミニマップはズームやスクロールが可能です。エディター ノードは、それに応じてミニマップのパンを追跡します。
ImGui::Begin ( " node editor " );
ImNodes::BeginNodeEditor ();
// add nodes...
// must be called right before EndNodeEditor
ImNodes::MiniMap ();
ImNodes::EndNodeEditor ();
ImGui::End ();
エディター空間内のミニマップの相対的なサイズと角の位置は、次のように指定できます。
// 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);
ミニマップは、ユーザー定義のコールバックを介した限定的なノード ホバリングのカスタマイズもサポートしています。
// 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
ImNodes は、 imnodes_config.h
ヘッダーを提供し、コンパイル時にIMNODES_USER_CONFIG=imnodes_config.h
の定義を指定することでカスタマイズできます。
現在、ミニマップ ホバリング コールバック関数のタイプをオーバーライドすることが可能です。これは、別の言語のバインディングを生成するときに便利です。
これは、コールバックの pybind ラッパーを生成する imnodes_config.h の例です。
# 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
ImGui::Separator()
現在のウィンドウ スパンにまたがります。その結果、ノード内でセパレータを使用すると、セパレータがノードからノード エディタ グリッドにはみ出してしまいます。 ライブラリの使用方法の詳細については、 examples/
ディレクトリを参照してください。