Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/docking/mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ description = "Dockable-windows demo using the imgui `docking` feature"
license = "MIT"

[dependencies]
imgui = { path = "../..", features = ["docking"] }
imgui = { path = "../..", features = ["docking", "viewports"] }
64 changes: 50 additions & 14 deletions examples/docking/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,62 @@
// Docking demo — `imgui = { ..., features = ["docking"] }`.
// The imgui.app facade auto-enables ImGuiConfigFlags_DockingEnable when the
// feature is active; DockSpaceOverViewport turns the whole window into a
// dock host, so the two panels below can be dragged into / split around it.
// Docking + multi-viewport demo —
// imgui = { ..., features = ["docking", "viewports"] }
//
// On the first frame, DockBuilder splits the dockspace into an IDE-style
// layout (Scene | Viewport | Inspector, Console at the bottom). Every pane is
// a real dock node: drag any tab to re-split, stack, or float it.
// With `viewports`, drag a tab OUTSIDE the main window and it detaches into
// its own OS window; the "Detached" panel below starts outside on purpose.
import imgui.core;
import imgui.app;

int main() {
return ImGui::App::run({.title = "mcpp imgui docking demo"}, [] {
const auto dockspace = ImGui::DockSpaceOverViewport();
auto dockspace = ImGui::DockSpaceOverViewport();

// Pre-dock both panels into the dockspace on first run; they remain
// freely draggable/splittable afterwards.
ImGui::SetNextWindowDockID(dockspace, ImGui::Cond_FirstUseEver);
ImGui::Begin("Toolbox");
ImGui::TextUnformatted("Drag this panel onto the dockspace.");
ImGui::TextUnformatted("Docked: ");
ImGui::TextUnformatted(ImGui::IsWindowDocked() ? "yes" : "no");
static bool layout_built = false;
if (!layout_built) {
layout_built = true;
const auto root = dockspace;
auto left = ImGui::DockBuilderSplitNode(
dockspace, ImGui::Dir_Left, 0.22f, nullptr, &dockspace);
auto down = ImGui::DockBuilderSplitNode(
dockspace, ImGui::Dir_Down, 0.28f, nullptr, &dockspace);
auto right = ImGui::DockBuilderSplitNode(
dockspace, ImGui::Dir_Right, 0.30f, nullptr, &dockspace);
ImGui::DockBuilderDockWindow("Scene", left);
ImGui::DockBuilderDockWindow("Console", down);
ImGui::DockBuilderDockWindow("Inspector", right);
ImGui::DockBuilderDockWindow("Viewport", dockspace);
ImGui::DockBuilderFinish(root);
}

ImGui::Begin("Scene");
ImGui::TextUnformatted("Scene tree pane (left split).");
ImGui::TextUnformatted(ImGui::IsWindowDocked() ? "docked: yes" : "docked: no");
ImGui::End();

ImGui::Begin("Viewport");
ImGui::TextUnformatted("Central pane. Drag any tab to");
ImGui::TextUnformatted("re-split / stack / float it.");
ImGui::End();

ImGui::SetNextWindowDockID(dockspace, ImGui::Cond_FirstUseEver);
ImGui::Begin("Inspector");
ImGui::TextUnformatted("Split me against the Toolbox.");
ImGui::TextUnformatted("Properties pane (right split).");
ImGui::End();

ImGui::Begin("Console");
ImGui::TextUnformatted("Log pane (bottom split).");
ImGui::End();

// Starts OUTSIDE the main window: with `viewports` this is a real,
// separate OS window from the very first frame.
const auto* main_vp = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(
ImVec2{main_vp->Pos.x + main_vp->Size.x + 60.0f, main_vp->Pos.y + 80.0f},
ImGui::Cond_FirstUseEver);
ImGui::Begin("Detached");
ImGui::TextUnformatted("I live in my own OS window.");
ImGui::TextUnformatted("Drag me back inside to re-dock.");
ImGui::End();
});
}
3 changes: 3 additions & 0 deletions mcpp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ default = []
# docking: export the Dock* API surface and auto-enable
# ImGuiConfigFlags_DockingEnable in the imgui.app facade.
docking = []
# viewports: ImGui windows dragged outside the main window detach into real
# OS windows (multi-viewport). Usually combined with docking.
viewports = []

[dependencies]
compat.imgui = "1.92.8-docking"
Expand Down
14 changes: 14 additions & 0 deletions src/app.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export namespace ImGui::App {
// `docking` feature: enable dockable windows out of the box.
ImGui::GetIO().ConfigFlags |= ImGui::ConfigFlags_DockingEnable;
#endif
#ifdef MCPP_FEATURE_VIEWPORTS
// `viewports` feature: windows dragged outside the main window
// detach into real OS windows.
ImGui::GetIO().ConfigFlags |= ImGui::ConfigFlags_ViewportsEnable;
#endif

if (!Backend::Init(window)) {
const auto error = Backend::LastError();
Expand Down Expand Up @@ -84,6 +89,15 @@ export namespace ImGui::App {
Backend::ClearColor(0.10f, 0.10f, 0.12f, 1.0f);
Backend::ClearColorBuffer();
Backend::RenderDrawData(ImGui::GetDrawData());
#ifdef MCPP_FEATURE_VIEWPORTS
// Render the detached OS windows, then restore the main context.
{
auto* backup = Backend::GetCurrentContext();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
Backend::MakeContextCurrent(backup);
}
#endif
Backend::SwapBuffers(window);
}

Expand Down
4 changes: 4 additions & 0 deletions src/backends/glfw_opengl3.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export namespace ImGui::Backend {
GlfwPlatform::MakeContextCurrent(window);
}

static Window* GetCurrentContext() {
return GlfwPlatform::GetCurrentContext();
}

static void SwapInterval(int interval) {
GlfwPlatform::SwapInterval(interval);
}
Expand Down
4 changes: 4 additions & 0 deletions src/backends/platform_glfw.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export namespace ImGui::Backend {
glfwMakeContextCurrent(window);
}

static Window* GetCurrentContext() {
return glfwGetCurrentContext();
}

static FbSize FramebufferSize(Window* window) {
int width = 0;
int height = 0;
Expand Down
32 changes: 32 additions & 0 deletions src/core.cppm
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
module;

#include <imgui.h>
#ifdef MCPP_FEATURE_DOCKING
// DockBuilder (programmatic dock layouts) lives in the internal header.
#include <imgui_internal.h>
#endif

export module imgui.core;

Expand Down Expand Up @@ -42,9 +46,37 @@ export namespace ImGui {
using ::ImGui::GetWindowDockID;
using ::ImGui::IsWindowDocked;

// DockBuilder — programmatic dock layouts (e.g. an IDE-style default
// split). Upstream ships it in imgui_internal.h; the docking feature
// exports the minimal stable surface needed to build layouts.
using ::ImGui::DockBuilderSplitNode;
using ::ImGui::DockBuilderDockWindow;
using ::ImGui::DockBuilderFinish;

// Unscoped global enumerators, re-exported as namespaced constants for
// module consumers.
inline constexpr int ConfigFlags_DockingEnable = ::ImGuiConfigFlags_DockingEnable;
inline constexpr int Cond_FirstUseEver = ::ImGuiCond_FirstUseEver;
// Typed as the underlying enum so they pass straight into
// DockBuilderSplitNode without the consumer naming ImGuiDir.
inline constexpr ::ImGuiDir Dir_Left = ::ImGuiDir_Left;
inline constexpr ::ImGuiDir Dir_Right = ::ImGuiDir_Right;
inline constexpr ::ImGuiDir Dir_Up = ::ImGuiDir_Up;
inline constexpr ::ImGuiDir Dir_Down = ::ImGuiDir_Down;
}
#endif

// Multi-viewport surface — gated by the `viewports` feature: ImGui windows
// dragged (or positioned) outside the main window become real OS windows.
#ifdef MCPP_FEATURE_VIEWPORTS
export using ImGuiViewport = ::ImGuiViewport;

export namespace ImGui {
using ::ImGui::GetMainViewport;
using ::ImGui::UpdatePlatformWindows;
using ::ImGui::RenderPlatformWindowsDefault;
using ::ImGui::SetNextWindowPos;

inline constexpr int ConfigFlags_ViewportsEnable = ::ImGuiConfigFlags_ViewportsEnable;
}
#endif
Loading