From a0b68cbc9f81555c5492d5cbfe77d3cb1eca8521 Mon Sep 17 00:00:00 2001 From: thedmd Date: Wed, 27 Dec 2023 13:15:30 +0100 Subject: [PATCH] Editor: Add smooth zoom (#266) --- docs/CHANGELOG.txt | 2 ++ imgui_node_editor.cpp | 29 +++++++++++++++++++++++++++-- imgui_node_editor.h | 10 +++++++++- imgui_node_editor_internal.h | 2 ++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d1f9b320..f41699fd 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -6,6 +6,8 @@ v0.10.0 (WIP): NEW: Canvas: Add example of zooming at fixed point (#270) + NEW: Editor: Add smooth zoom (#266) + CHANGE: Canvas: Use ImDrawCallback_ImCanvas macro as draw callback sentinel (#256), thanks @nspitko BUGFIX: Examples: Call ed::EndCreate() and ed::EndDelete() only when ed::BeginCreate() and ed::BeginDelete() returned true diff --git a/imgui_node_editor.cpp b/imgui_node_editor.cpp index 2adf0279..a46beabd 100644 --- a/imgui_node_editor.cpp +++ b/imgui_node_editor.cpp @@ -3449,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; @@ -3626,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); diff --git a/imgui_node_editor.h b/imgui_node_editor.h index 5f7289b2..38532bdc 100644 --- a/imgui_node_editor.h +++ b/imgui_node_editor.h @@ -105,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") @@ -121,6 +123,12 @@ struct Config , SelectButtonIndex(0) , NavigateButtonIndex(1) , ContextMenuButtonIndex(1) + , EnableSmoothZoom(true) +# ifdef __APPLE__ + , SmoothZoomPower(1.1f) +# else + , SmoothZoomPower(1.3f) +# endif { } }; @@ -519,4 +527,4 @@ struct PinId final: Details::SafePointerType //------------------------------------------------------------------------------ -# endif // __IMGUI_NODE_EDITOR_H__ \ No newline at end of file +# endif // __IMGUI_NODE_EDITOR_H__ diff --git a/imgui_node_editor_internal.h b/imgui_node_editor_internal.h index 33c74225..0d018cf5 100644 --- a/imgui_node_editor_internal.h +++ b/imgui_node_editor_internal.h @@ -886,6 +886,8 @@ struct NavigateAction final: EditorAction 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);