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

Vertical Tab #3032

Open
devkaiwang opened this issue Feb 19, 2020 · 6 comments
Open

Vertical Tab #3032

devkaiwang opened this issue Feb 19, 2020 · 6 comments
Labels
enhancement tabs tab bars, tabs

Comments

@devkaiwang
Copy link

How can we implement vertical tab? Blender's panel looks great (please see the icon tabs on the very left) -
image

@rokups
Copy link
Contributor

rokups commented Feb 19, 2020

Current tab bar implementation does not support vertical tabs. It is possible to implement this, but you would have to do it manually, using BeginChild()/EndChild(), Button() and ImDrawList for rendering of custom shapes.

  1. Render a dark rect as a background for tab selector buttons.
  2. Render all buttons in a column using SetCursorPos()
  3. Render a child with contents of selected tab on the right.

This is overly simplified list, but you should get the general idea.

@ocornut
Copy link
Owner

ocornut commented Feb 23, 2020

As Rokas mentioned you can reimplement a simplified version of a vertical tab yourself. In particular the style you showed in that picture, using icon, is also much easier to implement manually than "rotated tabs":

image

Either way it be nice if this was also supported vertical tab bars. I didn't implement vertical tabs yet, one of the reason being that I was expecting to use rotated text which we don't have yet (aiming for a text refactor in the upcoming semester).

We could imagine that the BeginTabBar() api could allow two distinct options for vertical tabs: rotated tabs with rotated text, and stacked tabs with fixed-width text like in your picture.

@ocornut
Copy link
Owner

ocornut commented Mar 22, 2020

FYI (copied from #705)

The code in #3067 has another function to draw 90 rotated text:
https://github.com/mahilab/mahi-gui/blob/master/src/Mahi/Gui/imgui_plot.cpp

/// Draws vertical text. The position is the bottom left of the text rect.
inline void AddTextVertical(ImDrawList* DrawList, const char *text, ImVec2 pos, ImU32 text_color) {
    pos.x = IM_ROUND(pos.x);
    pos.y = IM_ROUND(pos.y);
    ImFont *font = GImGui->Font;
    const ImFontGlyph *glyph;
    char c;
    ImGuiContext& g = *GImGui;
    ImVec2 text_size = CalcTextSize(text);
    while ((c = *text++)) {
        glyph = font->FindGlyph(c);
        if (!glyph) continue;

        DrawList->PrimReserve(6, 4);
        DrawList->PrimQuadUV(
                pos + ImVec2(glyph->Y0, -glyph->X0),
                pos + ImVec2(glyph->Y0, -glyph->X1),
                pos + ImVec2(glyph->Y1, -glyph->X1),
                pos + ImVec2(glyph->Y1, -glyph->X0),

                ImVec2(glyph->U0, glyph->V0),
                ImVec2(glyph->U1, glyph->V0),
                ImVec2(glyph->U1, glyph->V1),
                ImVec2(glyph->U0, glyph->V1),
                    text_color);
        pos.y -= glyph->AdvanceX;
    }
}

If you don't need clipping, wrapping etc. it's fairly easy to write it.
We will aim to support full-featured rotated text in a new low-level text rendering API this year.

(After you made this post I started trying to implement vertical tab and ended up with the conclusion that it would be more natural to implement once we finish work on the WorkRect system to "claim" space from any direction, instead of the current top-to-bottom focused system.)

@Nitr0-G
Copy link

Nitr0-G commented Dec 11, 2023

We will aim to support full-featured rotated text in a new low-level text rendering API this year.

Is there any progress?

@Displee
Copy link

Displee commented Jan 14, 2024

I also need this

@Displee
Copy link

Displee commented Jan 20, 2024

I was able to replicate this with a child with table with 1 column for the buttons, and a child window for the tab content next to it, which looks like this:
afbeelding
afbeelding

I use Java bindings for ImGui, here's the Kotlin code:

fun show() = ImGuiExt.groupWithoutSpacing {
        if (ImGui.beginChild("TabButtons", 40F, 0F, false, WINDOW_UNDECORATED or ImGuiWindowFlags.NoBackground)) {
            ImGui.sameLine(8F)

            val tabCount = 5
            if (ImGui.beginTable("TabButtonsTable", 1, ImGuiTableFlags.None, 32F, 32F)) {
                repeat(tabCount) {
                    ImGui.tableNextRow()
                    ImGui.tableNextColumn()
                    ImGui.pushID("EditorTab$it")
                    val selected = selectedTab == it
                    if (selected) {
                        ImGui.pushStyleColor(ImGuiCol.Button, buttonActiveBackground)
                        ImGui.pushStyleColor(ImGuiCol.Border, buttonActiveBorderColor)
                    } else {
                        ImGui.pushStyleColor(ImGuiCol.Button, buttonBackground)
                        ImGui.pushStyleColor(ImGuiCol.Border, buttonBorderColor)
                    }
                    ImGui.pushStyleVar(ImGuiStyleVar.FrameBorderSize, 2F)
                    if (ImGui.button("Tab 1", 32F, 32F)) {
                        selectedTab = it
                    }
                    ImGui.popStyleVar()
                    ImGui.popStyleColor(2)
                    ImGui.popID()
                }
                ImGui.endTable()
            }
            ImGui.endChild()
        }

        ImGui.sameLine()

        ImGuiExt.groupWithSpacing {
            ImGui.pushStyleColor(ImGuiCol.ChildBg, tabContentBackgroundColor)
            ImGui.pushStyleColor(ImGuiCol.Border, tabContentBackgroundColor)
            if (ImGui.beginChild("TabContent", WIDTH - 40F, 0F, true, WINDOW_UNDECORATED)) {
                ImGui.popStyleColor(2)
                when (selectedTab) {
                    0 -> {
                        MapTilePropertyTable.show()
                    }
                    1 -> {
                        ImGui.text("Tab 2")
                    }
                }
                ImGui.endChild()
            }
        }
    }

Some of my extension functions :)

    fun groupWithSpacing(x: Float = 8F, y: Float = 4F, block: () -> Unit) {
        ImGui.pushStyleVar(ImGuiStyleVar.ItemSpacing, x, y)
        ImGui.beginGroup()

        block()

        ImGui.popStyleVar()
        ImGui.endGroup()
    }

    fun groupWithoutSpacing(block: () -> Unit) {
        ImGui.pushStyleVar(ImGuiStyleVar.ItemSpacing, 0F, 0F)
        ImGui.beginGroup()

        block()

        ImGui.popStyleVar()
        ImGui.endGroup()
    }

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

No branches or pull requests

5 participants