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. // Crude implementation of JSON value object and parser.
// //
// VERSION 0.1 // VERSION 0.1
@ -569,7 +561,7 @@ private:
if (end != hex.c_str() + hex.size()) if (end != hex.c_str() + hex.size())
return false; return false;
c = v; c = static_cast<int>(v);
return true; return true;
} }
@ -896,8 +888,3 @@ bool value::save(const string& path, const int indent, const char indent_char) c
# endif # endif
} // namespace crude_json } // 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 // Crude implementation of JSON value object and parser.
#ifndef _MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
// Crude implementation of JSON value object and parser.
// //
// VERSION 0.1 // VERSION 0.1
// //
@ -253,9 +247,4 @@ template <> inline number* value::get_ptr<number>() { if (m_Type =
} // namespace crude_json } // namespace crude_json
# endif // __CRUDE_JSON_H__ # endif // __CRUDE_JSON_H__
//Disable a bunch of warnings for now
#ifndef _MSC_VER
#pragma GCC diagnostic pop
#endif

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 CHANGE: Remove unwanted extra frame height from node bottom

View File

@ -69,15 +69,12 @@ endif()
if (OpenGL_FOUND) if (OpenGL_FOUND)
set(HAVE_OPENGL YES) 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_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 list(APPEND _Application_Sources
source/imgui_impl_opengl3.cpp source/imgui_impl_opengl3.cpp
source/imgui_impl_opengl3.h source/imgui_impl_opengl3.h
source/imgui_impl_opengl3_loader.h
) )
endif() endif()

View File

@ -1,5 +1,8 @@
# pragma once # pragma once
# include <imgui.h> # include <imgui.h>
# if !defined(IMGUI_VERSION_NUM) || (IMGUI_VERSION_NUM < 18822)
# include <type_traits> # include <type_traits>
// https://stackoverflow.com/a/8597498 // https://stackoverflow.com/a/8597498
@ -46,3 +49,17 @@ static inline int GetEnumValueForD()
{ {
return KeyTester_ImGuiKey_D::Get<ImGuiKey_>(nullptr); 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 // - Desktop GL: 2.x 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) // - 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: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! // [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. // About WebGL/ES:
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
// https://github.com/ocornut/imgui // - 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: // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Modern Desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // Learn about Dear ImGui:
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // - 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: // 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" // 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. // 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 #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
// Backend API // 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_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); 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_ES2 // Auto-detected on Emscripten
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android //#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
// Attempt to auto-detect the default Desktop GL loader based on available header files. // 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 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.
#if !defined(IMGUI_IMPL_OPENGL_ES2) \ #if !defined(IMGUI_IMPL_OPENGL_ES2) \
&& !defined(IMGUI_IMPL_OPENGL_ES3) \ && !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)
// Try to detect GLES on matching platforms // Try to detect GLES on matching platforms
#if defined(__APPLE__) #if defined(__APPLE__)
#include "TargetConditionals.h" #include <TargetConditionals.h>
#endif #endif
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" #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" #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 #else
#error "Cannot detect OpenGL loader!" // Otherwise imgui_impl_opengl3_loader.h will be used.
#endif
#else
#define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W embedded in our repository
#endif #endif
#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_Space] = VK_SPACE;
io.KeyMap[ImGuiKey_Enter] = VK_RETURN; io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; 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; io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
# endif
io.KeyMap[ImGuiKey_A] = 'A'; io.KeyMap[ImGuiKey_A] = 'A';
io.KeyMap[ImGuiKey_C] = 'C'; io.KeyMap[ImGuiKey_C] = 'C';
io.KeyMap[ImGuiKey_V] = 'V'; io.KeyMap[ImGuiKey_V] = 'V';

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
# include "drawing.h"
# define IMGUI_DEFINE_MATH_OPERATORS # define IMGUI_DEFINE_MATH_OPERATORS
# include "drawing.h"
# include <imgui_internal.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) 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 # define IMGUI_DEFINE_MATH_OPERATORS
# include "widgets.h"
# include <imgui_internal.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)*/) 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 # define IMGUI_DEFINE_MATH_OPERATORS
# include <imgui.h>
# include <imgui_internal.h> # include <imgui_internal.h>
# include <imgui_canvas.h> # include <imgui_canvas.h>
# include <application.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 // VERSION 0.1
// //
@ -403,19 +395,17 @@ inline ImCubicBezierIntersectResult ImCubicBezierLineIntersect(const ImVec2& p0,
return count; return count;
}; };
/* // https://github.com/kaishiqi/Geometric-Bezier/blob/master/GeometricBezier/src/kaishiqi/geometric/intersection/Intersection.as
https://github.com/kaishiqi/Geometric-Bezier/blob/master/GeometricBezier/src/kaishiqi/geometric/intersection/Intersection.as //
// Start with Bezier using Bernstein polynomials for weighting functions:
Start with Bezier using Bernstein polynomials for weighting functions: // (1-t^3)P0 + 3t(1-t)^2P1 + 3t^2(1-t)P2 + t^3P3
(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
Expand and collect terms to form linear combinations of original Bezier // controls. This ends up with a vector cubic in t:
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
(-P0+3P1-3P2+P3)t^3 + (3P0-6P1+3P2)t^2 + (-3P0+3P1)t + P0 // /\ /\ /\ /\
/\ /\ /\ /\ // || || || ||
|| || || || // c3 c2 c1 c0
c3 c2 c1 c0
*/
// Calculate the coefficients // Calculate the coefficients
auto c3 = -p0 + 3 * p1 - 3 * p2 + p3; 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__ # 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 "imgui_canvas.h"
# include <type_traits> # include <type_traits>
@ -25,6 +27,11 @@
static constexpr bool value = (sizeof(yes_type) == sizeof(test<mixin>(0))); \ 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 { namespace ImCanvasDetails {
DECLARE_HAS_MEMBER(HasFringeScale, _FringeScale); DECLARE_HAS_MEMBER(HasFringeScale, _FringeScale);
@ -115,7 +122,7 @@ bool ImGuiEx::Canvas::Begin(ImGuiID id, const ImVec2& size)
// #debug: Canvas content. // #debug: Canvas content.
//m_DrawList->AddRectFilled(m_StartPos, m_StartPos + m_CurrentSize, IM_COL32(0, 0, 0, 64)); //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)); ImGui::SetCursorScreenPos(ImVec2(0.0f, 0.0f));
@ -131,6 +138,10 @@ bool ImGuiEx::Canvas::Begin(ImGuiID id, const ImVec2& size)
EnterLocalSpace(); EnterLocalSpace();
# if IMGUI_VERSION_NUM >= 18967
ImGui::SetNextItemAllowOverlap();
# endif
// Emit dummy widget matching bounds of the canvas. // Emit dummy widget matching bounds of the canvas.
ImGui::SetCursorScreenPos(m_ViewRect.Min); ImGui::SetCursorScreenPos(m_ViewRect.Min);
ImGui::Dummy(m_ViewRect.GetSize()); ImGui::Dummy(m_ViewRect.GetSize());
@ -162,7 +173,9 @@ void ImGuiEx::Canvas::End()
ImGui::GetCurrentWindow()->DC.CursorMaxPos = m_WindowCursorMaxBackup; ImGui::GetCurrentWindow()->DC.CursorMaxPos = m_WindowCursorMaxBackup;
# if IMGUI_VERSION_NUM < 18967
ImGui::SetItemAllowOverlap(); ImGui::SetItemAllowOverlap();
# endif
// Emit dummy widget matching bounds of the canvas. // Emit dummy widget matching bounds of the canvas.
ImGui::SetCursorScreenPos(m_WidgetPosition); ImGui::SetCursorScreenPos(m_WidgetPosition);
@ -407,6 +420,15 @@ void ImGuiEx::Canvas::EnterLocalSpace()
auto clipped_clip_rect = m_DrawList->_ClipRectStack.back(); auto clipped_clip_rect = m_DrawList->_ClipRectStack.back();
ImGui::PopClipRect(); 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 // Make sure we do not share draw command with anyone. We don't want to mess
// with someones clip rectangle. // with someones clip rectangle.
@ -421,16 +443,9 @@ void ImGuiEx::Canvas::EnterLocalSpace()
// //
// More investigation is needed. To get to the bottom of this. // 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) 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_DrawListFirstCommandIndex = ImMax(m_DrawList->CmdBuffer.Size - 1, 0);
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);
# if defined(IMGUI_HAS_VIEWPORT) # if defined(IMGUI_HAS_VIEWPORT)
auto window = ImGui::GetCurrentWindow(); auto window = ImGui::GetCurrentWindow();
@ -510,7 +525,7 @@ void ImGuiEx::Canvas::LeaveLocalSpace()
} }
// Move clip rectangles to screen space. // 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]; auto& command = m_DrawList->CmdBuffer[i];
command.ClipRect.x = command.ClipRect.x * m_View.Scale + m_ViewTransformPosition.x; 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. // 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]; auto& command = m_DrawList->CmdBuffer[i];
command.ClipRect.x = command.ClipRect.x + m_ViewTransformPosition.x; 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); auto& fringeScale = ImFringeScaleRef(m_DrawList);
fringeScale = m_LastFringeScale; fringeScale = m_LastFringeScale;

