Merge remote-tracking branch 'origin/main'

# Conflicts:
#	src/AnimGraph/AnimGraphEditor.cc
RefactorUnifiedBlendTreeStateMachineHandling
Martin Felis 2024-03-16 20:08:45 +01:00
commit 1ef53d6486
24 changed files with 1067 additions and 666 deletions

View File

@ -1,11 +1,3 @@
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
// Crude implementation of JSON value object and parser.
//
// VERSION 0.1
@ -569,7 +561,7 @@ private:
if (end != hex.c_str() + hex.size())
return false;
c = v;
c = static_cast<int>(v);
return true;
}
@ -896,8 +888,3 @@ bool value::save(const string& path, const int indent, const char indent_char) c
# endif
} // namespace crude_json
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif

View File

@ -1,10 +1,4 @@
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
// Crude implementation of JSON value object and parser.
// Crude implementation of JSON value object and parser.
//
// VERSION 0.1
//
@ -253,9 +247,4 @@ template <> inline number* value::get_ptr<number>() { if (m_Type =
} // namespace crude_json
# endif // __CRUDE_JSON_H__
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif
# endif // __CRUDE_JSON_H__

View File

@ -1,4 +1,70 @@
v0.9.1 (WIP):
v0.9.4 (WIP):
NEW: Editor: Add smooth zoom (#266)
BUGFIX: Canvas: Remember index of first command buffer to not miss updating any used (#260)
BUGFIX: Editor: Don't duplicated ImVec2/ImVec3 == != operators defined since ImGui r19002 (#268)
BUGFIX: Examples: Use imgui_impl_opengl3_loader.h instead of gl3w (#264)
v0.9.3 (2023-10-14):
CHANGE: Canvas: Use ImDrawCallback_ImCanvas macro as draw callback sentinel (#256), thanks @nspitko
BUGFIX: Canvas: Ensure SentinelDrawCallback cleanup (#255)
BUGFIX: Editor: Don't call Reasume/Suspend on invisible canvas (#255)
v0.9.2 (2023-09-01):
NEW: Editor: Add offset of hover/select to style (thanks @MultiPain)
NEW: Editor: Add IMGUI_NODE_EDITOR_API to support building editor as a shared library (#189)
NEW: Canvas: Add IMGUIEX_CANVAS_API to support building canvas as a shared library (#189)
CHANGE: Editor: Support ImGui r18836 after SetItemUsingMouseWheel removal (#218), thanks @ocornut
CHANGE: Editor: Define IMGUI_DEFINE_MATH_OPERATORS before <imgui.h> (#209), thanks @ocornut
CHANGE: Examples: Define IMGUI_DEFINE_MATH_OPERATORS before <imgui.h> (#209), thanks @ocornut
CHANGE: Canvas: Don't use deprecated SetItemAllowOverlap (#250)
CHANGE: Examples: Don't use deprecated SetItemAllowOverlap (#250)
CHANGE: Editor: Define IMGUI_DEFINE_MATH_OPERATORS before <imgui.h> (#209), thanks @ocornut
CHANGE: Editor: Unary operator- for ImVec2 is defined by ImGui since r18955 (#248)
BUGFIX: Editor: Correctly initialize 'width' for view resize code (thx @gnif)
BUGFIX: Examples: Handle node deletion before links (#182)
Deleting node queue connected links for deletion.
BUGFIX: Examples: Simplify and fix drawing of node header line (#180)
BUGFIX: Editor: Cleanup tabs.
BUGFIX: Editor: Use ImGuiKey directly with ImGui r18822 (#183)
BUGFIX: Examples: Use ImGuiKey directly with ImGui r18822 (#183)
BUGFIX: Examples: Use ImGuiKey_KeypadEnter with ImGui r18604 (#183)
BUGFIX: Examples: Add missing <cstdint> include for std::intptr_t (#199)
BUGFIX: Examples: Don't use empty string as identifier
BUGFIX: Editor: Clean long to int implicit cast warning in crude_json
BUGFIX: Canvas: Ensure canvas draw commands are separated from other ImGui draw commands (#205, #250)
BUGFIX: Editor: Don't call Canvas.End() when Canvas.Begin() failed (#186), thanks @pthom, @TheZoc
v0.9.1 (2022-08-27):
CHANGE: Remove unwanted extra frame height from node bottom

View File

@ -69,15 +69,12 @@ endif()
if (OpenGL_FOUND)
set(HAVE_OPENGL YES)
find_package(gl3w REQUIRED)
# Explicitly select embedded GL3W loader
target_compile_definitions(application PRIVATE IMGUI_IMPL_OPENGL_LOADER_GL3W)
target_include_directories(application PRIVATE ${OPENGL_INCLUDE_DIR})
target_link_libraries(application PRIVATE ${OPENGL_gl_LIBRARY} gl3w)
target_link_libraries(application PRIVATE ${OPENGL_gl_LIBRARY})
list(APPEND _Application_Sources
source/imgui_impl_opengl3.cpp
source/imgui_impl_opengl3.h
source/imgui_impl_opengl3_loader.h
)
endif()

View File

@ -1,5 +1,8 @@
# pragma once
# include <imgui.h>
# if !defined(IMGUI_VERSION_NUM) || (IMGUI_VERSION_NUM < 18822)
# include <type_traits>
// https://stackoverflow.com/a/8597498
@ -46,3 +49,17 @@ static inline int GetEnumValueForD()
{
return KeyTester_ImGuiKey_D::Get<ImGuiKey_>(nullptr);
}
# else
static inline ImGuiKey GetEnumValueForF()
{
return ImGuiKey_F;
}
static inline ImGuiKey GetEnumValueForD()
{
return ImGuiKey_D;
}
# endif

View File

@ -1,31 +1,36 @@
// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 2.x 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
// Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
// About WebGL/ES:
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
// - This is done automatically on iOS, Android and Emscripten targets.
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
// About Desktop OpenGL function loaders:
// Modern Desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// About GLSL version:
// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string.
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
// Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL);
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
@ -40,48 +45,22 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
// Attempt to auto-detect the default Desktop GL loader based on available header files.
// If auto-detection fails or doesn't select the same GL loader file as used by your application,
// you are likely to get a crash in ImGui_ImplOpenGL3_Init().
// You can explicitly select a loader by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
#if !defined(IMGUI_IMPL_OPENGL_ES2) \
&& !defined(IMGUI_IMPL_OPENGL_ES3) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
&& !defined(IMGUI_IMPL_OPENGL_ES3)
// Try to detect GLES on matching platforms
#if defined(__APPLE__)
#include "TargetConditionals.h"
#include <TargetConditionals.h>
#endif
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
#elif defined(__EMSCRIPTEN__)
#elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
// Otherwise try to detect supported Desktop OpenGL loaders..
#elif defined(__has_include)
#if __has_include(<GL/glew.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLEW
#elif __has_include(<glad/glad.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
#elif __has_include(<glad/gl.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLAD2
#elif __has_include(<GL/gl3w.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GL3W
#elif __has_include(<glbinding/glbinding.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3
#elif __has_include(<glbinding/Binding.h>)
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2
#else
#error "Cannot detect OpenGL loader!"
#endif
#else
#define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W embedded in our repository
// Otherwise imgui_impl_opengl3_loader.h will be used.
#endif
#endif
#endif // #ifndef IMGUI_DISABLE

View File

@ -93,7 +93,11 @@ bool ImGui_ImplWin32_Init(void* hwnd)
io.KeyMap[ImGuiKey_Space] = VK_SPACE;
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
# if defined(IMGUI_VERSION_NUM) && (IMGUI_VERSION_NUM >= 18604)
io.KeyMap[ImGuiKey_KeypadEnter] = VK_RETURN;
# else
io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
# endif
io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V';

View File

@ -4,6 +4,7 @@
# include "platform.h"
# include <algorithm>
# include <cstdint> // std::intptr_t
# if PLATFORM(WINDOWS)
# define NOMINMAX
@ -31,8 +32,10 @@ using namespace gl;
# include <glbinding/glbinding.h>// Initialize with glbinding::initialize()
# include <glbinding/gl/gl.h>
using namespace gl;
# else
# elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
# include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
# else
# include "imgui_impl_opengl3_loader.h"
# endif
struct ImTexture

View File

@ -1,10 +1,9 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include <application.h>
#include "utilities/builders.h"
#include "utilities/widgets.h"
#include <imgui_node_editor.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui_internal.h>
#include <string>
@ -648,7 +647,9 @@ struct Example:
ImGui::DragFloat("Node Rounding", &editorStyle.NodeRounding, 0.1f, 0.0f, 40.0f);
ImGui::DragFloat("Node Border Width", &editorStyle.NodeBorderWidth, 0.1f, 0.0f, 15.0f);
ImGui::DragFloat("Hovered Node Border Width", &editorStyle.HoveredNodeBorderWidth, 0.1f, 0.0f, 15.0f);
ImGui::DragFloat("Hovered Node Border Offset", &editorStyle.HoverNodeBorderOffset, 0.1f, -40.0f, 40.0f);
ImGui::DragFloat("Selected Node Border Width", &editorStyle.SelectedNodeBorderWidth, 0.1f, 0.0f, 15.0f);
ImGui::DragFloat("Selected Node Border Offset", &editorStyle.SelectedNodeBorderOffset, 0.1f, -40.0f, 40.0f);
ImGui::DragFloat("Pin Rounding", &editorStyle.PinRounding, 0.1f, 0.0f, 40.0f);
ImGui::DragFloat("Pin Border Width", &editorStyle.PinBorderWidth, 0.1f, 0.0f, 15.0f);
ImGui::DragFloat("Link Strength", &editorStyle.LinkStrength, 1.0f, 0.0f, 500.0f);
@ -682,7 +683,7 @@ struct Example:
ImGui::EndHorizontal();
static ImGuiTextFilter filter;
filter.Draw("", paneWidth);
filter.Draw("##filter", paneWidth);
ImGui::Spacing();
@ -765,6 +766,9 @@ struct Example:
}
bool isSelected = std::find(selectedNodes.begin(), selectedNodes.end(), node.ID) != selectedNodes.end();
# if IMGUI_VERSION_NUM >= 18967
ImGui::SetNextItemAllowOverlap();
# endif
if (ImGui::Selectable((node.Name + "##" + std::to_string(reinterpret_cast<uintptr_t>(node.ID.AsPointer()))).c_str(), &isSelected))
{
if (io.KeyCtrl)
@ -793,7 +797,11 @@ struct Example:
auto drawList = ImGui::GetWindowDrawList();
ImGui::SetCursorScreenPos(iconPanelPos);
# if IMGUI_VERSION_NUM < 18967
ImGui::SetItemAllowOverlap();
# else
ImGui::SetNextItemAllowOverlap();
# endif
if (node.SavedState.empty())
{
if (ImGui::InvisibleButton("save", ImVec2((float)saveIconWidth, (float)saveIconHeight)))
@ -813,7 +821,11 @@ struct Example:
}
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
# if IMGUI_VERSION_NUM < 18967
ImGui::SetItemAllowOverlap();
# else
ImGui::SetNextItemAllowOverlap();
# endif
if (!node.SavedState.empty())
{
if (ImGui::InvisibleButton("restore", ImVec2((float)restoreIconWidth, (float)restoreIconHeight)))
@ -837,7 +849,9 @@ struct Example:
}
ImGui::SameLine(0, 0);
# if IMGUI_VERSION_NUM < 18967
ImGui::SetItemAllowOverlap();
# endif
ImGui::Dummy(ImVec2(0, (float)restoreIconHeight));
ImGui::PopID();
@ -1537,17 +1551,6 @@ struct Example:
if (ed::BeginDelete())
{
ed::LinkId linkId = 0;
while (ed::QueryDeletedLink(&linkId))
{
if (ed::AcceptDeletedItem())
{
auto id = std::find_if(m_Links.begin(), m_Links.end(), [linkId](auto& link) { return link.ID == linkId; });
if (id != m_Links.end())
m_Links.erase(id);
}
}
ed::NodeId nodeId = 0;
while (ed::QueryDeletedNode(&nodeId))
{
@ -1558,6 +1561,17 @@ struct Example:
m_Nodes.erase(id);
}
}
ed::LinkId linkId = 0;
while (ed::QueryDeletedLink(&linkId))
{
if (ed::AcceptDeletedItem())
{
auto id = std::find_if(m_Links.begin(), m_Links.end(), [linkId](auto& link) { return link.ID == linkId; });
if (id != m_Links.end())
m_Links.erase(id);
}
}
}
ed::EndDelete();
}

View File

@ -7,8 +7,8 @@
// CREDITS
// Written by Michal Cichon
//------------------------------------------------------------------------------
# include "builders.h"
# define IMGUI_DEFINE_MATH_OPERATORS
# include "builders.h"
# include <imgui_internal.h>
@ -72,15 +72,11 @@ void util::BlueprintNodeBuilder::End()
headerColor, GetStyle().NodeRounding, 1 | 2);
#endif
auto headerSeparatorMin = ImVec2(HeaderMin.x, HeaderMax.y);
auto headerSeparatorMax = ImVec2(HeaderMax.x, HeaderMin.y);
if ((headerSeparatorMax.x > headerSeparatorMin.x) && (headerSeparatorMax.y > headerSeparatorMin.y))
if (ContentMin.y > HeaderMax.y)
{
drawList->AddLine(
headerSeparatorMin + ImVec2(-(8 - halfBorderWidth), -0.5f),
headerSeparatorMax + ImVec2( (8 - halfBorderWidth), -0.5f),
ImVec2(HeaderMin.x - (8 - halfBorderWidth), HeaderMax.y - 0.5f),
ImVec2(HeaderMax.x + (8 - halfBorderWidth), HeaderMax.y - 0.5f),
ImColor(255, 255, 255, 96 * alpha / (3 * 255)), 1.0f);
}
}

View File

@ -1,5 +1,5 @@
# include "drawing.h"
# define IMGUI_DEFINE_MATH_OPERATORS
# include "drawing.h"
# include <imgui_internal.h>
void ax::Drawing::DrawIcon(ImDrawList* drawList, const ImVec2& a, const ImVec2& b, IconType type, bool filled, ImU32 color, ImU32 innerColor)

View File

@ -1,5 +1,5 @@
# include "widgets.h"
# define IMGUI_DEFINE_MATH_OPERATORS
# include "widgets.h"
# include <imgui_internal.h>
void ax::Widgets::Icon(const ImVec2& size, IconType type, bool filled, const ImVec4& color/* = ImVec4(1, 1, 1, 1)*/, const ImVec4& innerColor/* = ImVec4(0, 0, 0, 0)*/)

View File

@ -1,5 +1,5 @@
# include <imgui.h>
# define IMGUI_DEFINE_MATH_OPERATORS
# include <imgui.h>
# include <imgui_internal.h>
# include <imgui_canvas.h>
# include <application.h>

View File

@ -1,11 +1,3 @@
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//------------------------------------------------------------------------------
// VERSION 0.1
//
@ -403,19 +395,17 @@ inline ImCubicBezierIntersectResult ImCubicBezierLineIntersect(const ImVec2& p0,
return count;
};
/*
https://github.com/kaishiqi/Geometric-Bezier/blob/master/GeometricBezier/src/kaishiqi/geometric/intersection/Intersection.as
Start with Bezier using Bernstein polynomials for weighting functions:
(1-t^3)P0 + 3t(1-t)^2P1 + 3t^2(1-t)P2 + t^3P3
Expand and collect terms to form linear combinations of original Bezier
controls. This ends up with a vector cubic in t:
(-P0+3P1-3P2+P3)t^3 + (3P0-6P1+3P2)t^2 + (-3P0+3P1)t + P0
/\ /\ /\ /\
|| || || ||
c3 c2 c1 c0
*/
// https://github.com/kaishiqi/Geometric-Bezier/blob/master/GeometricBezier/src/kaishiqi/geometric/intersection/Intersection.as
//
// Start with Bezier using Bernstein polynomials for weighting functions:
// (1-t^3)P0 + 3t(1-t)^2P1 + 3t^2(1-t)P2 + t^3P3
//
// Expand and collect terms to form linear combinations of original Bezier
// controls. This ends up with a vector cubic in t:
// (-P0+3P1-3P2+P3)t^3 + (3P0-6P1+3P2)t^2 + (-3P0+3P1)t + P0
// /\ /\ /\ /\
// || || || ||
// c3 c2 c1 c0
// Calculate the coefficients
auto c3 = -p0 + 3 * p1 - 3 * p2 + p3;
@ -683,7 +673,3 @@ inline void ImCubicBezierFixedStep(F& callback, const ImCubicBezierPoints& curve
//------------------------------------------------------------------------------
# endif // __IMGUI_BEZIER_MATH_INL__
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif

View File

@ -1,4 +1,6 @@
# define IMGUI_DEFINE_MATH_OPERATORS
# ifndef IMGUI_DEFINE_MATH_OPERATORS
# define IMGUI_DEFINE_MATH_OPERATORS
# endif
# include "imgui_canvas.h"
# include <type_traits>
@ -25,6 +27,11 @@
static constexpr bool value = (sizeof(yes_type) == sizeof(test<mixin>(0))); \
}
// Special sentinel value. This needs to be unique, so allow it to be overridden in the user's ImGui config
# ifndef ImDrawCallback_ImCanvas
# define ImDrawCallback_ImCanvas (ImDrawCallback)(-2)
# endif
namespace ImCanvasDetails {
DECLARE_HAS_MEMBER(HasFringeScale, _FringeScale);
@ -115,7 +122,7 @@ bool ImGuiEx::Canvas::Begin(ImGuiID id, const ImVec2& size)
// #debug: Canvas content.
//m_DrawList->AddRectFilled(m_StartPos, m_StartPos + m_CurrentSize, IM_COL32(0, 0, 0, 64));
m_DrawList->AddRect(m_WidgetRect.Min, m_WidgetRect.Max, IM_COL32(255, 0, 255, 64));
//m_DrawList->AddRect(m_WidgetRect.Min, m_WidgetRect.Max, IM_COL32(255, 0, 255, 64));
ImGui::SetCursorScreenPos(ImVec2(0.0f, 0.0f));
@ -131,6 +138,10 @@ bool ImGuiEx::Canvas::Begin(ImGuiID id, const ImVec2& size)
EnterLocalSpace();
# if IMGUI_VERSION_NUM >= 18967
ImGui::SetNextItemAllowOverlap();
# endif
// Emit dummy widget matching bounds of the canvas.
ImGui::SetCursorScreenPos(m_ViewRect.Min);
ImGui::Dummy(m_ViewRect.GetSize());
@ -162,7 +173,9 @@ void ImGuiEx::Canvas::End()
ImGui::GetCurrentWindow()->DC.CursorMaxPos = m_WindowCursorMaxBackup;
# if IMGUI_VERSION_NUM < 18967
ImGui::SetItemAllowOverlap();
# endif
// Emit dummy widget matching bounds of the canvas.
ImGui::SetCursorScreenPos(m_WidgetPosition);
@ -407,6 +420,15 @@ void ImGuiEx::Canvas::EnterLocalSpace()
auto clipped_clip_rect = m_DrawList->_ClipRectStack.back();
ImGui::PopClipRect();
# if IMGUI_EX_CANVAS_DEFERED()
m_Ranges.resize(m_Ranges.Size + 1);
m_CurrentRange = &m_Ranges.back();
m_CurrentRange->BeginComandIndex = ImMax(m_DrawList->CmdBuffer.Size, 0);
m_CurrentRange->BeginVertexIndex = m_DrawList->_VtxCurrentIdx + ImVtxOffsetRef(m_DrawList);
# endif
m_DrawListCommadBufferSize = ImMax(m_DrawList->CmdBuffer.Size, 0);
m_DrawListStartVertexIndex = m_DrawList->_VtxCurrentIdx + ImVtxOffsetRef(m_DrawList);
// Make sure we do not share draw command with anyone. We don't want to mess
// with someones clip rectangle.
@ -421,16 +443,9 @@ void ImGuiEx::Canvas::EnterLocalSpace()
//
// More investigation is needed. To get to the bottom of this.
if ((!m_DrawList->CmdBuffer.empty() && m_DrawList->CmdBuffer.back().ElemCount > 0) || m_DrawList->_Splitter._Count > 1)
m_DrawList->AddDrawCmd();
m_DrawList->AddCallback(ImDrawCallback_ImCanvas, nullptr);
# if IMGUI_EX_CANVAS_DEFERED()
m_Ranges.resize(m_Ranges.Size + 1);
m_CurrentRange = &m_Ranges.back();
m_CurrentRange->BeginComandIndex = ImMax(m_DrawList->CmdBuffer.Size - 1, 0);
m_CurrentRange->BeginVertexIndex = m_DrawList->_VtxCurrentIdx + ImVtxOffsetRef(m_DrawList);
# endif
m_DrawListCommadBufferSize = ImMax(m_DrawList->CmdBuffer.Size - 1, 0);
m_DrawListStartVertexIndex = m_DrawList->_VtxCurrentIdx + ImVtxOffsetRef(m_DrawList);
m_DrawListFirstCommandIndex = ImMax(m_DrawList->CmdBuffer.Size - 1, 0);
# if defined(IMGUI_HAS_VIEWPORT)
auto window = ImGui::GetCurrentWindow();
@ -510,7 +525,7 @@ void ImGuiEx::Canvas::LeaveLocalSpace()
}
// Move clip rectangles to screen space.
for (int i = m_DrawListCommadBufferSize; i < m_DrawList->CmdBuffer.size(); ++i)
for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer.size(); ++i)
{
auto& command = m_DrawList->CmdBuffer[i];
command.ClipRect.x = command.ClipRect.x * m_View.Scale + m_ViewTransformPosition.x;
@ -529,7 +544,7 @@ void ImGuiEx::Canvas::LeaveLocalSpace()
}
// Move clip rectangles to screen space.
for (int i = m_DrawListCommadBufferSize; i < m_DrawList->CmdBuffer.size(); ++i)
for (int i = m_DrawListFirstCommandIndex; i < m_DrawList->CmdBuffer.size(); ++i)
{
auto& command = m_DrawList->CmdBuffer[i];
command.ClipRect.x = command.ClipRect.x + m_ViewTransformPosition.x;
@ -539,6 +554,15 @@ void ImGuiEx::Canvas::LeaveLocalSpace()
}
}
// Remove sentinel draw command if present
if (m_DrawListCommadBufferSize > 0)
{
if (m_DrawList->CmdBuffer.size() > m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize].UserCallback == ImDrawCallback_ImCanvas)
m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize);
else if (m_DrawList->CmdBuffer.size() >= m_DrawListCommadBufferSize && m_DrawList->CmdBuffer[m_DrawListCommadBufferSize - 1].UserCallback == ImDrawCallback_ImCanvas)
m_DrawList->CmdBuffer.erase(m_DrawList->CmdBuffer.Data + m_DrawListCommadBufferSize - 1);
}
auto& fringeScale = ImFringeScaleRef(m_DrawList);
fringeScale = m_LastFringeScale;

View File

@ -51,6 +51,10 @@
# include <imgui.h>
# include <imgui_internal.h> // ImRect, ImFloor
#ifndef IMGUIEX_CANVAS_API
#define IMGUIEX_CANVAS_API
#endif
namespace ImGuiEx {
struct CanvasView
@ -106,13 +110,13 @@ struct Canvas
//
// You can query size of the canvas while it is being drawn
// by calling Rect().
bool Begin(const char* id, const ImVec2& size);
bool Begin(ImGuiID id, const ImVec2& size);
IMGUIEX_CANVAS_API bool Begin(const char* id, const ImVec2& size);
IMGUIEX_CANVAS_API bool Begin(ImGuiID id, const ImVec2& size);
// Ends interaction with canvas plane.
//
// Must be called only when Begin() retuned true.
void End();
IMGUIEX_CANVAS_API void End();
// Sets visible region of canvas plane.
//
@ -120,50 +124,50 @@ struct Canvas
// corner of the canvas.
//
// Scale greater than 1 make canvas content be bigger, less than 1 smaller.
void SetView(const ImVec2& origin, float scale);
void SetView(const CanvasView& view);
IMGUIEX_CANVAS_API void SetView(const ImVec2& origin, float scale);
IMGUIEX_CANVAS_API void SetView(const CanvasView& view);
// Centers view over specific point on canvas plane.
//
// View will be centered on specific point by changing origin
// but not scale.
void CenterView(const ImVec2& canvasPoint);
IMGUIEX_CANVAS_API void CenterView(const ImVec2& canvasPoint);
// Calculates view over specific point on canvas plane.
CanvasView CalcCenterView(const ImVec2& canvasPoint) const;
IMGUIEX_CANVAS_API CanvasView CalcCenterView(const ImVec2& canvasPoint) const;
// Centers view over specific rectangle on canvas plane.
//
// Whole rectangle will fit in canvas view. This will affect both
// origin and scale.
void CenterView(const ImRect& canvasRect);
IMGUIEX_CANVAS_API void CenterView(const ImRect& canvasRect);
// Calculates view over specific rectangle on canvas plane.
CanvasView CalcCenterView(const ImRect& canvasRect) const;
IMGUIEX_CANVAS_API CanvasView CalcCenterView(const ImRect& canvasRect) const;
// Suspends canvas by returning to normal ImGui transformation space.
// While suspended UI will not be drawn on canvas plane.
//
// Calls to Suspend()/Resume() are symetrical. Each call to Suspend()
// must be matched with call to Resume().
void Suspend();
void Resume();
IMGUIEX_CANVAS_API void Suspend();
IMGUIEX_CANVAS_API void Resume();
// Transforms point from canvas plane to ImGui.
ImVec2 FromLocal(const ImVec2& point) const;
ImVec2 FromLocal(const ImVec2& point, const CanvasView& view) const;
IMGUIEX_CANVAS_API ImVec2 FromLocal(const ImVec2& point) const;
IMGUIEX_CANVAS_API ImVec2 FromLocal(const ImVec2& point, const CanvasView& view) const;
// Transforms vector from canvas plant to ImGui.
ImVec2 FromLocalV(const ImVec2& vector) const;
ImVec2 FromLocalV(const ImVec2& vector, const CanvasView& view) const;
IMGUIEX_CANVAS_API ImVec2 FromLocalV(const ImVec2& vector) const;
IMGUIEX_CANVAS_API ImVec2 FromLocalV(const ImVec2& vector, const CanvasView& view) const;
// Transforms point from ImGui to canvas plane.
ImVec2 ToLocal(const ImVec2& point) const;
ImVec2 ToLocal(const ImVec2& point, const CanvasView& view) const;
IMGUIEX_CANVAS_API ImVec2 ToLocal(const ImVec2& point) const;
IMGUIEX_CANVAS_API ImVec2 ToLocal(const ImVec2& point, const CanvasView& view) const;
// Transforms vector from ImGui to canvas plane.
ImVec2 ToLocalV(const ImVec2& vector) const;
ImVec2 ToLocalV(const ImVec2& vector, const CanvasView& view) const;
IMGUIEX_CANVAS_API ImVec2 ToLocalV(const ImVec2& vector) const;
IMGUIEX_CANVAS_API ImVec2 ToLocalV(const ImVec2& vector, const CanvasView& view) const;
// Returns widget bounds.
//
@ -175,7 +179,7 @@ struct Canvas
const ImRect& ViewRect() const { return m_ViewRect; }
// Calculates visible region for view.
ImRect CalcViewRect(const CanvasView& view) const;
IMGUIEX_CANVAS_API ImRect CalcViewRect(const CanvasView& view) const;
// Returns current view.
const CanvasView& View() const { return m_View; }
@ -232,6 +236,7 @@ private:
Range* m_CurrentRange = nullptr;
# endif
int m_DrawListFirstCommandIndex = 0;
int m_DrawListCommadBufferSize = 0;
int m_DrawListStartVertexIndex = 0;

View File

@ -15,10 +15,10 @@
//------------------------------------------------------------------------------
# include <imgui.h>
# ifndef IMGUI_DEFINE_MATH_OPERATORS
# define IMGUI_DEFINE_MATH_OPERATORS
# endif
# include <imgui.h>
# include <imgui_internal.h>
@ -30,10 +30,14 @@ struct ImLine
//------------------------------------------------------------------------------
# if IMGUI_VERSION_NUM < 19002
inline bool operator==(const ImVec2& lhs, const ImVec2& rhs);
inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs);
# endif
inline ImVec2 operator*(const float lhs, const ImVec2& rhs);
# if IMGUI_VERSION_NUM < 18955
inline ImVec2 operator-(const ImVec2& lhs);
# endif
//------------------------------------------------------------------------------

View File

@ -19,6 +19,7 @@
//------------------------------------------------------------------------------
# if IMGUI_VERSION_NUM < 19002
inline bool operator==(const ImVec2& lhs, const ImVec2& rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
@ -28,16 +29,19 @@ inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs)
{
return lhs.x != rhs.x || lhs.y != rhs.y;
}
# endif
inline ImVec2 operator*(const float lhs, const ImVec2& rhs)
{
return ImVec2(lhs * rhs.x, lhs * rhs.y);
}
# if IMGUI_VERSION_NUM < 18955
inline ImVec2 operator-(const ImVec2& lhs)
{
return ImVec2(-lhs.x, -lhs.y);
}
# endif
//------------------------------------------------------------------------------

View File

@ -1,10 +1,3 @@
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//------------------------------------------------------------------------------
// VERSION 0.9.1
//
@ -42,6 +35,58 @@
static bool const value = sizeof(test<T>(0)) == sizeof(yes); \
};
namespace ax {
namespace NodeEditor {
namespace Detail {
# if !defined(IMGUI_VERSION_NUM) || (IMGUI_VERSION_NUM < 18822)
# define DECLARE_KEY_TESTER(Key) \
DECLARE_HAS_NESTED(Key, Key) \
struct KeyTester_ ## Key \
{ \
template <typename T> \
static int Get(typename std::enable_if<has_nested_ ## Key<ImGuiKey_>::value, T>::type*) \
{ \
return ImGui::GetKeyIndex(T::Key); \
} \
\
template <typename T> \
static int Get(typename std::enable_if<!has_nested_ ## Key<ImGuiKey_>::value, T>::type*) \
{ \
return -1; \
} \
}
DECLARE_KEY_TESTER(ImGuiKey_F);
DECLARE_KEY_TESTER(ImGuiKey_D);
static inline int GetKeyIndexForF()
{
return KeyTester_ImGuiKey_F::Get<ImGuiKey_>(nullptr);
}
static inline int GetKeyIndexForD()
{
return KeyTester_ImGuiKey_D::Get<ImGuiKey_>(nullptr);
}
# else
static inline ImGuiKey GetKeyIndexForF()
{
return ImGuiKey_F;
}
static inline ImGuiKey GetKeyIndexForD()
{
return ImGuiKey_D;
}
# endif
} // namespace Detail
} // namespace NodeEditor
} // namespace ax
//------------------------------------------------------------------------------
namespace ed = ax::NodeEditor::Detail;
@ -169,34 +214,34 @@ static void ImDrawListSplitter_Grow(ImDrawList* draw_list, ImDrawListSplitter* s
static void ImDrawList_ChannelsGrow(ImDrawList* draw_list, int channels_count)
{
ImDrawListSplitter_Grow(draw_list, &draw_list->_Splitter, channels_count);
ImDrawListSplitter_Grow(draw_list, &draw_list->_Splitter, channels_count);
}
static void ImDrawListSplitter_SwapChannels(ImDrawListSplitter* splitter, int left, int right)
{
IM_ASSERT(left < splitter->_Count && right < splitter->_Count);
if (left == right)
return;
IM_ASSERT(left < splitter->_Count && right < splitter->_Count);
if (left == right)
return;
auto currentChannel = splitter->_Current;
auto currentChannel = splitter->_Current;
auto* leftCmdBuffer = &splitter->_Channels[left]._CmdBuffer;
auto* leftIdxBuffer = &splitter->_Channels[left]._IdxBuffer;
auto* rightCmdBuffer = &splitter->_Channels[right]._CmdBuffer;
auto* rightIdxBuffer = &splitter->_Channels[right]._IdxBuffer;
auto* leftCmdBuffer = &splitter->_Channels[left]._CmdBuffer;
auto* leftIdxBuffer = &splitter->_Channels[left]._IdxBuffer;
auto* rightCmdBuffer = &splitter->_Channels[right]._CmdBuffer;
auto* rightIdxBuffer = &splitter->_Channels[right]._IdxBuffer;
leftCmdBuffer->swap(*rightCmdBuffer);
leftIdxBuffer->swap(*rightIdxBuffer);
leftCmdBuffer->swap(*rightCmdBuffer);
leftIdxBuffer->swap(*rightIdxBuffer);
if (currentChannel == left)
splitter->_Current = right;
else if (currentChannel == right)
splitter->_Current = left;
if (currentChannel == left)
splitter->_Current = right;
else if (currentChannel == right)
splitter->_Current = left;
}
static void ImDrawList_SwapChannels(ImDrawList* drawList, int left, int right)
{
ImDrawListSplitter_SwapChannels(&drawList->_Splitter, left, right);
ImDrawListSplitter_SwapChannels(&drawList->_Splitter, left, right);
}
static void ImDrawList_SwapSplitter(ImDrawList* drawList, ImDrawListSplitter& splitter)
@ -655,7 +700,7 @@ void ed::Node::Draw(ImDrawList* drawList, DrawFlags flags)
drawList->ChannelsSetCurrent(m_Channel + c_NodeBaseChannel);
DrawBorder(drawList, borderColor, editorStyle.SelectedNodeBorderWidth);
DrawBorder(drawList, borderColor, editorStyle.SelectedNodeBorderWidth, editorStyle.SelectedNodeBorderOffset);
}
else if (!IsGroup(this) && (flags & Hovered))
{
@ -664,16 +709,18 @@ void ed::Node::Draw(ImDrawList* drawList, DrawFlags flags)
drawList->ChannelsSetCurrent(m_Channel + c_NodeBaseChannel);
DrawBorder(drawList, borderColor, editorStyle.HoveredNodeBorderWidth);
DrawBorder(drawList, borderColor, editorStyle.HoveredNodeBorderWidth, editorStyle.HoverNodeBorderOffset);
}
}
void ed::Node::DrawBorder(ImDrawList* drawList, ImU32 color, float thickness)
void ed::Node::DrawBorder(ImDrawList* drawList, ImU32 color, float thickness, float offset)
{
if (thickness > 0.0f)
{
drawList->AddRect(m_Bounds.Min, m_Bounds.Max,
color, m_Rounding, c_AllRoundCornersFlags, thickness);
const ImVec2 extraOffset = ImVec2(offset, offset);
drawList->AddRect(m_Bounds.Min - extraOffset, m_Bounds.Max + extraOffset,
color, ImMax(0.0f, m_Rounding + offset), c_AllRoundCornersFlags, thickness);
}
}
@ -1090,9 +1137,9 @@ void ed::EditorContext::Begin(const char* id, const ImVec2& size)
if (!m_IsInitialized)
{
// Cycle canvas so it has a change to setup its size before settings are loaded
m_Canvas.Begin(id, canvasSize);
m_Canvas.End();
// Cycle canvas, so it has a chance to initialize its size before settings are loaded
if (m_Canvas.Begin(id, canvasSize))
m_Canvas.End();
LoadSettings();
m_IsInitialized = true;
@ -1161,7 +1208,7 @@ void ed::EditorContext::Begin(const char* id, const ImVec2& size)
auto centerY = (previousVisibleRect.Max.y + previousVisibleRect.Min.y) * 0.5f;
auto currentVisibleRect = m_Canvas.ViewRect();
auto currentAspectRatio = currentVisibleRect.GetHeight() ? (currentVisibleRect.GetWidth() / currentVisibleRect.GetHeight()) : 0.0f;
auto width = previousVisibleRect.GetHeight();
auto width = previousVisibleRect.GetWidth();
auto height = previousVisibleRect.GetHeight();
if (m_Config.CanvasSizeMode == ax::NodeEditor::CanvasSizeMode::FitVerticalView)
@ -1918,7 +1965,8 @@ void ed::EditorContext::Suspend(SuspendFlags flags)
IM_ASSERT(m_DrawList != nullptr && "Suspend was called outiside of Begin/End.");
auto lastChannel = m_DrawList->_Splitter._Current;
m_DrawList->ChannelsSetCurrent(m_ExternalChannel);
m_Canvas.Suspend();
if (m_IsCanvasVisible)
m_Canvas.Suspend();
m_DrawList->ChannelsSetCurrent(lastChannel);
if ((flags & SuspendFlags::KeepSplitter) != SuspendFlags::KeepSplitter)
ImDrawList_SwapSplitter(m_DrawList, m_Splitter);
@ -1931,13 +1979,14 @@ void ed::EditorContext::Resume(SuspendFlags flags)
ImDrawList_SwapSplitter(m_DrawList, m_Splitter);
auto lastChannel = m_DrawList->_Splitter._Current;
m_DrawList->ChannelsSetCurrent(m_ExternalChannel);
m_Canvas.Resume();
if (m_IsCanvasVisible)
m_Canvas.Resume();
m_DrawList->ChannelsSetCurrent(lastChannel);
}
bool ed::EditorContext::IsSuspended()
{
return m_Canvas.IsSuspended();
return m_Canvas.IsSuspended();
}
bool ed::EditorContext::IsFocused()
@ -2513,9 +2562,12 @@ ed::Control ed::EditorContext::BuildControl(bool allowOffscreen)
if (!allowOffscreen && !m_IsHovered)
return Control();
# if IMGUI_VERSION_NUM >= 17909
# if IMGUI_VERSION_NUM >= 18836
if (m_IsHoveredWithoutOverlapp)
ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY);
# elif IMGUI_VERSION_NUM >= 17909
if (m_IsHoveredWithoutOverlapp)
ImGui::SetItemUsingMouseWheel();
# endif
return Control(hotObject, activeObject, clickedObject, doubleClickedObject,
@ -3281,7 +3333,7 @@ ed::EditorAction::AcceptResult ed::NavigateAction::Accept(const Control& control
auto& io = ImGui::GetIO();
if (Editor->CanAcceptUserInput() && ImGui::IsKeyPressed(ImGuiKey_F) && Editor->AreShortcutsEnabled())
if (Editor->CanAcceptUserInput() && ImGui::IsKeyPressed(GetKeyIndexForF()) && Editor->AreShortcutsEnabled())
{
const auto zoomMode = io.KeyShift ? NavigateAction::ZoomMode::WithMargin : NavigateAction::ZoomMode::None;
@ -3397,8 +3449,7 @@ bool ed::NavigateAction::HandleZoom(const Control& control)
m_Animation.Finish();
auto mousePos = io.MousePos;
auto steps = (int)io.MouseWheel;
auto newZoom = MatchZoom(steps, m_ZoomLevels[steps < 0 ? 0 : m_ZoomLevelCount - 1]);
auto newZoom = GetNextZoom(io.MouseWheel);
auto oldView = GetView();
m_Zoom = newZoom;
@ -3574,6 +3625,32 @@ ImRect ed::NavigateAction::GetViewRect() const
return m_Canvas.CalcViewRect(GetView());
}
float ed::NavigateAction::GetNextZoom(float steps)
{
if (this->Editor->GetConfig().EnableSmoothZoom)
{
return MatchSmoothZoom(steps);
}
else
{
auto fixedSteps = (int)steps;
return MatchZoom(fixedSteps, m_ZoomLevels[fixedSteps < 0 ? 0 : m_ZoomLevelCount - 1]);
}
}
float ed::NavigateAction::MatchSmoothZoom(float steps)
{
const auto power = Editor->GetConfig().SmoothZoomPower;
const auto newZoom = m_Zoom * powf(power, steps);
if (newZoom < m_ZoomLevels[0])
return m_ZoomLevels[0];
else if (newZoom > m_ZoomLevels[m_ZoomLevelCount - 1])
return m_ZoomLevels[m_ZoomLevelCount - 1];
else
return newZoom;
}
float ed::NavigateAction::MatchZoom(int steps, float fallbackZoom)
{
auto currentZoomIndex = MatchZoomIndex(steps);
@ -4320,7 +4397,7 @@ ed::EditorAction::AcceptResult ed::ShortcutAction::Accept(const Control& control
candidateAction = Copy;
if (io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_V)))
candidateAction = Paste;
if (io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_D)))
if (io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(GetKeyIndexForD()))
candidateAction = Duplicate;
if (!io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space)))
candidateAction = CreateNode;
@ -5650,6 +5727,8 @@ float* ed::Style::GetVarFloatAddr(StyleVar idx)
case StyleVar_GroupBorderWidth: return &GroupBorderWidth;
case StyleVar_HighlightConnectedLinks: return &HighlightConnectedLinks;
case StyleVar_SnapLinkToPinDir: return &SnapLinkToPinDir;
case StyleVar_HoveredNodeBorderOffset: return &HoverNodeBorderOffset;
case StyleVar_SelectedNodeBorderOffset: return &SelectedNodeBorderOffset;
default: return nullptr;
}
}
@ -5774,7 +5853,3 @@ void ed::Config::EndSave()
if (EndSaveSession)
EndSaveSession(UserPointer);
}
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif

View File

@ -15,15 +15,20 @@
//------------------------------------------------------------------------------
#define IMGUI_DEFINE_MATH_OPERATORS
# include <imgui.h>
# include <cstdint> // std::uintXX_t
# include <utility> // std::move
//------------------------------------------------------------------------------
# define IMGUI_NODE_EDITOR_VERSION "0.9.2"
# define IMGUI_NODE_EDITOR_VERSION_NUM 000902
# define IMGUI_NODE_EDITOR_VERSION "0.9.4"
# define IMGUI_NODE_EDITOR_VERSION_NUM 000904
//------------------------------------------------------------------------------
#ifndef IMGUI_NODE_EDITOR_API
#define IMGUI_NODE_EDITOR_API
#endif
//------------------------------------------------------------------------------
@ -100,6 +105,8 @@ struct Config
int SelectButtonIndex; // Mouse button index select action will react to (0-left, 1-right, 2-middle)
int NavigateButtonIndex; // Mouse button index navigate action will react to (0-left, 1-right, 2-middle)
int ContextMenuButtonIndex; // Mouse button index context menu action will react to (0-left, 1-right, 2-middle)
bool EnableSmoothZoom;
float SmoothZoomPower;
Config()
: SettingsFile("NodeEditor.json")
@ -116,6 +123,12 @@ struct Config
, SelectButtonIndex(0)
, NavigateButtonIndex(1)
, ContextMenuButtonIndex(1)
, EnableSmoothZoom(false)
# ifdef __APPLE__
, SmoothZoomPower(1.1f)
# else
, SmoothZoomPower(1.3f)
# endif
{
}
};
@ -174,6 +187,8 @@ enum StyleVar
StyleVar_GroupBorderWidth,
StyleVar_HighlightConnectedLinks,
StyleVar_SnapLinkToPinDir,
StyleVar_HoveredNodeBorderOffset,
StyleVar_SelectedNodeBorderOffset,
StyleVar_Count
};
@ -184,7 +199,9 @@ struct Style
float NodeRounding;
float NodeBorderWidth;
float HoveredNodeBorderWidth;
float HoverNodeBorderOffset;
float SelectedNodeBorderWidth;
float SelectedNodeBorderOffset;
float PinRounding;
float PinBorderWidth;
float LinkStrength;
@ -209,35 +226,37 @@ struct Style
Style()
{
NodePadding = ImVec4(8, 8, 8, 8);
NodeRounding = 12.0f;
NodeBorderWidth = 1.5f;
HoveredNodeBorderWidth = 3.5f;
SelectedNodeBorderWidth = 3.5f;
PinRounding = 4.0f;
PinBorderWidth = 0.0f;
LinkStrength = 100.0f;
SourceDirection = ImVec2(1.0f, 0.0f);
TargetDirection = ImVec2(-1.0f, 0.0f);
ScrollDuration = 0.35f;
FlowMarkerDistance = 30.0f;
FlowSpeed = 150.0f;
FlowDuration = 2.0f;
PivotAlignment = ImVec2(0.5f, 0.5f);
PivotSize = ImVec2(0.0f, 0.0f);
PivotScale = ImVec2(1, 1);
NodePadding = ImVec4(8, 8, 8, 8);
NodeRounding = 12.0f;
NodeBorderWidth = 1.5f;
HoveredNodeBorderWidth = 3.5f;
HoverNodeBorderOffset = 0.0f;
SelectedNodeBorderWidth = 3.5f;
SelectedNodeBorderOffset = 0.0f;
PinRounding = 4.0f;
PinBorderWidth = 0.0f;
LinkStrength = 100.0f;
SourceDirection = ImVec2(1.0f, 0.0f);
TargetDirection = ImVec2(-1.0f, 0.0f);
ScrollDuration = 0.35f;
FlowMarkerDistance = 30.0f;
FlowSpeed = 150.0f;
FlowDuration = 2.0f;
PivotAlignment = ImVec2(0.5f, 0.5f);
PivotSize = ImVec2(0.0f, 0.0f);
PivotScale = ImVec2(1, 1);
#if IMGUI_VERSION_NUM > 18101
PinCorners = ImDrawFlags_RoundCornersAll;
PinCorners = ImDrawFlags_RoundCornersAll;
#else
PinCorners = ImDrawCornerFlags_All;
PinCorners = ImDrawCornerFlags_All;
#endif
PinRadius = 0.0f;
PinArrowSize = 0.0f;
PinArrowWidth = 0.0f;
GroupRounding = 6.0f;
GroupBorderWidth = 1.0f;
HighlightConnectedLinks = 0.0f;
SnapLinkToPinDir = 0.0f;
PinRadius = 0.0f;
PinArrowSize = 0.0f;
PinArrowWidth = 0.0f;
GroupRounding = 6.0f;
GroupBorderWidth = 1.0f;
HighlightConnectedLinks = 0.0f;
SnapLinkToPinDir = 0.0f;
Colors[StyleColor_Bg] = ImColor( 60, 60, 70, 200);
Colors[StyleColor_Grid] = ImColor(120, 120, 120, 40);
@ -267,150 +286,150 @@ struct EditorContext;
//------------------------------------------------------------------------------
void SetCurrentEditor(EditorContext* ctx);
EditorContext* GetCurrentEditor();
EditorContext* CreateEditor(const Config* config = nullptr);
void DestroyEditor(EditorContext* ctx);
const Config& GetConfig(EditorContext* ctx = nullptr);
IMGUI_NODE_EDITOR_API void SetCurrentEditor(EditorContext* ctx);
IMGUI_NODE_EDITOR_API EditorContext* GetCurrentEditor();
IMGUI_NODE_EDITOR_API EditorContext* CreateEditor(const Config* config = nullptr);
IMGUI_NODE_EDITOR_API void DestroyEditor(EditorContext* ctx);
IMGUI_NODE_EDITOR_API const Config& GetConfig(EditorContext* ctx = nullptr);
Style& GetStyle();
const char* GetStyleColorName(StyleColor colorIndex);
IMGUI_NODE_EDITOR_API Style& GetStyle();
IMGUI_NODE_EDITOR_API const char* GetStyleColorName(StyleColor colorIndex);
void PushStyleColor(StyleColor colorIndex, const ImVec4& color);
void PopStyleColor(int count = 1);
IMGUI_NODE_EDITOR_API void PushStyleColor(StyleColor colorIndex, const ImVec4& color);
IMGUI_NODE_EDITOR_API void PopStyleColor(int count = 1);
void PushStyleVar(StyleVar varIndex, float value);
void PushStyleVar(StyleVar varIndex, const ImVec2& value);
void PushStyleVar(StyleVar varIndex, const ImVec4& value);
void PopStyleVar(int count = 1);
IMGUI_NODE_EDITOR_API void PushStyleVar(StyleVar varIndex, float value);
IMGUI_NODE_EDITOR_API void PushStyleVar(StyleVar varIndex, const ImVec2& value);
IMGUI_NODE_EDITOR_API void PushStyleVar(StyleVar varIndex, const ImVec4& value);
IMGUI_NODE_EDITOR_API void PopStyleVar(int count = 1);
void Begin(const char* id, const ImVec2& size = ImVec2(0, 0));
void End();
IMGUI_NODE_EDITOR_API void Begin(const char* id, const ImVec2& size = ImVec2(0, 0));
IMGUI_NODE_EDITOR_API void End();
void BeginNode(NodeId id);
void BeginPin(PinId id, PinKind kind);
void PinRect(const ImVec2& a, const ImVec2& b);
void PinPivotRect(const ImVec2& a, const ImVec2& b);
void PinPivotSize(const ImVec2& size);
void PinPivotScale(const ImVec2& scale);
void PinPivotAlignment(const ImVec2& alignment);
void EndPin();
void Group(const ImVec2& size);
void EndNode();
IMGUI_NODE_EDITOR_API void BeginNode(NodeId id);
IMGUI_NODE_EDITOR_API void BeginPin(PinId id, PinKind kind);
IMGUI_NODE_EDITOR_API void PinRect(const ImVec2& a, const ImVec2& b);
IMGUI_NODE_EDITOR_API void PinPivotRect(const ImVec2& a, const ImVec2& b);
IMGUI_NODE_EDITOR_API void PinPivotSize(const ImVec2& size);
IMGUI_NODE_EDITOR_API void PinPivotScale(const ImVec2& scale);
IMGUI_NODE_EDITOR_API void PinPivotAlignment(const ImVec2& alignment);
IMGUI_NODE_EDITOR_API void EndPin();
IMGUI_NODE_EDITOR_API void Group(const ImVec2& size);
IMGUI_NODE_EDITOR_API void EndNode();
bool BeginGroupHint(NodeId nodeId);
ImVec2 GetGroupMin();
ImVec2 GetGroupMax();
ImDrawList* GetHintForegroundDrawList();
ImDrawList* GetHintBackgroundDrawList();
void EndGroupHint();
IMGUI_NODE_EDITOR_API bool BeginGroupHint(NodeId nodeId);
IMGUI_NODE_EDITOR_API ImVec2 GetGroupMin();
IMGUI_NODE_EDITOR_API ImVec2 GetGroupMax();
IMGUI_NODE_EDITOR_API ImDrawList* GetHintForegroundDrawList();
IMGUI_NODE_EDITOR_API ImDrawList* GetHintBackgroundDrawList();
IMGUI_NODE_EDITOR_API void EndGroupHint();
// TODO: Add a way to manage node background channels
ImDrawList* GetNodeBackgroundDrawList(NodeId nodeId);
IMGUI_NODE_EDITOR_API ImDrawList* GetNodeBackgroundDrawList(NodeId nodeId);
bool Link(LinkId id, PinId startPinId, PinId endPinId, const ImVec4& color = ImVec4(1, 1, 1, 1), float thickness = 1.0f);
IMGUI_NODE_EDITOR_API bool Link(LinkId id, PinId startPinId, PinId endPinId, const ImVec4& color = ImVec4(1, 1, 1, 1), float thickness = 1.0f);
void Flow(LinkId linkId, FlowDirection direction = FlowDirection::Forward);
IMGUI_NODE_EDITOR_API void Flow(LinkId linkId, FlowDirection direction = FlowDirection::Forward);
bool BeginCreate(const ImVec4& color = ImVec4(1, 1, 1, 1), float thickness = 1.0f);
bool QueryNewLink(PinId* startId, PinId* endId);
bool QueryNewLink(PinId* startId, PinId* endId, const ImVec4& color, float thickness = 1.0f);
bool QueryNewNode(PinId* pinId);
bool QueryNewNode(PinId* pinId, const ImVec4& color, float thickness = 1.0f);
bool AcceptNewItem();
bool AcceptNewItem(const ImVec4& color, float thickness = 1.0f);
void RejectNewItem();
void RejectNewItem(const ImVec4& color, float thickness = 1.0f);
void EndCreate();
IMGUI_NODE_EDITOR_API bool BeginCreate(const ImVec4& color = ImVec4(1, 1, 1, 1), float thickness = 1.0f);
IMGUI_NODE_EDITOR_API bool QueryNewLink(PinId* startId, PinId* endId);
IMGUI_NODE_EDITOR_API bool QueryNewLink(PinId* startId, PinId* endId, const ImVec4& color, float thickness = 1.0f);
IMGUI_NODE_EDITOR_API bool QueryNewNode(PinId* pinId);
IMGUI_NODE_EDITOR_API bool QueryNewNode(PinId* pinId, const ImVec4& color, float thickness = 1.0f);
IMGUI_NODE_EDITOR_API bool AcceptNewItem();
IMGUI_NODE_EDITOR_API bool AcceptNewItem(const ImVec4& color, float thickness = 1.0f);
IMGUI_NODE_EDITOR_API void RejectNewItem();
IMGUI_NODE_EDITOR_API void RejectNewItem(const ImVec4& color, float thickness = 1.0f);
IMGUI_NODE_EDITOR_API void EndCreate();
bool BeginDelete();
bool QueryDeletedLink(LinkId* linkId, PinId* startId = nullptr, PinId* endId = nullptr);
bool QueryDeletedNode(NodeId* nodeId);
bool AcceptDeletedItem(bool deleteDependencies = true);
void RejectDeletedItem();
void EndDelete();
IMGUI_NODE_EDITOR_API bool BeginDelete();
IMGUI_NODE_EDITOR_API bool QueryDeletedLink(LinkId* linkId, PinId* startId = nullptr, PinId* endId = nullptr);
IMGUI_NODE_EDITOR_API bool QueryDeletedNode(NodeId* nodeId);
IMGUI_NODE_EDITOR_API bool AcceptDeletedItem(bool deleteDependencies = true);
IMGUI_NODE_EDITOR_API void RejectDeletedItem();
IMGUI_NODE_EDITOR_API void EndDelete();
void SetNodePosition(NodeId nodeId, const ImVec2& editorPosition);
void SetGroupSize(NodeId nodeId, const ImVec2& size);
ImVec2 GetNodePosition(NodeId nodeId);
ImVec2 GetNodeSize(NodeId nodeId);
void CenterNodeOnScreen(NodeId nodeId);
void SetNodeZPosition(NodeId nodeId, float z); // Sets node z position, nodes with higher value are drawn over nodes with lower value
float GetNodeZPosition(NodeId nodeId); // Returns node z position, defaults is 0.0f
IMGUI_NODE_EDITOR_API void SetNodePosition(NodeId nodeId, const ImVec2& editorPosition);
IMGUI_NODE_EDITOR_API void SetGroupSize(NodeId nodeId, const ImVec2& size);
IMGUI_NODE_EDITOR_API ImVec2 GetNodePosition(NodeId nodeId);
IMGUI_NODE_EDITOR_API ImVec2 GetNodeSize(NodeId nodeId);
IMGUI_NODE_EDITOR_API void CenterNodeOnScreen(NodeId nodeId);
IMGUI_NODE_EDITOR_API void SetNodeZPosition(NodeId nodeId, float z); // Sets node z position, nodes with higher value are drawn over nodes with lower value
IMGUI_NODE_EDITOR_API float GetNodeZPosition(NodeId nodeId); // Returns node z position, defaults is 0.0f
void RestoreNodeState(NodeId nodeId);
IMGUI_NODE_EDITOR_API void RestoreNodeState(NodeId nodeId);
void Suspend();
void Resume();
bool IsSuspended();
IMGUI_NODE_EDITOR_API void Suspend();
IMGUI_NODE_EDITOR_API void Resume();
IMGUI_NODE_EDITOR_API bool IsSuspended();
bool IsActive();
IMGUI_NODE_EDITOR_API bool IsActive();
bool HasSelectionChanged();
int GetSelectedObjectCount();
int GetSelectedNodes(NodeId* nodes, int size);
int GetSelectedLinks(LinkId* links, int size);
bool IsNodeSelected(NodeId nodeId);
bool IsLinkSelected(LinkId linkId);
void ClearSelection();
void SelectNode(NodeId nodeId, bool append = false);
void SelectLink(LinkId linkId, bool append = false);
void DeselectNode(NodeId nodeId);
void DeselectLink(LinkId linkId);
IMGUI_NODE_EDITOR_API bool HasSelectionChanged();
IMGUI_NODE_EDITOR_API int GetSelectedObjectCount();
IMGUI_NODE_EDITOR_API int GetSelectedNodes(NodeId* nodes, int size);
IMGUI_NODE_EDITOR_API int GetSelectedLinks(LinkId* links, int size);
IMGUI_NODE_EDITOR_API bool IsNodeSelected(NodeId nodeId);
IMGUI_NODE_EDITOR_API bool IsLinkSelected(LinkId linkId);
IMGUI_NODE_EDITOR_API void ClearSelection();
IMGUI_NODE_EDITOR_API void SelectNode(NodeId nodeId, bool append = false);
IMGUI_NODE_EDITOR_API void SelectLink(LinkId linkId, bool append = false);
IMGUI_NODE_EDITOR_API void DeselectNode(NodeId nodeId);
IMGUI_NODE_EDITOR_API void DeselectLink(LinkId linkId);
bool DeleteNode(NodeId nodeId);
bool DeleteLink(LinkId linkId);
IMGUI_NODE_EDITOR_API bool DeleteNode(NodeId nodeId);
IMGUI_NODE_EDITOR_API bool DeleteLink(LinkId linkId);
bool HasAnyLinks(NodeId nodeId); // Returns true if node has any link connected
bool HasAnyLinks(PinId pinId); // Return true if pin has any link connected
int BreakLinks(NodeId nodeId); // Break all links connected to this node
int BreakLinks(PinId pinId); // Break all links connected to this pin
IMGUI_NODE_EDITOR_API bool HasAnyLinks(NodeId nodeId); // Returns true if node has any link connected
IMGUI_NODE_EDITOR_API bool HasAnyLinks(PinId pinId); // Return true if pin has any link connected
IMGUI_NODE_EDITOR_API int BreakLinks(NodeId nodeId); // Break all links connected to this node
IMGUI_NODE_EDITOR_API int BreakLinks(PinId pinId); // Break all links connected to this pin
void NavigateToContent(float duration = -1);
void NavigateToSelection(bool zoomIn = false, float duration = -1);
IMGUI_NODE_EDITOR_API void NavigateToContent(float duration = -1);
IMGUI_NODE_EDITOR_API void NavigateToSelection(bool zoomIn = false, float duration = -1);
bool ShowNodeContextMenu(NodeId* nodeId);
bool ShowPinContextMenu(PinId* pinId);
bool ShowLinkContextMenu(LinkId* linkId);
bool ShowBackgroundContextMenu();
IMGUI_NODE_EDITOR_API bool ShowNodeContextMenu(NodeId* nodeId);
IMGUI_NODE_EDITOR_API bool ShowPinContextMenu(PinId* pinId);
IMGUI_NODE_EDITOR_API bool ShowLinkContextMenu(LinkId* linkId);
IMGUI_NODE_EDITOR_API bool ShowBackgroundContextMenu();
void EnableShortcuts(bool enable);
bool AreShortcutsEnabled();
IMGUI_NODE_EDITOR_API void EnableShortcuts(bool enable);
IMGUI_NODE_EDITOR_API bool AreShortcutsEnabled();
bool BeginShortcut();
bool AcceptCut();
bool AcceptCopy();
bool AcceptPaste();
bool AcceptDuplicate();
bool AcceptCreateNode();
int GetActionContextSize();
int GetActionContextNodes(NodeId* nodes, int size);
int GetActionContextLinks(LinkId* links, int size);
void EndShortcut();
IMGUI_NODE_EDITOR_API bool BeginShortcut();
IMGUI_NODE_EDITOR_API bool AcceptCut();
IMGUI_NODE_EDITOR_API bool AcceptCopy();
IMGUI_NODE_EDITOR_API bool AcceptPaste();
IMGUI_NODE_EDITOR_API bool AcceptDuplicate();
IMGUI_NODE_EDITOR_API bool AcceptCreateNode();
IMGUI_NODE_EDITOR_API int GetActionContextSize();
IMGUI_NODE_EDITOR_API int GetActionContextNodes(NodeId* nodes, int size);
IMGUI_NODE_EDITOR_API int GetActionContextLinks(LinkId* links, int size);
IMGUI_NODE_EDITOR_API void EndShortcut();
float GetCurrentZoom();
IMGUI_NODE_EDITOR_API float GetCurrentZoom();
NodeId GetHoveredNode();
PinId GetHoveredPin();
LinkId GetHoveredLink();
NodeId GetDoubleClickedNode();
PinId GetDoubleClickedPin();
LinkId GetDoubleClickedLink();
bool IsBackgroundClicked();
bool IsBackgroundDoubleClicked();
ImGuiMouseButton GetBackgroundClickButtonIndex(); // -1 if none
ImGuiMouseButton GetBackgroundDoubleClickButtonIndex(); // -1 if none
IMGUI_NODE_EDITOR_API NodeId GetHoveredNode();
IMGUI_NODE_EDITOR_API PinId GetHoveredPin();
IMGUI_NODE_EDITOR_API LinkId GetHoveredLink();
IMGUI_NODE_EDITOR_API NodeId GetDoubleClickedNode();
IMGUI_NODE_EDITOR_API PinId GetDoubleClickedPin();
IMGUI_NODE_EDITOR_API LinkId GetDoubleClickedLink();
IMGUI_NODE_EDITOR_API bool IsBackgroundClicked();
IMGUI_NODE_EDITOR_API bool IsBackgroundDoubleClicked();
IMGUI_NODE_EDITOR_API ImGuiMouseButton GetBackgroundClickButtonIndex(); // -1 if none
IMGUI_NODE_EDITOR_API ImGuiMouseButton GetBackgroundDoubleClickButtonIndex(); // -1 if none
bool GetLinkPins(LinkId linkId, PinId* startPinId, PinId* endPinId); // pass nullptr if particular pin do not interest you
IMGUI_NODE_EDITOR_API bool GetLinkPins(LinkId linkId, PinId* startPinId, PinId* endPinId); // pass nullptr if particular pin do not interest you
bool PinHadAnyLinks(PinId pinId);
IMGUI_NODE_EDITOR_API bool PinHadAnyLinks(PinId pinId);
ImVec2 GetScreenSize();
ImVec2 ScreenToCanvas(const ImVec2& pos);
ImVec2 CanvasToScreen(const ImVec2& pos);
IMGUI_NODE_EDITOR_API ImVec2 GetScreenSize();
IMGUI_NODE_EDITOR_API ImVec2 ScreenToCanvas(const ImVec2& pos);
IMGUI_NODE_EDITOR_API ImVec2 CanvasToScreen(const ImVec2& pos);
int GetNodeCount(); // Returns number of submitted nodes since Begin() call
int GetOrderedNodeIds(NodeId* nodes, int size); // Fills an array with node id's in order they're drawn; up to 'size` elements are set. Returns actual size of filled id's.
IMGUI_NODE_EDITOR_API int GetNodeCount(); // Returns number of submitted nodes since Begin() call
IMGUI_NODE_EDITOR_API int GetOrderedNodeIds(NodeId* nodes, int size); // Fills an array with node id's in order they're drawn; up to 'size` elements are set. Returns actual size of filled id's.

View File

@ -1,10 +1,3 @@
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//------------------------------------------------------------------------------
// VERSION 0.9.1
//
@ -767,8 +760,3 @@ int ax::NodeEditor::GetOrderedNodeIds(NodeId* nodes, int size)
{
return s_Editor->GetNodeIds(nodes, size);
}
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif

View File

@ -1,10 +1,3 @@
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//------------------------------------------------------------------------------
// VERSION 0.9.1
//
@ -22,12 +15,14 @@
//------------------------------------------------------------------------------
# ifndef IMGUI_DEFINE_MATH_OPERATORS
# define IMGUI_DEFINE_MATH_OPERATORS
# endif
# include "imgui_node_editor.h"
//------------------------------------------------------------------------------
# include <imgui.h>
# define IMGUI_DEFINE_MATH_OPERATORS
# include <imgui_internal.h>
# include "imgui_extra_math.h"
# include "imgui_bezier_math.h"
@ -440,7 +435,7 @@ struct Node final: Object
virtual bool IsSelectable() override { return true; }
virtual void Draw(ImDrawList* drawList, DrawFlags flags = None) override final;
void DrawBorder(ImDrawList* drawList, ImU32 color, float thickness = 1.0f);
void DrawBorder(ImDrawList* drawList, ImU32 color, float thickness = 1.0f, float offset = 0.0f);
void GetGroupedNodes(std::vector<Node*>& result, bool append = false);
@ -891,6 +886,8 @@ private:
void NavigateTo(const ImRect& target, float duration = -1.0f, NavigationReason reason = NavigationReason::Unknown);
float GetNextZoom(float steps);
float MatchSmoothZoom(float steps);
float MatchZoom(int steps, float fallbackZoom);
int MatchZoomIndex(int direction);
@ -1561,8 +1558,3 @@ private:
//------------------------------------------------------------------------------
# endif // __IMGUI_NODE_EDITOR_INTERNAL_H__
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif

View File

@ -37,6 +37,14 @@ ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) {
return ImNodesPinShape_Quad;
}
int GetNodeInputSocketId(int node_index, int input_socket_index) {
return node_index * 1000 + input_socket_index;
}
int GetNodeOutputSocketId(int node_index, int output_socket_index) {
return node_index * 1000 + 100 + output_socket_index;
}
void NodeSocketEditor(Socket& socket) {
int mode_current = static_cast<int>(socket.m_type);
ImGui::InputText("Name", &socket.m_name);
@ -182,9 +190,7 @@ void AnimGraphEditorRenderSidebar(
100.f);
} else if (property.m_type == SocketType::SocketTypeBool) {
bool flag_value = property.GetValue<bool>();
if (ImGui::Checkbox(
property.m_name.c_str(),
&flag_value)) {
if (ImGui::Checkbox(property.m_name.c_str(), &flag_value)) {
property.SetValue(flag_value);
}
} else if (property.m_type == SocketType::SocketTypeString) {
@ -255,14 +261,14 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
}
if (ImGui::Button("Load")) {
sGraphGresource.loadFromFile("editor_graph.json");
// for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) {
// const AnimNodeResource& node_resource = sGraphGresource.m_nodes[i];
// ImNodes::SetNodeGridSpacePos(
// i,
// ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
// }
sGraphLoadedThisFrame = true;
// for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) {
// const AnimNodeResource& node_resource = sGraphGresource.m_nodes[i];
// ImNodes::SetNodeGridSpacePos(
// i,
// ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
// }
}
if (ImGui::Button("Clear")) {
sGraphGresource.clear();
@ -285,8 +291,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
ax::NodeEditor::SetCurrentEditor(context);
ax::NodeEditor::Begin("Graph Editor");
int node_editor_id = 0;
#if 1
for (size_t node_id = 0, n = sGraphGresource.m_nodes.size(); node_id < n;
node_id++) {
AnimNodeResource& node_resource = sGraphGresource.m_nodes[node_id];
@ -295,70 +300,63 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
// continue;
}
node_editor_id++;
if (sGraphLoadedThisFrame) {
ax::NodeEditor::SetNodePosition(node_editor_id, ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
ax::NodeEditor::SetNodePosition(
node_id,
ImVec2(node_resource.m_position[0], node_resource.m_position[1]));
}
ax::NodeEditor::BeginNode(node_editor_id);
ax::NodeEditor::BeginNode(node_id);
ImGui::Text("%s", node_resource.m_type_name.c_str());
// // Inputs
// std::vector<Socket>& node_inputs =
// node_resource.m_socket_accessor->m_inputs;
// for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) {
// Socket& socket = node_inputs[j];
// int pin_id = static_cast<int>(node_id) + j * 1000;
// ax::NodeEditor::BeginPin(pin_id, ax::NodeEditor::PinKind::Input);
// ImGui::Text("%s", socket.m_name.c_str());
// ax::NodeEditor::EndPin();
// }
//
// // Outputs
// const std::vector<Socket>& node_outputs =
// node_resource.m_socket_accessor->m_outputs;
// for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) {
// const Socket& socket = node_outputs[j];
// int pin_id = static_cast<int>(node_id) + j * 1000 * 1000;
// ax::NodeEditor::BeginPin(pin_id, ax::NodeEditor::PinKind::Output);
// ImGui::Text("%s", socket.m_name.c_str());
// ax::NodeEditor::EndPin();
// }
// Inputs
std::vector<Socket>& node_inputs =
node_resource.m_socket_accessor->m_inputs;
for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) {
Socket& socket = node_inputs[j];
ax::NodeEditor::BeginPin(
GetNodeInputSocketId(static_cast<int>(node_id), static_cast<int>(j)),
ax::NodeEditor::PinKind::Input);
ImGui::Text("%s", socket.m_name.c_str());
ax::NodeEditor::EndPin();
}
// Outputs
std::vector<Socket>& node_outputs =
node_resource.m_socket_accessor->m_outputs;
for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) {
Socket& socket = node_outputs[j];
ax::NodeEditor::BeginPin(
GetNodeOutputSocketId(static_cast<int>(node_id), static_cast<int>(j)),
ax::NodeEditor::PinKind::Output);
ImGui::Text("%s", socket.m_name.c_str());
ax::NodeEditor::EndPin();
}
ax::NodeEditor::EndNode();
}
#if 0
int unique_id = 1;
ax::NodeEditor::BeginNode(unique_id++);
int link_id = 0;
for (size_t connection_id = 0, n = sGraphGresource.m_connections.size(); connection_id < n;
connection_id++) {
const AnimGraphConnectionResource& connection_resource = sGraphGresource.m_connections[connection_id];
// Node A
ImGui::Text("Node A");
ax::NodeEditor::BeginPin(unique_id++, ax::NodeEditor::PinKind::Input);
ImGui::Text("In");
ax::NodeEditor::EndPin();
ImGui::SameLine();
ax::NodeEditor::BeginPin(unique_id++, ax::NodeEditor::PinKind::Output);
ImGui::Text("Out");
ax::NodeEditor::EndPin();
const AnimNodeResource& source_node_resource = sGraphGresource.m_nodes[connection_resource.source_node_index];
int source_socket_index = source_node_resource.m_socket_accessor->GetOutputIndex(connection_resource.source_socket_name.c_str());
ax::NodeEditor::EndNode();
const AnimNodeResource& target_node_resource = sGraphGresource.m_nodes[connection_resource.target_node_index];
int target_socket_index = target_node_resource.m_socket_accessor->GetInputIndex(connection_resource.target_socket_name.c_str());
// Node B
ax::NodeEditor::BeginNode(unique_id++);
int source_socket_id = GetNodeOutputSocketId(static_cast<int>(connection_resource.source_node_index), source_socket_index);
int target_socket_id = GetNodeInputSocketId(static_cast<int>(connection_resource.target_node_index), target_socket_index);
ax::NodeEditor::Link(link_id++, source_socket_id, target_socket_id);
}
ImGui::Text("Node B");
ax::NodeEditor::BeginPin(unique_id++, ax::NodeEditor::PinKind::Input);
ImGui::Text("In");
ax::NodeEditor::EndPin();
ImGui::SameLine();
ax::NodeEditor::BeginPin(unique_id++, ax::NodeEditor::PinKind::Output);
ImGui::Text("Out");
ax::NodeEditor::EndPin();
ax::NodeEditor::EndNode();
#endif
#if 1
// Create Connections
if (ax::NodeEditor::BeginCreate()) {
ax::NodeEditor::PinId input_pin_id, output_pin_id;
@ -370,16 +368,13 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
}
}
ax::NodeEditor::EndCreate();
#endif
ax::NodeEditor::End();
ax::NodeEditor::SetCurrentEditor(nullptr);
if (sGraphLoadedThisFrame) {
ax::NodeEditor::NavigateToContent();
}
sGraphLoadedThisFrame = false;
ax::NodeEditor::SetCurrentEditor(nullptr);
}
void LegacyAnimGraphEditorUpdate() {