Last active
December 14, 2022 18:47
-
-
Save marpe/49404475a3c326af43952f8cd3c60645 to your computer and use it in GitHub Desktop.
ImGui window with splitter using docking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
public abstract class SplitWindow | |
{ | |
private string _leftTitle; | |
private string _rightTitle; | |
private string _dockSpaceId; | |
private Action _drawLeft; | |
private Action _drawRight; | |
public string Title; | |
private readonly Action<uint> _initializeDockSpace; | |
protected SplitWindow(string title) | |
{ | |
_leftTitle = $"{title}_Left"; | |
_rightTitle = $"{title}_Right"; | |
_dockSpaceId = $"{title}_DockSpace"; | |
_drawLeft = DrawLeft; | |
_drawRight = DrawRight; | |
_initializeDockSpace = InitializeDockSpace(_leftTitle, _rightTitle); | |
} | |
public void Draw(ref bool isOpen) | |
{ | |
if (!isOpen) | |
return; | |
CreateDockSpace(Title, _dockSpaceId, ref isOpen, _initializeDockSpace); | |
DrawSplit(_leftTitle, _drawLeft); | |
DrawSplit(_rightTitle, _drawRight); | |
} | |
private static void CreateDockSpace(string windowTitle, string dockspaceId, ref bool isOpen, Action<uint> initializeLayout, | |
ImGuiWindowFlags flags = ImGuiWindowFlags.NoCollapse) | |
{ | |
ImGui.SetNextWindowSize(new Vector2(800, 850), ImGuiCond.Appearing); | |
ImGui.SetNextWindowSizeConstraints(new Vector2(200, 200), new Vector2(800, 850)); | |
var result = ImGui.Begin(windowTitle, ImGuiExt.RefPtr(ref isOpen), flags); | |
SetupDockSpace(dockspaceId, initializeLayout, !result); | |
ImGui.End(); | |
} | |
private static Action<uint> InitializeDockSpace(string leftWindowTitle, string rightWindowTitle) | |
{ | |
return dockspaceID => | |
{ | |
var rightDockID = 0u; | |
var leftDockID = 0u; | |
ImGuiInternal.DockBuilderSplitNode(dockspaceID, ImGuiDir.Left, 0.5f, &leftDockID, &rightDockID); | |
ImGuiInternal.DockBuilderDockWindow(leftWindowTitle, leftDockID); | |
ImGuiInternal.DockBuilderDockWindow(rightWindowTitle, rightDockID); | |
}; | |
} | |
private static void DrawSplit(string title, Action drawContent) | |
{ | |
if (ImGui.Begin(title)) | |
{ | |
drawContent(); | |
} | |
SetDockSpaceFlags(); | |
ImGui.End(); | |
} | |
private static void SetDockSpaceFlags() | |
{ | |
var dockNode = ImGuiInternal.GetWindowDockNode(); | |
if (dockNode != null) | |
{ | |
dockNode->LocalFlags = 0; | |
dockNode->LocalFlags |= (ImGuiDockNodeFlags)(ImGuiDockNodeFlagsPrivate_.ImGuiDockNodeFlags_NoDockingSplitMe); | |
dockNode->LocalFlags |= (ImGuiDockNodeFlags)(ImGuiDockNodeFlagsPrivate_.ImGuiDockNodeFlags_NoDockingOverMe); | |
dockNode->LocalFlags |= (ImGuiDockNodeFlags)(ImGuiDockNodeFlagsPrivate_.ImGuiDockNodeFlags_NoTabBar); | |
} | |
} | |
protected abstract void DrawLeft(); | |
protected abstract void DrawRight(); | |
private static void SetupDockSpace(string dockspaceId, Action<uint> setupCallback, bool keepAlive = false) | |
{ | |
var dockspaceID = ImGui.GetID(dockspaceId); | |
ImGuiWindowClass workspaceWindowClass; | |
workspaceWindowClass.ClassId = dockspaceID; | |
workspaceWindowClass.DockingAllowUnclassed = false; | |
if (ImGuiInternal.DockBuilderGetNode(dockspaceID) == null) | |
{ | |
var dockFlags = ImGuiDockNodeFlagsPrivate_.ImGuiDockNodeFlags_DockSpace | | |
ImGuiDockNodeFlagsPrivate_.ImGuiDockNodeFlags_NoWindowMenuButton | | |
ImGuiDockNodeFlagsPrivate_.ImGuiDockNodeFlags_NoCloseButton; | |
ImGuiInternal.DockBuilderAddNode(dockspaceID, (ImGuiDockNodeFlags)dockFlags); | |
var contentAvail = ImGui.GetContentRegionAvail(); | |
var size = new Num.Vector2(MathF.Max(4.0f, contentAvail.X), MathF.Max(4.0f, contentAvail.Y)); | |
ImGuiInternal.DockBuilderSetNodeSize(dockspaceID, size); | |
// | |
setupCallback.Invoke(dockspaceID); | |
// | |
ImGuiInternal.DockBuilderFinish(dockspaceID); | |
} | |
var flags = keepAlive ? ImGuiDockNodeFlags.KeepAliveOnly : ImGuiDockNodeFlags.None | ImGuiDockNodeFlags.NoSplit; | |
ImGui.DockSpace(dockspaceID, new Num.Vector2(0.0f, 0.0f), flags, &workspaceWindowClass); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment