Skip to content

Instantly share code, notes, and snippets.

@BanditTech
Forked from AidanSun05/ImGuiDockspaceExample.cpp
Last active April 26, 2023 20:24
Show Gist options
  • Save BanditTech/17b238152eea593036eae054f13a69d3 to your computer and use it in GitHub Desktop.
Save BanditTech/17b238152eea593036eae054f13a69d3 to your computer and use it in GitHub Desktop.
A modified DockSpace example for Dear ImGui.NET. Changes are listed at the top of the file.
// CHANGES MADE:
// Fix fullscreen background being opaque.
// Remove helptext as I dont know howto include that in C#
// Convert most of the example to using C# syntax and functions provided with ImGui.NET
// ------------
// Added more clarifying comments inside the function.
// Removed MSVC warning C6011 - null pointer dereference.
// Fixed a slight grammar error - "This demo app only demonstrate" => "This demo app only demonstrates"
// Still Broken:
// ------------
// The The menu only seems to have functional code for changing between Fullscreen, and having padding.
// Demonstrate using DockSpace() to create an explicit docking node within an existing window.
// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking!
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
// About dockspaces:
// - Use DockSpace() to create an explicit dock node _within_ an existing window.
// - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport.
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode.
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame! (*)
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
// (*) because of this constraint, the implicit \"Debug\" window can not be docked into an explicit DockSpace() node,
// because that window is submitted as part of the part of the NewFrame() call. An easy workaround is that you can create
// your own implicit "Debug##2" window after calling DockSpace() and leave it in the window stack for anyone to use.
private void ShowExampleAppDockSpace(ref bool p_open)
{
// Variables to configure the Dockspace example.
// Includes App.fullscreen, App.padding
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags.None;
// In this example, we're embedding the Dockspace into an invisible parent window to make it more configurable.
// We set ImGuiWindowFlags_NoDocking to make sure the parent isn't dockable into because this is handled by the Dockspace.
//
// ImGuiWindowFlags_MenuBar is to show a menu bar with config options. This isn't necessary to the functionality of a
// Dockspace, but it is here to provide a way to change the configuration flags interactively.
// You can remove the MenuBar flag if you don't want it in your app, but also remember to remove the code which actually
// renders the menu bar, found at the end of this function.
ImGuiWindowFlags window_flags = ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoDocking;
// Is the example in Fullscreen mode?
if (App.fullscreen)
{
// If so, get the main viewport:
var viewport = ImGui.GetMainViewport();
// Set the parent window's position, size, and viewport to match that of the main viewport. This is so the parent window
// completely covers the main viewport, giving it a "full-screen" feel.
ImGui.SetNextWindowPos(viewport.WorkPos);
ImGui.SetNextWindowSize(viewport.WorkSize);
ImGui.SetNextWindowViewport(viewport.ID);
// Set the parent window's styles to match that of the main viewport:
ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0.0f); // No corner rounding on the window
ImGui.PushStyleVar(ImGuiStyleVar.WindowBorderSize, 0.0f); // No border around the window
// Set the alpha component of the window background color to 0 to make it transparent
ImGui.PushStyleColor(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 0));
// Manipulate the window flags to make it inaccessible to the user (no titlebar, resize/move, or navigation)
window_flags |= ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove;
window_flags |= ImGuiWindowFlags.NoBringToFrontOnFocus | ImGuiWindowFlags.NoNavFocus;
}
else
{
// The example is not in Fullscreen mode (the parent window can be dragged around and resized), disable the
// ImGuiDockNodeFlags_PassthruCentralNode flag.
dockspace_flags &= ~ImGuiDockNodeFlags.PassthruCentralNode;
}
// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
// and handle the pass-thru hole, so the parent window should not have its own background:
if ((dockspace_flags & ImGuiDockNodeFlags.PassthruCentralNode) != 0)
window_flags |= ImGuiWindowFlags.NoBackground;
// If the padding option is disabled, set the parent window's padding size to 0 to effectively hide said padding.
if (!App.padding)
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(0.0f, 0.0f));
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
// all active windows docked into it will lose their parent and become undocked.
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
ImGui.Begin("DockSpace Demo", ref p_open, window_flags);
// Remove the padding configuration - we pushed it, now we pop it:
if (!App.padding)
ImGui.PopStyleVar();
// Pop the two style rules set in Fullscreen mode - the corner rounding and the border size.
if (App.fullscreen)
{
ImGui.PopStyleColor();
ImGui.PopStyleVar(2);
}
// Check if Docking is enabled:
ImGuiIOPtr io = ImGui.GetIO();
if ((io.ConfigFlags & ImGuiConfigFlags.DockingEnable) != 0)
{
// Set the alpha component of the docking area background color to 0 to make it transparent
ImGui.PushStyleColor(ImGuiCol.DockingEmptyBg, new Vector4(0, 0, 0, 0));
// If it is, draw the Dockspace with the DockSpace() function.
// The GetID() function is to give a unique identifier to the Dockspace - here, it's "MyDockSpace".
uint dockspace_id = ImGui.GetID("MyDockSpace");
ImGui.DockSpace(dockspace_id, new Vector2(0.0f, 0.0f), dockspace_flags);
ImGui.PopStyleColor();
}
else
{
// Docking is DISABLED - Show a warning message
App.Log("Docking is disabled!");
}
// This is to show the menu bar that will change the config settings at runtime.
// If you copied this demo function into your own code and removed ImGuiWindowFlags_MenuBar at the top of the function,
// you should remove the below if-statement as well.
if (ImGui.BeginMenuBar())
{
if (ImGui.BeginMenu("Options"))
{
// Disabling fullscreen would allow the window to be moved to the front of other windows,
// which we can't undo at the moment without finer window depth/z control.
ImGui.MenuItem("Fullscreen", null, ref App.fullscreen);
ImGui.MenuItem("Padding", null, ref App.padding);
ImGui.Separator();
// Display a menu item for each Dockspace flag, clicking on one will toggle its assigned flag.
if (ImGui.MenuItem("Flag: NoSplit", "", (dockspace_flags & ImGuiDockNodeFlags.NoSplit) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags.NoSplit; }
if (ImGui.MenuItem("Flag: NoResize", "", (dockspace_flags & ImGuiDockNodeFlags.NoResize) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags.NoResize; }
if (ImGui.MenuItem("Flag: NoDockingInCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags.NoDockingInCentralNode) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags.NoDockingInCentralNode; }
if (ImGui.MenuItem("Flag: AutoHideTabBar", "", (dockspace_flags & ImGuiDockNodeFlags.AutoHideTabBar) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags.AutoHideTabBar; }
if (ImGui.MenuItem("Flag: PassthruCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags.PassthruCentralNode) != 0, App.fullscreen)) { dockspace_flags ^= ImGuiDockNodeFlags.PassthruCentralNode; }
ImGui.Separator();
// Display a menu item to close this example.
if (ImGui.MenuItem("Close", null, false, p_open != null))
if (p_open != null) // Remove MSVC warning C6011 (null dereference) - the `p_open != null` in MenuItem() does prevent null derefs, but IntelliSense doesn't analyze that deep so we need to add this in ourselves.
p_open = false; // Changing this variable to false will close the parent window, therefore closing the Dockspace as well.
ImGui.EndMenu();
}
ImGui.EndMenuBar();
}
// End the parent window that contains the Dockspace:
ImGui.End();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment