친애하는 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 콘텐츠입니다. 속성에는 노드 양쪽에 핀(작은 원)이 있습니다. 속성에는 입력 속성과 출력 속성의 두 가지 유형이 있습니다. 입력 속성 핀은 노드의 왼쪽에 있고, 출력 속성 핀은 오른쪽에 있습니다. 노드와 마찬가지로 핀도 고유하게 식별되어야 합니다.
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 ();
사용자는 노드 사이에 자신의 링크도 렌더링해야 합니다. 링크는 두 속성을 연결하는 곡선입니다. 링크는 단지 속성 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/
디렉토리를 참조하세요.