View File

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

View File

@ -15,10 +15,10 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
# include <imgui.h>
# ifndef IMGUI_DEFINE_MATH_OPERATORS # ifndef IMGUI_DEFINE_MATH_OPERATORS
# define IMGUI_DEFINE_MATH_OPERATORS # define IMGUI_DEFINE_MATH_OPERATORS
# endif # endif
# include <imgui.h>
# include <imgui_internal.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);
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); inline ImVec2 operator*(const float lhs, const ImVec2& rhs);
# if IMGUI_VERSION_NUM < 18955
inline ImVec2 operator-(const ImVec2& lhs); 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) inline bool operator==(const ImVec2& lhs, const ImVec2& rhs)
{ {
return lhs.x == rhs.x && lhs.y == rhs.y; 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; return lhs.x != rhs.x || lhs.y != rhs.y;
} }
# endif
inline ImVec2 operator*(const float lhs, const ImVec2& rhs) inline ImVec2 operator*(const float lhs, const ImVec2& rhs)
{ {
return ImVec2(lhs * rhs.x, lhs * rhs.y); return ImVec2(lhs * rhs.x, lhs * rhs.y);
} }
# if IMGUI_VERSION_NUM < 18955
inline ImVec2 operator-(const ImVec2& lhs) inline ImVec2 operator-(const ImVec2& lhs)
{ {
return ImVec2(-lhs.x, -lhs.y); 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 // VERSION 0.9.1
// //
@ -42,6 +35,58 @@
static bool const value = sizeof(test<T>(0)) == sizeof(yes); \ 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; 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) 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) static void ImDrawListSplitter_SwapChannels(ImDrawListSplitter* splitter, int left, int right)
{ {
IM_ASSERT(left < splitter->_Count && right < splitter->_Count); IM_ASSERT(left < splitter->_Count && right < splitter->_Count);
if (left == right) if (left == right)
return; return;
auto currentChannel = splitter->_Current; auto currentChannel = splitter->_Current;
auto* leftCmdBuffer = &splitter->_Channels[left]._CmdBuffer; auto* leftCmdBuffer = &splitter->_Channels[left]._CmdBuffer;
auto* leftIdxBuffer = &splitter->_Channels[left]._IdxBuffer; auto* leftIdxBuffer = &splitter->_Channels[left]._IdxBuffer;
auto* rightCmdBuffer = &splitter->_Channels[right]._CmdBuffer; auto* rightCmdBuffer = &splitter->_Channels[right]._CmdBuffer;
auto* rightIdxBuffer = &splitter->_Channels[right]._IdxBuffer; auto* rightIdxBuffer = &splitter->_Channels[right]._IdxBuffer;
leftCmdBuffer->swap(*rightCmdBuffer); leftCmdBuffer->swap(*rightCmdBuffer);
leftIdxBuffer->swap(*rightIdxBuffer); leftIdxBuffer->swap(*rightIdxBuffer);
if (currentChannel == left) if (currentChannel == left)
splitter->_Current = right; splitter->_Current = right;
else if (currentChannel == right) else if (currentChannel == right)
splitter->_Current = left; splitter->_Current = left;
} }
static void ImDrawList_SwapChannels(ImDrawList* drawList, int left, int right) 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) 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); drawList->ChannelsSetCurrent(m_Channel + c_NodeBaseChannel);
DrawBorder(drawList, borderColor, editorStyle.SelectedNodeBorderWidth); DrawBorder(drawList, borderColor, editorStyle.SelectedNodeBorderWidth, editorStyle.SelectedNodeBorderOffset);
} }
else if (!IsGroup(this) && (flags & Hovered)) else if (!IsGroup(this) && (flags & Hovered))
{ {
@ -664,16 +709,18 @@ void ed::Node::Draw(ImDrawList* drawList, DrawFlags flags)
drawList->ChannelsSetCurrent(m_Channel + c_NodeBaseChannel); 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) if (thickness > 0.0f)
{ {
drawList->AddRect(m_Bounds.Min, m_Bounds.Max, const ImVec2 extraOffset = ImVec2(offset, offset);
color, m_Rounding, c_AllRoundCornersFlags, thickness);
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) if (!m_IsInitialized)
{ {
// Cycle canvas so it has a change to setup its size before settings are loaded // Cycle canvas, so it has a chance to initialize its size before settings are loaded
m_Canvas.Begin(id, canvasSize); if (m_Canvas.Begin(id, canvasSize))
m_Canvas.End(); m_Canvas.End();
LoadSettings(); LoadSettings();
m_IsInitialized = true; 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 centerY = (previousVisibleRect.Max.y + previousVisibleRect.Min.y) * 0.5f;
auto currentVisibleRect = m_Canvas.ViewRect(); auto currentVisibleRect = m_Canvas.ViewRect();
auto currentAspectRatio = currentVisibleRect.GetHeight() ? (currentVisibleRect.GetWidth() / currentVisibleRect.GetHeight()) : 0.0f; auto currentAspectRatio = currentVisibleRect.GetHeight() ? (currentVisibleRect.GetWidth() / currentVisibleRect.GetHeight()) : 0.0f;
auto width = previousVisibleRect.GetHeight(); auto width = previousVisibleRect.GetWidth();
auto height = previousVisibleRect.GetHeight(); auto height = previousVisibleRect.GetHeight();
if (m_Config.CanvasSizeMode == ax::NodeEditor::CanvasSizeMode::FitVerticalView) 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."); IM_ASSERT(m_DrawList != nullptr && "Suspend was called outiside of Begin/End.");
auto lastChannel = m_DrawList->_Splitter._Current; auto lastChannel = m_DrawList->_Splitter._Current;
m_DrawList->ChannelsSetCurrent(m_ExternalChannel); m_DrawList->ChannelsSetCurrent(m_ExternalChannel);
m_Canvas.Suspend(); if (m_IsCanvasVisible)
m_Canvas.Suspend();
m_DrawList->ChannelsSetCurrent(lastChannel); m_DrawList->ChannelsSetCurrent(lastChannel);
if ((flags & SuspendFlags::KeepSplitter) != SuspendFlags::KeepSplitter) if ((flags & SuspendFlags::KeepSplitter) != SuspendFlags::KeepSplitter)
ImDrawList_SwapSplitter(m_DrawList, m_Splitter); ImDrawList_SwapSplitter(m_DrawList, m_Splitter);
@ -1931,13 +1979,14 @@ void ed::EditorContext::Resume(SuspendFlags flags)
ImDrawList_SwapSplitter(m_DrawList, m_Splitter); ImDrawList_SwapSplitter(m_DrawList, m_Splitter);
auto lastChannel = m_DrawList->_Splitter._Current; auto lastChannel = m_DrawList->_Splitter._Current;
m_DrawList->ChannelsSetCurrent(m_ExternalChannel); m_DrawList->ChannelsSetCurrent(m_ExternalChannel);
m_Canvas.Resume(); if (m_IsCanvasVisible)
m_Canvas.Resume();
m_DrawList->ChannelsSetCurrent(lastChannel); m_DrawList->ChannelsSetCurrent(lastChannel);
} }
bool ed::EditorContext::IsSuspended() bool ed::EditorContext::IsSuspended()
{ {
return m_Canvas.IsSuspended(); return m_Canvas.IsSuspended();
} }
bool ed::EditorContext::IsFocused() bool ed::EditorContext::IsFocused()
@ -2513,9 +2562,12 @@ ed::Control ed::EditorContext::BuildControl(bool allowOffscreen)
if (!allowOffscreen && !m_IsHovered) if (!allowOffscreen && !m_IsHovered)
return Control(); return Control();
# if IMGUI_VERSION_NUM >= 17909 # if IMGUI_VERSION_NUM >= 18836
if (m_IsHoveredWithoutOverlapp) if (m_IsHoveredWithoutOverlapp)
ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY); ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY);
# elif IMGUI_VERSION_NUM >= 17909
if (m_IsHoveredWithoutOverlapp)
ImGui::SetItemUsingMouseWheel();
# endif # endif
return Control(hotObject, activeObject, clickedObject, doubleClickedObject, return Control(hotObject, activeObject, clickedObject, doubleClickedObject,
@ -3281,7 +3333,7 @@ ed::EditorAction::AcceptResult ed::NavigateAction::Accept(const Control& control
auto& io = ImGui::GetIO(); 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; 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(); m_Animation.Finish();
auto mousePos = io.MousePos; auto mousePos = io.MousePos;
auto steps = (int)io.MouseWheel; auto newZoom = GetNextZoom(io.MouseWheel);
auto newZoom = MatchZoom(steps, m_ZoomLevels[steps < 0 ? 0 : m_ZoomLevelCount - 1]);
auto oldView = GetView(); auto oldView = GetView();
m_Zoom = newZoom; m_Zoom = newZoom;
@ -3574,6 +3625,32 @@ ImRect ed::NavigateAction::GetViewRect() const
return m_Canvas.CalcViewRect(GetView()); 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) float ed::NavigateAction::MatchZoom(int steps, float fallbackZoom)
{ {
auto currentZoomIndex = MatchZoomIndex(steps); auto currentZoomIndex = MatchZoomIndex(steps);
@ -4320,7 +4397,7 @@ ed::EditorAction::AcceptResult ed::ShortcutAction::Accept(const Control& control
candidateAction = Copy; candidateAction = Copy;
if (io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_V))) if (io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_V)))
candidateAction = Paste; 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; candidateAction = Duplicate;
if (!io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space))) if (!io.KeyCtrl && !io.KeyShift && !io.KeyAlt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space)))
candidateAction = CreateNode; candidateAction = CreateNode;
@ -5650,6 +5727,8 @@ float* ed::Style::GetVarFloatAddr(StyleVar idx)
case StyleVar_GroupBorderWidth: return &GroupBorderWidth; case StyleVar_GroupBorderWidth: return &GroupBorderWidth;
case StyleVar_HighlightConnectedLinks: return &HighlightConnectedLinks; case StyleVar_HighlightConnectedLinks: return &HighlightConnectedLinks;
case StyleVar_SnapLinkToPinDir: return &SnapLinkToPinDir; case StyleVar_SnapLinkToPinDir: return &SnapLinkToPinDir;
case StyleVar_HoveredNodeBorderOffset: return &HoverNodeBorderOffset;
case StyleVar_SelectedNodeBorderOffset: return &SelectedNodeBorderOffset;
default: return nullptr; default: return nullptr;
} }
} }
@ -5774,7 +5853,3 @@ void ed::Config::EndSave()
if (EndSaveSession) if (EndSaveSession)
EndSaveSession(UserPointer); 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 <imgui.h>
# include <cstdint> // std::uintXX_t # include <cstdint> // std::uintXX_t
# include <utility> // std::move # include <utility> // std::move
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
# define IMGUI_NODE_EDITOR_VERSION "0.9.2" # define IMGUI_NODE_EDITOR_VERSION "0.9.4"
# define IMGUI_NODE_EDITOR_VERSION_NUM 000902 # 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 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 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) int ContextMenuButtonIndex; // Mouse button index context menu action will react to (0-left, 1-right, 2-middle)
bool EnableSmoothZoom;
float SmoothZoomPower;
Config() Config()
: SettingsFile("NodeEditor.json") : SettingsFile("NodeEditor.json")
@ -116,6 +123,12 @@ struct Config
, SelectButtonIndex(0) , SelectButtonIndex(0)
, NavigateButtonIndex(1) , NavigateButtonIndex(1)
, ContextMenuButtonIndex(1) , ContextMenuButtonIndex(1)
, EnableSmoothZoom(false)
# ifdef __APPLE__
, SmoothZoomPower(1.1f)
# else
, SmoothZoomPower(1.3f)
# endif
{ {
} }
}; };
@ -174,6 +187,8 @@ enum StyleVar
StyleVar_GroupBorderWidth, StyleVar_GroupBorderWidth,
StyleVar_HighlightConnectedLinks, StyleVar_HighlightConnectedLinks,
StyleVar_SnapLinkToPinDir, StyleVar_SnapLinkToPinDir,
StyleVar_HoveredNodeBorderOffset,
StyleVar_SelectedNodeBorderOffset,
StyleVar_Count StyleVar_Count
}; };
@ -184,7 +199,9 @@ struct Style
float NodeRounding; float NodeRounding;
float NodeBorderWidth; float NodeBorderWidth;
float HoveredNodeBorderWidth; float HoveredNodeBorderWidth;
float HoverNodeBorderOffset;
float SelectedNodeBorderWidth; float SelectedNodeBorderWidth;
float SelectedNodeBorderOffset;
float PinRounding; float PinRounding;
float PinBorderWidth; float PinBorderWidth;
float LinkStrength; float LinkStrength;
@ -209,35 +226,37 @@ struct Style
Style() Style()
{ {
NodePadding = ImVec4(8, 8, 8, 8); NodePadding = ImVec4(8, 8, 8, 8);
NodeRounding = 12.0f; NodeRounding = 12.0f;
NodeBorderWidth = 1.5f; NodeBorderWidth = 1.5f;
HoveredNodeBorderWidth = 3.5f; HoveredNodeBorderWidth = 3.5f;
SelectedNodeBorderWidth = 3.5f; HoverNodeBorderOffset = 0.0f;
PinRounding = 4.0f; SelectedNodeBorderWidth = 3.5f;
PinBorderWidth = 0.0f; SelectedNodeBorderOffset = 0.0f;
LinkStrength = 100.0f; PinRounding = 4.0f;
SourceDirection = ImVec2(1.0f, 0.0f); PinBorderWidth = 0.0f;
TargetDirection = ImVec2(-1.0f, 0.0f); LinkStrength = 100.0f;
ScrollDuration = 0.35f; SourceDirection = ImVec2(1.0f, 0.0f);
FlowMarkerDistance = 30.0f; TargetDirection = ImVec2(-1.0f, 0.0f);
FlowSpeed = 150.0f; ScrollDuration = 0.35f;
FlowDuration = 2.0f; FlowMarkerDistance = 30.0f;
PivotAlignment = ImVec2(0.5f, 0.5f); FlowSpeed = 150.0f;
PivotSize = ImVec2(0.0f, 0.0f); FlowDuration = 2.0f;
PivotScale = ImVec2(1, 1); PivotAlignment = ImVec2(0.5f, 0.5f);
PivotSize = ImVec2(0.0f, 0.0f);
PivotScale = ImVec2(1, 1);
#if IMGUI_VERSION_NUM > 18101 #if IMGUI_VERSION_NUM > 18101
PinCorners = ImDrawFlags_RoundCornersAll; PinCorners = ImDrawFlags_RoundCornersAll;
#else #else
PinCorners = ImDrawCornerFlags_All; PinCorners = ImDrawCornerFlags_All;
#endif #endif
PinRadius = 0.0f; PinRadius = 0.0f;
PinArrowSize = 0.0f; PinArrowSize = 0.0f;
PinArrowWidth = 0.0f; PinArrowWidth = 0.0f;
GroupRounding = 6.0f; GroupRounding = 6.0f;
GroupBorderWidth = 1.0f; GroupBorderWidth = 1.0f;
HighlightConnectedLinks = 0.0f; HighlightConnectedLinks = 0.0f;
SnapLinkToPinDir = 0.0f; SnapLinkToPinDir = 0.0f;
Colors[StyleColor_Bg] = ImColor( 60, 60, 70, 200); Colors[StyleColor_Bg] = ImColor( 60, 60, 70, 200);
Colors[StyleColor_Grid] = ImColor(120, 120, 120, 40); Colors[StyleColor_Grid] = ImColor(120, 120, 120, 40);
@ -267,150 +286,150 @@ struct EditorContext;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void SetCurrentEditor(EditorContext* ctx); IMGUI_NODE_EDITOR_API void SetCurrentEditor(EditorContext* ctx);
EditorContext* GetCurrentEditor(); IMGUI_NODE_EDITOR_API EditorContext* GetCurrentEditor();
EditorContext* CreateEditor(const Config* config = nullptr); IMGUI_NODE_EDITOR_API EditorContext* CreateEditor(const Config* config = nullptr);
void DestroyEditor(EditorContext* ctx); IMGUI_NODE_EDITOR_API void DestroyEditor(EditorContext* ctx);
const Config& GetConfig(EditorContext* ctx = nullptr); IMGUI_NODE_EDITOR_API const Config& GetConfig(EditorContext* ctx = nullptr);
Style& GetStyle(); IMGUI_NODE_EDITOR_API Style& GetStyle();
const char* GetStyleColorName(StyleColor colorIndex); IMGUI_NODE_EDITOR_API const char* GetStyleColorName(StyleColor colorIndex);
void PushStyleColor(StyleColor colorIndex, const ImVec4& color); IMGUI_NODE_EDITOR_API void PushStyleColor(StyleColor colorIndex, const ImVec4& color);
void PopStyleColor(int count = 1); IMGUI_NODE_EDITOR_API void PopStyleColor(int count = 1);
void PushStyleVar(StyleVar varIndex, float value); IMGUI_NODE_EDITOR_API void PushStyleVar(StyleVar varIndex, float value);
void PushStyleVar(StyleVar varIndex, const ImVec2& value); IMGUI_NODE_EDITOR_API void PushStyleVar(StyleVar varIndex, const ImVec2& value);
void PushStyleVar(StyleVar varIndex, const ImVec4& value); IMGUI_NODE_EDITOR_API void PushStyleVar(StyleVar varIndex, const ImVec4& value);
void PopStyleVar(int count = 1); IMGUI_NODE_EDITOR_API void PopStyleVar(int count = 1);
void Begin(const char* id, const ImVec2& size = ImVec2(0, 0)); IMGUI_NODE_EDITOR_API void Begin(const char* id, const ImVec2& size = ImVec2(0, 0));
void End(); IMGUI_NODE_EDITOR_API void End();
void BeginNode(NodeId id); IMGUI_NODE_EDITOR_API void BeginNode(NodeId id);
void BeginPin(PinId id, PinKind kind); IMGUI_NODE_EDITOR_API void BeginPin(PinId id, PinKind kind);
void PinRect(const ImVec2& a, const ImVec2& b); IMGUI_NODE_EDITOR_API void PinRect(const ImVec2& a, const ImVec2& b);
void PinPivotRect(const ImVec2& a, const ImVec2& b); IMGUI_NODE_EDITOR_API void PinPivotRect(const ImVec2& a, const ImVec2& b);
void PinPivotSize(const ImVec2& size); IMGUI_NODE_EDITOR_API void PinPivotSize(const ImVec2& size);
void PinPivotScale(const ImVec2& scale); IMGUI_NODE_EDITOR_API void PinPivotScale(const ImVec2& scale);
void PinPivotAlignment(const ImVec2& alignment); IMGUI_NODE_EDITOR_API void PinPivotAlignment(const ImVec2& alignment);
void EndPin(); IMGUI_NODE_EDITOR_API void EndPin();
void Group(const ImVec2& size); IMGUI_NODE_EDITOR_API void Group(const ImVec2& size);
void EndNode(); IMGUI_NODE_EDITOR_API void EndNode();
bool BeginGroupHint(NodeId nodeId); IMGUI_NODE_EDITOR_API bool BeginGroupHint(NodeId nodeId);
ImVec2 GetGroupMin(); IMGUI_NODE_EDITOR_API ImVec2 GetGroupMin();
ImVec2 GetGroupMax(); IMGUI_NODE_EDITOR_API ImVec2 GetGroupMax();
ImDrawList* GetHintForegroundDrawList(); IMGUI_NODE_EDITOR_API ImDrawList* GetHintForegroundDrawList();
ImDrawList* GetHintBackgroundDrawList(); IMGUI_NODE_EDITOR_API ImDrawList* GetHintBackgroundDrawList();
void EndGroupHint(); IMGUI_NODE_EDITOR_API void EndGroupHint();
// TODO: Add a way to manage node background channels // 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); IMGUI_NODE_EDITOR_API bool BeginCreate(const ImVec4& color = ImVec4(1, 1, 1, 1), float thickness = 1.0f);
bool QueryNewLink(PinId* startId, PinId* endId); IMGUI_NODE_EDITOR_API bool QueryNewLink(PinId* startId, PinId* endId);
bool QueryNewLink(PinId* startId, PinId* endId, const ImVec4& color, float thickness = 1.0f); IMGUI_NODE_EDITOR_API bool QueryNewLink(PinId* startId, PinId* endId, const ImVec4& color, float thickness = 1.0f);
bool QueryNewNode(PinId* pinId); IMGUI_NODE_EDITOR_API bool QueryNewNode(PinId* pinId);
bool QueryNewNode(PinId* pinId, const ImVec4& color, float thickness = 1.0f); IMGUI_NODE_EDITOR_API bool QueryNewNode(PinId* pinId, const ImVec4& color, float thickness = 1.0f);
bool AcceptNewItem(); IMGUI_NODE_EDITOR_API bool AcceptNewItem();
bool AcceptNewItem(const ImVec4& color, float thickness = 1.0f); IMGUI_NODE_EDITOR_API bool AcceptNewItem(const ImVec4& color, float thickness = 1.0f);
void RejectNewItem(); IMGUI_NODE_EDITOR_API void RejectNewItem();
void RejectNewItem(const ImVec4& color, float thickness = 1.0f); IMGUI_NODE_EDITOR_API void RejectNewItem(const ImVec4& color, float thickness = 1.0f);
void EndCreate(); IMGUI_NODE_EDITOR_API void EndCreate();
bool BeginDelete(); IMGUI_NODE_EDITOR_API bool BeginDelete();
bool QueryDeletedLink(LinkId* linkId, PinId* startId = nullptr, PinId* endId = nullptr); IMGUI_NODE_EDITOR_API bool QueryDeletedLink(LinkId* linkId, PinId* startId = nullptr, PinId* endId = nullptr);
bool QueryDeletedNode(NodeId* nodeId); IMGUI_NODE_EDITOR_API bool QueryDeletedNode(NodeId* nodeId);
bool AcceptDeletedItem(bool deleteDependencies = true); IMGUI_NODE_EDITOR_API bool AcceptDeletedItem(bool deleteDependencies = true);
void RejectDeletedItem(); IMGUI_NODE_EDITOR_API void RejectDeletedItem();
void EndDelete(); IMGUI_NODE_EDITOR_API void EndDelete();
void SetNodePosition(NodeId nodeId, const ImVec2& editorPosition); IMGUI_NODE_EDITOR_API void SetNodePosition(NodeId nodeId, const ImVec2& editorPosition);
void SetGroupSize(NodeId nodeId, const ImVec2& size); IMGUI_NODE_EDITOR_API void SetGroupSize(NodeId nodeId, const ImVec2& size);
ImVec2 GetNodePosition(NodeId nodeId); IMGUI_NODE_EDITOR_API ImVec2 GetNodePosition(NodeId nodeId);
ImVec2 GetNodeSize(NodeId nodeId); IMGUI_NODE_EDITOR_API ImVec2 GetNodeSize(NodeId nodeId);
void CenterNodeOnScreen(NodeId nodeId); IMGUI_NODE_EDITOR_API 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 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
float GetNodeZPosition(NodeId nodeId); // Returns node z position, defaults is 0.0f 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(); IMGUI_NODE_EDITOR_API void Suspend();
void Resume(); IMGUI_NODE_EDITOR_API void Resume();
bool IsSuspended(); IMGUI_NODE_EDITOR_API bool IsSuspended();
bool IsActive(); IMGUI_NODE_EDITOR_API bool IsActive();
bool HasSelectionChanged(); IMGUI_NODE_EDITOR_API bool HasSelectionChanged();
int GetSelectedObjectCount(); IMGUI_NODE_EDITOR_API int GetSelectedObjectCount();
int GetSelectedNodes(NodeId* nodes, int size); IMGUI_NODE_EDITOR_API int GetSelectedNodes(NodeId* nodes, int size);
int GetSelectedLinks(LinkId* links, int size); IMGUI_NODE_EDITOR_API int GetSelectedLinks(LinkId* links, int size);
bool IsNodeSelected(NodeId nodeId); IMGUI_NODE_EDITOR_API bool IsNodeSelected(NodeId nodeId);
bool IsLinkSelected(LinkId linkId); IMGUI_NODE_EDITOR_API bool IsLinkSelected(LinkId linkId);
void ClearSelection(); IMGUI_NODE_EDITOR_API void ClearSelection();
void SelectNode(NodeId nodeId, bool append = false); IMGUI_NODE_EDITOR_API void SelectNode(NodeId nodeId, bool append = false);
void SelectLink(LinkId linkId, bool append = false); IMGUI_NODE_EDITOR_API void SelectLink(LinkId linkId, bool append = false);
void DeselectNode(NodeId nodeId); IMGUI_NODE_EDITOR_API void DeselectNode(NodeId nodeId);
void DeselectLink(LinkId linkId); IMGUI_NODE_EDITOR_API void DeselectLink(LinkId linkId);
bool DeleteNode(NodeId nodeId); IMGUI_NODE_EDITOR_API bool DeleteNode(NodeId nodeId);
bool DeleteLink(LinkId linkId); IMGUI_NODE_EDITOR_API bool DeleteLink(LinkId linkId);
bool HasAnyLinks(NodeId nodeId); // Returns true if node has any link connected IMGUI_NODE_EDITOR_API bool HasAnyLinks(NodeId nodeId); // Returns true if node has any link connected
bool HasAnyLinks(PinId pinId); // Return true if pin has any link connected IMGUI_NODE_EDITOR_API bool HasAnyLinks(PinId pinId); // Return true if pin has any link connected
int BreakLinks(NodeId nodeId); // Break all links connected to this node IMGUI_NODE_EDITOR_API 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 int BreakLinks(PinId pinId); // Break all links connected to this pin
void NavigateToContent(float duration = -1); IMGUI_NODE_EDITOR_API void NavigateToContent(float duration = -1);
void NavigateToSelection(bool zoomIn = false, float duration = -1); IMGUI_NODE_EDITOR_API void NavigateToSelection(bool zoomIn = false, float duration = -1);
bool ShowNodeContextMenu(NodeId* nodeId); IMGUI_NODE_EDITOR_API bool ShowNodeContextMenu(NodeId* nodeId);
bool ShowPinContextMenu(PinId* pinId); IMGUI_NODE_EDITOR_API bool ShowPinContextMenu(PinId* pinId);
bool ShowLinkContextMenu(LinkId* linkId); IMGUI_NODE_EDITOR_API bool ShowLinkContextMenu(LinkId* linkId);
bool ShowBackgroundContextMenu(); IMGUI_NODE_EDITOR_API bool ShowBackgroundContextMenu();
void EnableShortcuts(bool enable); IMGUI_NODE_EDITOR_API void EnableShortcuts(bool enable);
bool AreShortcutsEnabled(); IMGUI_NODE_EDITOR_API bool AreShortcutsEnabled();
bool BeginShortcut(); IMGUI_NODE_EDITOR_API bool BeginShortcut();
bool AcceptCut(); IMGUI_NODE_EDITOR_API bool AcceptCut();
bool AcceptCopy(); IMGUI_NODE_EDITOR_API bool AcceptCopy();
bool AcceptPaste(); IMGUI_NODE_EDITOR_API bool AcceptPaste();
bool AcceptDuplicate(); IMGUI_NODE_EDITOR_API bool AcceptDuplicate();
bool AcceptCreateNode(); IMGUI_NODE_EDITOR_API bool AcceptCreateNode();
int GetActionContextSize(); IMGUI_NODE_EDITOR_API int GetActionContextSize();
int GetActionContextNodes(NodeId* nodes, int size); IMGUI_NODE_EDITOR_API int GetActionContextNodes(NodeId* nodes, int size);
int GetActionContextLinks(LinkId* links, int size); IMGUI_NODE_EDITOR_API int GetActionContextLinks(LinkId* links, int size);
void EndShortcut(); IMGUI_NODE_EDITOR_API void EndShortcut();
float GetCurrentZoom(); IMGUI_NODE_EDITOR_API float GetCurrentZoom();
NodeId GetHoveredNode(); IMGUI_NODE_EDITOR_API NodeId GetHoveredNode();
PinId GetHoveredPin(); IMGUI_NODE_EDITOR_API PinId GetHoveredPin();
LinkId GetHoveredLink(); IMGUI_NODE_EDITOR_API LinkId GetHoveredLink();
NodeId GetDoubleClickedNode(); IMGUI_NODE_EDITOR_API NodeId GetDoubleClickedNode();
PinId GetDoubleClickedPin(); IMGUI_NODE_EDITOR_API PinId GetDoubleClickedPin();
LinkId GetDoubleClickedLink(); IMGUI_NODE_EDITOR_API LinkId GetDoubleClickedLink();
bool IsBackgroundClicked(); IMGUI_NODE_EDITOR_API bool IsBackgroundClicked();
bool IsBackgroundDoubleClicked(); IMGUI_NODE_EDITOR_API bool IsBackgroundDoubleClicked();
ImGuiMouseButton GetBackgroundClickButtonIndex(); // -1 if none IMGUI_NODE_EDITOR_API ImGuiMouseButton GetBackgroundClickButtonIndex(); // -1 if none
ImGuiMouseButton GetBackgroundDoubleClickButtonIndex(); // -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(); IMGUI_NODE_EDITOR_API ImVec2 GetScreenSize();
ImVec2 ScreenToCanvas(const ImVec2& pos); IMGUI_NODE_EDITOR_API ImVec2 ScreenToCanvas(const ImVec2& pos);
ImVec2 CanvasToScreen(const ImVec2& pos); IMGUI_NODE_EDITOR_API ImVec2 CanvasToScreen(const ImVec2& pos);
int GetNodeCount(); // Returns number of submitted nodes since Begin() call IMGUI_NODE_EDITOR_API 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 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 // VERSION 0.9.1
// //
@ -767,8 +760,3 @@ int ax::NodeEditor::GetOrderedNodeIds(NodeId* nodes, int size)
{ {
return s_Editor->GetNodeIds(nodes, 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 // 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_node_editor.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
# include <imgui.h> # include <imgui.h>
# define IMGUI_DEFINE_MATH_OPERATORS
# include <imgui_internal.h> # include <imgui_internal.h>
# include "imgui_extra_math.h" # include "imgui_extra_math.h"
# include "imgui_bezier_math.h" # include "imgui_bezier_math.h"
@ -440,7 +435,7 @@ struct Node final: Object
virtual bool IsSelectable() override { return true; } virtual bool IsSelectable() override { return true; }
virtual void Draw(ImDrawList* drawList, DrawFlags flags = None) override final; 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); 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); 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); float MatchZoom(int steps, float fallbackZoom);
int MatchZoomIndex(int direction); int MatchZoomIndex(int direction);
@ -1561,8 +1558,3 @@ private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
# endif // __IMGUI_NODE_EDITOR_INTERNAL_H__ # 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; 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) { void NodeSocketEditor(Socket& socket) {
int mode_current = static_cast<int>(socket.m_type); int mode_current = static_cast<int>(socket.m_type);
ImGui::InputText("Name", &socket.m_name); ImGui::InputText("Name", &socket.m_name);
@ -182,9 +190,7 @@ void AnimGraphEditorRenderSidebar(
100.f); 100.f);
} else if (property.m_type == SocketType::SocketTypeBool) { } else if (property.m_type == SocketType::SocketTypeBool) {
bool flag_value = property.GetValue<bool>(); bool flag_value = property.GetValue<bool>();
if (ImGui::Checkbox( if (ImGui::Checkbox(property.m_name.c_str(), &flag_value)) {
property.m_name.c_str(),
&flag_value)) {
property.SetValue(flag_value); property.SetValue(flag_value);
} }
} else if (property.m_type == SocketType::SocketTypeString) { } else if (property.m_type == SocketType::SocketTypeString) {
@ -255,14 +261,14 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
} }
if (ImGui::Button("Load")) { if (ImGui::Button("Load")) {
sGraphGresource.loadFromFile("editor_graph.json"); 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; 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")) { if (ImGui::Button("Clear")) {
sGraphGresource.clear(); sGraphGresource.clear();
@ -285,8 +291,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
ax::NodeEditor::SetCurrentEditor(context); ax::NodeEditor::SetCurrentEditor(context);
ax::NodeEditor::Begin("Graph Editor"); 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; for (size_t node_id = 0, n = sGraphGresource.m_nodes.size(); node_id < n;
node_id++) { node_id++) {
AnimNodeResource& node_resource = sGraphGresource.m_nodes[node_id]; AnimNodeResource& node_resource = sGraphGresource.m_nodes[node_id];
@ -295,70 +300,63 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
// continue; // continue;
} }
node_editor_id++;
if (sGraphLoadedThisFrame) { 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()); ImGui::Text("%s", node_resource.m_type_name.c_str());
// // Inputs // Inputs
// std::vector<Socket>& node_inputs = std::vector<Socket>& node_inputs =
// node_resource.m_socket_accessor->m_inputs; node_resource.m_socket_accessor->m_inputs;
// for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) { for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) {
// Socket& socket = node_inputs[j]; Socket& socket = node_inputs[j];
// int pin_id = static_cast<int>(node_id) + j * 1000; ax::NodeEditor::BeginPin(
// ax::NodeEditor::BeginPin(pin_id, ax::NodeEditor::PinKind::Input); GetNodeInputSocketId(static_cast<int>(node_id), static_cast<int>(j)),
// ImGui::Text("%s", socket.m_name.c_str()); ax::NodeEditor::PinKind::Input);
// ax::NodeEditor::EndPin(); ImGui::Text("%s", socket.m_name.c_str());
// } ax::NodeEditor::EndPin();
// }
// // Outputs
// const std::vector<Socket>& node_outputs = // Outputs
// node_resource.m_socket_accessor->m_outputs; std::vector<Socket>& node_outputs =
// for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) { node_resource.m_socket_accessor->m_outputs;
// const Socket& socket = node_outputs[j]; for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) {
// int pin_id = static_cast<int>(node_id) + j * 1000 * 1000; Socket& socket = node_outputs[j];
// ax::NodeEditor::BeginPin(pin_id, ax::NodeEditor::PinKind::Output); ax::NodeEditor::BeginPin(
// ImGui::Text("%s", socket.m_name.c_str()); GetNodeOutputSocketId(static_cast<int>(node_id), static_cast<int>(j)),
// ax::NodeEditor::EndPin(); ax::NodeEditor::PinKind::Output);
// } ImGui::Text("%s", socket.m_name.c_str());
ax::NodeEditor::EndPin();
}
ax::NodeEditor::EndNode(); ax::NodeEditor::EndNode();
} }
#if 0 int link_id = 0;
int unique_id = 1; for (size_t connection_id = 0, n = sGraphGresource.m_connections.size(); connection_id < n;
ax::NodeEditor::BeginNode(unique_id++); connection_id++) {
const AnimGraphConnectionResource& connection_resource = sGraphGresource.m_connections[connection_id];
// Node A const AnimNodeResource& source_node_resource = sGraphGresource.m_nodes[connection_resource.source_node_index];
ImGui::Text("Node A"); int source_socket_index = source_node_resource.m_socket_accessor->GetOutputIndex(connection_resource.source_socket_name.c_str());
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(); 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 int source_socket_id = GetNodeOutputSocketId(static_cast<int>(connection_resource.source_node_index), source_socket_index);
ax::NodeEditor::BeginNode(unique_id++); 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 #endif
#if 1
// Create Connections // Create Connections
if (ax::NodeEditor::BeginCreate()) { if (ax::NodeEditor::BeginCreate()) {
ax::NodeEditor::PinId input_pin_id, output_pin_id; ax::NodeEditor::PinId input_pin_id, output_pin_id;
@ -370,16 +368,13 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
} }
} }
ax::NodeEditor::EndCreate(); ax::NodeEditor::EndCreate();
#endif
ax::NodeEditor::End(); ax::NodeEditor::End();
ax::NodeEditor::SetCurrentEditor(nullptr);
if (sGraphLoadedThisFrame) {
ax::NodeEditor::NavigateToContent();
}
sGraphLoadedThisFrame = false; sGraphLoadedThisFrame = false;
ax::NodeEditor::SetCurrentEditor(nullptr);
} }
void LegacyAnimGraphEditorUpdate() { void LegacyAnimGraphEditorUpdate() {