diff options
Diffstat (limited to '3rdparty/imgui-node-editor/imgui_canvas.h')
-rw-r--r-- | 3rdparty/imgui-node-editor/imgui_canvas.h | 258 |
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 |