summaryrefslogtreecommitdiff
path: root/3rdparty/imgui-node-editor/imgui_canvas.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/imgui-node-editor/imgui_canvas.h')
-rw-r--r--3rdparty/imgui-node-editor/imgui_canvas.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/3rdparty/imgui-node-editor/imgui_canvas.h b/3rdparty/imgui-node-editor/imgui_canvas.h
new file mode 100644
index 0000000..44f4347
--- /dev/null
+++ b/3rdparty/imgui-node-editor/imgui_canvas.h
@@ -0,0 +1,258 @@
+// Canvas widget - view over infinite virtual space.
+//
+// Canvas allows you to draw your widgets anywhere over infinite space and provide
+// view over it with support for panning and scaling.
+//
+// When you enter a canvas ImGui is moved to virtual space which mean:
+// - ImGui::GetCursorScreenPos() return (0, 0) and which correspond to top left corner
+// of the canvas on the screen (this can be changed usign CanvasView()).
+// - Mouse input is brought to canvas space, so widgets works as usual.
+// - Everything you draw with ImDrawList will be in virtual space.
+//
+// By default origin point is on top left corner of canvas widget. It can be
+// changed with call to CanvasView() where you can specify what part of space
+// should be viewed by setting viewport origin point and scale. Current state
+// can be queried with CanvasViewOrigin() and CanvasViewScale().
+//
+// Viewport size is controlled by 'size' parameter in BeginCanvas(). You can query
+// it using CanvasContentMin/Max/Size functions. They are useful if you to not specify
+// canvas size in which case all free space is used.
+//
+// Bounds of visible region of infinite space can be queried using CanvasViewMin/Max/Size
+// functions. Everything that is drawn outside of this region will be clipped
+// as usual in ImGui.
+//
+// While drawing inside canvas you can translate position from world (usual ImGui space)
+// to virtual space and back usign CanvasFromWorld()/CanvasToWorld().
+//
+// Canvas can be nested in each other (they are regular widgets after all). There
+// is a way to transform position between current and parent canvas with
+// CanvasFromParent()/CanvasToParent().
+//
+// Sometimes in more elaborate scenarios you want to move out canvas virtual space,
+// do something and came back. You can do that with SuspendCanvas() and ResumeCanvas().
+//
+// Note:
+// It is not valid to call canvas API outside of BeginCanvas() / EndCanvas() scope.
+//
+// LICENSE
+// This software is dual-licensed to the public domain and under the following
+// license: you are granted a perpetual, irrevocable license to copy, modify,
+// publish, and distribute this file as you see fit.
+//
+// CREDITS
+// Written by Michal Cichon
+# ifndef __IMGUI_EX_CANVAS_H__
+# define __IMGUI_EX_CANVAS_H__
+# pragma once
+
+# include <imgui.h>
+# include <imgui_internal.h> // ImRect, ImFloor
+
+namespace ImGuiEx {
+
+struct CanvasView
+{
+ ImVec2 Origin;
+ float Scale = 1.0f;
+ float InvScale = 1.0f;
+
+ CanvasView() = default;
+ CanvasView(const ImVec2& origin, float scale)
+ : Origin(origin)
+ , Scale(scale)
+ , InvScale(scale ? 1.0f / scale : 0.0f)
+ {
+ }
+
+ void Set(const ImVec2& origin, float scale)
+ {
+ *this = CanvasView(origin, scale);
+ }
+};
+
+// Canvas widget represent view over infinite plane.
+//
+// It acts like a child window without scroll bars with
+// ability to zoom to specific part of canvas plane.
+//
+// Widgets are clipped according to current view exactly
+// same way ImGui do. To avoid `missing widgets` artifacts first
+// setup visible region with SetView() then draw content.
+//
+// Everything drawn with ImDrawList betwen calls to Begin()/End()
+// will be drawn on canvas plane. This behavior can be suspended
+// by calling Suspend() and resumed by calling Resume().
+//
+// Warning:
+// Please do not interleave canvas with use of channel splitter.
+// Keep channel splitter contained inside canvas or always
+// call canvas functions from same channel.
+struct Canvas
+{
+ // Begins drawing content of canvas plane.
+ //
+ // When false is returned that mean canvas is not visible to the
+ // user can drawing should be skipped and End() not called.
+ // When true is returned drawing must be ended with call to End().
+ //
+ // If any size component is equal to zero or less canvas will
+ // automatically expand to all available area on that axis.
+ // So (0, 300) will take horizontal space and have height
+ // of 300 points. (0, 0) will take all remaining space of
+ // the window.
+ //
+ // 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);
+
+ // Ends interaction with canvas plane.
+ //
+ // Must be called only when Begin() retuned true.
+ void End();
+
+ // Sets visible region of canvas plane.
+ //
+ // Origin is an offset of infinite plane origin from top left
+ // 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);
+
+ // 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);
+
+ // Calculates view over specific point on canvas plane.
+ 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);
+
+ // Calculates view over specific rectangle on canvas plane.
+ 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();
+
+ // Transforms point from canvas plane to ImGui.
+ ImVec2 FromLocal(const ImVec2& point) const;
+ 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;
+
+ // Transforms point from ImGui to canvas plane.
+ ImVec2 ToLocal(const ImVec2& point) const;
+ 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;
+
+ // Returns widget bounds.
+ //
+ // Note:
+ // Rect is valid after call to Begin().
+ const ImRect& Rect() const { return m_WidgetRect; }
+
+ // Returns visible region on canvas plane (in canvas plane coordinates).
+ const ImRect& ViewRect() const { return m_ViewRect; }
+
+ // Calculates visible region for view.
+ ImRect CalcViewRect(const CanvasView& view) const;
+
+ // Returns current view.
+ const CanvasView& View() const { return m_View; }
+
+ // Returns origin of the view.
+ //
+ // Origin is an offset of infinite plane origin from top left
+ // corner of the canvas.
+ const ImVec2& ViewOrigin() const { return m_View.Origin; }
+
+ // Returns scale of the view.
+ float ViewScale() const { return m_View.Scale; }
+
+ // Returns true if canvas is suspended.
+ //
+ // See: Suspend()/Resume()
+ bool IsSuspended() const { return m_SuspendCounter > 0; }
+
+private:
+# define IMGUI_EX_CANVAS_DEFERED() 0
+
+# if IMGUI_EX_CANVAS_DEFERED()
+ struct Range
+ {
+ int BeginVertexIndex = 0;
+ int EndVertexIndex = 0;
+ int BeginComandIndex = 0;
+ int EndCommandIndex = 0;
+ };
+# endif
+
+ void UpdateViewTransformPosition();
+
+ void SaveInputState();
+ void RestoreInputState();
+
+ void SaveViewportState();
+ void RestoreViewportState();
+
+ void EnterLocalSpace();
+ void LeaveLocalSpace();
+
+ bool m_InBeginEnd = false;
+
+ ImVec2 m_WidgetPosition;
+ ImVec2 m_WidgetSize;
+ ImRect m_WidgetRect;
+
+ ImDrawList* m_DrawList = nullptr;
+ int m_ExpectedChannel = 0;
+
+# if IMGUI_EX_CANVAS_DEFERED()
+ ImVector<Range> m_Ranges;
+ Range* m_CurrentRange = nullptr;
+# endif
+
+ int m_DrawListCommadBufferSize = 0;
+ int m_DrawListStartVertexIndex = 0;
+
+ CanvasView m_View;
+ ImRect m_ViewRect;
+
+ ImVec2 m_ViewTransformPosition;
+
+ int m_SuspendCounter = 0;
+
+ float m_LastFringeScale = 1.0f;
+
+ ImVec2 m_MousePosBackup;
+ ImVec2 m_MousePosPrevBackup;
+ ImVec2 m_MouseClickedPosBackup[IM_ARRAYSIZE(ImGuiIO::MouseClickedPos)];
+ ImVec2 m_WindowCursorMaxBackup;
+
+# if defined(IMGUI_HAS_VIEWPORT)
+ ImVec2 m_ViewportPosBackup;
+ ImVec2 m_ViewportSizeBackup;
+# endif
+};
+
+} // namespace ImGuiEx
+
+# endif // __IMGUI_EX_CANVAS_H__ \ No newline at end of file