Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hiding the spacing between tabs #4368

Open
AidanSun05 opened this issue Jul 27, 2021 · 7 comments
Open

Hiding the spacing between tabs #4368

AidanSun05 opened this issue Jul 27, 2021 · 7 comments
Labels

Comments

@AidanSun05
Copy link

Version/Branch of Dear ImGui:

Version: 1.84 WIP
Branch: docking

Back-end/Renderer/Compiler/OS

(irrelevant)

My Issue/Question:

Is there a way to set the spacing between tabs [both docked and in BeginTabBar()] to 0 without affecting anything else?

image

I want to hide the gaps shown by the arrows in the image above.

Standalone, minimal, complete and verifiable example:

// Outside main loop, something like:
//     ImGuiStyle& style = ImGui::GetStyle();
//     style.TabInnerSpacing = 0.0f;
// ("TabInnerSpacing" does not exist.)

// --------------------

// Inside main loop
ImGui::SetNextWindowSize({ 400, 400 }, ImGuiCond_FirstUseEver);
if (ImGui::Begin("Window 1")) {
    if (ImGui::BeginTabBar("TabBar")) {
        if (ImGui::BeginTabItem("Tab 1")) {
            ImGui::Text("Tab 1");
            ImGui::EndTabItem();
        }

        if (ImGui::BeginTabItem("Tab 2")) {
            ImGui::Text("Tab 2");
            ImGui::EndTabItem();
        }

        ImGui::EndTabBar();
    }
}
ImGui::End();

ImGui::SetNextWindowSize({ 400, 400 }, ImGuiCond_FirstUseEver);
if (ImGui::Begin("Window 2")) {
    if (ImGui::BeginTabBar("TabBar")) {
        if (ImGui::BeginTabItem("Tab 1")) {
            ImGui::Text("Tab 1");
            ImGui::EndTabItem();
        }

        if (ImGui::BeginTabItem("Tab 2")) {
            ImGui::Text("Tab 2");
            ImGui::EndTabItem();
        }

        ImGui::EndTabBar();
    }
}
ImGui::End();
@PathogenDavid
Copy link
Contributor

That separation is controlled by ItemInnerSpacing. However, ItemInnerSpacing is used for many other things besides tabs so you probably don't want to change it for the entire app.

The layout of tabs in a tab bar happens during BeginTabItem. The easiest way to remove the spacing from tab bars would be to make your own variant of BeginTabItem and call it instead:

static bool BeginTabItem_NoSeparation(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0)
{
    ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
    bool result = ImGui::BeginTabItem(label, p_open, flags);
    ImGui::PopStyleVar();
    return result;
}

(You can also call PushStyleVar/PopStyleVar around BeginTabItem directly, but that gets a little annoying since you need to make sure PopStyleVar is always called even when the tab is not selected.)


The layout for the docked windows tab bar is done during NewFrame:

ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
ImGui::NewFrame();
ImGui::PopStyleVar();

(This may have unintended consequences. I didn't notice anything unusual, but quite a lot happens during NewFrame.)

@ocornut ocornut added the style label Jul 27, 2021
@AidanSun05
Copy link
Author

Thanks for your reply @PathogenDavid - I was able to remove the separation between the tabs.

image

However, because of the patch submitted for #4130, the dropdown in the corner is now akwardly pressed up against the first tab. This is because ItemInnerSpacing now controls the space before the first tab as well.

@PathogenDavid
Copy link
Contributor

Ah yeah, hadn't notice that. That's pretty claustrophobic, the X button is pretty squished too.

Unfortunately that does mean there probably isn't a great way to get what you want for the docked window tab bars. My understanding is that styling v2 will allow more granular per-widget customization like this, but as far as I'm aware that's still a long-term project.

If you really want this today, your best bet is probably to fork Dear ImGui for yourself and remove the spacing directly to avoid the unintended side-effects. (Or convince Omar to add a TabInnerSpacing style variable.) It's applied for all tab bars right here in TabBarLayout:

tab_offset += tab->Width + (tab_n < section->TabCount - 1 ? g.Style.ItemInnerSpacing.x : 0.0f);

@AidanSun05
Copy link
Author

AidanSun05 commented Jul 28, 2021

I see. I can propose a TabInnerSpacing style variable with datatype ImVec2. The x field sets the spaces between the tabs, and the y field sets any other spaces present in the tab bar (like dropdown => first tab or tab label => close button).

This way, we can provide more fine-grained control over tab spacing, while still respecting #4130 if the user still wants that behavior (set x = y for that).

Then, in the setup code:

ImGuiStyle& style = ImGui::GetStyle();
style.TabInnerSpacing.x = 0.0f; // No spacing between tabs, but keep the default for everything else

@PathogenDavid @ocornut If this all sounds fine I'll submit a PR for the mainstream and docking branches.

@gaetandezeiraud
Copy link

@AidanSun05 Can you a share a code example?
How to apply the style on ImGui::Begin? Because we don't direclty render the TabItem.

@ocornut
Copy link
Owner

ocornut commented Nov 17, 2022

The docked windows are created in NewFrame() so the style at the time of NewFrame() will apply there.

@gaetandezeiraud
Copy link

Thank you for the anwser.
I tried

ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
ImGui::NewFrame();
ImGui::PopStyleVar();

image

But it doesn't work on my side, with version v1.88. Do nothing (A first glance).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants