Skip to content

Docking: Detect window close vs tab close #4186

@scottmcnab

Description

@scottmcnab

Version/Branch of Dear ImGui:

Version: 1.83
Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: Custom (Unigine)
Compiler: Visual Studio 2019 v16.1.6
Operating System: Windows 10

My Issue/Question:

Is it possible to detect when a docking window is closed by the window close button, versus an individual tab close button?

close-window-vs-tab

Specifically, I've setup a dockspace with a similar layout to the above using 3 tabs as follows:

auto dockspaceId = ImGui::GetID("MyDockSpace");
// Don't clear previous layout if it exists
auto node = ImGui::DockBuilderGetNode(dockspaceId);
if (node == nullptr) {
    ImGui::DockBuilderAddNode(dockspaceId);

    const auto size = ImVec2(520.0f, 600.0f);
    ImGui::DockBuilderSetNodeSize(dockspaceId, size);

    // Center the window on the screen
    const auto viewport = ImGui::GetMainViewport();
    const auto pos = ImVec2(
        std::max(0.0f, (viewport->WorkSize.x - size.x) / 2.0f),
        std::max(0.0f, (viewport->WorkSize.y - size.y) / 2.0f));
    ImGui::DockBuilderSetNodePos(dockspaceId, pos);

    // Split the dockspace into 2 nodes
    ImGuiID dockspaceA = 0;
    ImGuiID dockspaceB = 0;
    ImGui::DockBuilderSplitNode(dockspaceId, ImGuiDir_Down, 0.60f, &dockspaceB, &dockspaceA);

    // Dock our windows into the docking nodes we made above
    ImGui::DockBuilderDockWindow("Tab A", dockspaceA);
    ImGui::DockBuilderDockWindow("Tab B", dockspaceB);
    ImGui::DockBuilderDockWindow("Tab C", dockspaceB);

    ImGui::DockBuilderFinish(dockspaceId);
}

I need the ability for tabs to be closed individually, but also have the option of closing the entire window.
At the moment the draw code looks like:

// All tabs initially open at construction
bool tab_a_open = true;
bool tab_b_open = true;
bool tab_c_open = true;

// ...

// Draw function here
if (tab_a_open) {
    if (ImGui::Begin("Tab A", &tab_a_open)) {
        // Draw tab A here...
    }
    ImGui::End();
    if (!tab_a_open) {
        // FIXME: only close the other tabs if window closed!
        tab_b_open = tab_c_open = false;
    }
}
if (tab_b_open) {
    if (ImGui::Begin("Tab B", &tab_b_open)) {
        // Draw tab B here...
    }
    ImGui::End();
    if (!tab_b_open) {
        // FIXME: only close the other tabs if window closed!
        tab_a_open = tab_c_open = false;
    }
}
if (tab_c_open) {
    if (ImGui::Begin("Tab C", &tab_c_open)) {
        // Draw tab C here...
    }
    ImGui::End();
    if (!tab_c_open) {
        // FIXME: only close the other tabs if window closed!
        tab_a_open = tab_b_open = false;
    }
}

This code detects that a tab has been closed by checking that the bool* p_open in ImGui::Begin() has been set to false. However, p_open is set to false both when the close button on the tab is clicked, and also when the close button on the window is clicked.

Is there some way I can detect the difference between the window vs tab being closed? I'd like to replace the FIXMEs above with conditional code that only closes the other tabs if the window was closed, and not if just a tab was closed.

Is this possible?
Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions