ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.46k stars 10.13k forks source link

Suggestion: Add a TabItem that behaves like a Button #7958

Closed LPFOXX closed 6 days ago

LPFOXX commented 1 week ago

Version/Branch of Dear ImGui:

Version 1.90, Branch: docking

Back-ends:

imgui_impl_glfw.cpp +imgui_impl_opengl3.cpp

Compiler, OS:

Windows 11 + MSVC 2022

Full config/build information:

Dear ImGui 1.90.7 (19070)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1941
define: _MSVC_LANG=201402
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_glfw
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000440
 DockingEnable
 ViewportsEnable
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
 RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,128
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

My Issue/Question:

I have a window with a tab bar and I dynamically add tabs to it. I noticed, however, that the contents of the selected tab is rendered in (almost) every frame - taking into account tabs deferred rendering.

I am setting some properties whenever a tab is selected/added, which are then used to render to a framebuffer below using ImGui::Image, effectively showing the contents of the selected tab item.

In order to prevent those properties being set on every frame, I'd like to have a tab that behaved like a ImGui::Button - that is, returns true when the tab is selected, added to the tab bar or switched to.

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

// Here's some code anyone can copy and paste to reproduce your issue
namespace ImGui
{
    static ImGuiID gSelectedTab = 0;
    ImGuiID GetSelectedTabItemId()
    {
        const auto& tabBar = ImGui::GetCurrentTabBar();
        return tabBar->SelectedTabId;
    }

        // The name is illustrative
    bool TabItemButton2(const char* label, bool* p_open = (bool*)0, ImGuiTabItemFlags flags = 0)
    {
        auto isOpen = ImGui::BeginTabItem(label, p_open, flags);
        if (isOpen)
        {
            const auto selectedId = GetSelectedTabItemId();
            if (gSelectedTab != selectedId && selectedId != 0)
            {
                gSelectedTab = selectedId;
                ImGui::EndTabItem();
                return true;
            }
            ImGui::EndTabItem();
        }

        return false;
    }
} // namespace ImGui
ocornut commented 1 week ago

, that the contents of the selected tab is rendered in (almost) every frame

Everything in Dear ImGui is rendered every frame. Your question doesn't seem to make much sense to me, it appears to be a mix of a XY Problem and/or premature optimization.

In order to prevent those properties being set on every frame, I'd like to have a tab that behaved like a ImGui::Button - that is, returns true when the tab is selected, added to the tab bar or switched to.

There is a already a tab item that behave like a button: ImGui::TabItemButton(). But what you describe in your sentence is not the behavior of a button. A button returns true when pressed.

If you need to cache e.g. contents into an image since you are going to need to store that image somewhere, you can simply store e.g. the last value of ImGui::GetFrameCount() where the contents was displayed, and compare that to invalidate your image. But my assumption is that you are going against the direction of what dear imgui is powerful for and efficient at.

LPFOXX commented 1 week ago

I appreciate the quick response.

I agree that I might have overstepped a little bit.

As for the the ImGui::TabItemButton I am aware of it. I had already tried using it, but I noticed it does not resemble the style of a regular tab.

LPFOXX commented 1 week ago

I guess this issue may now be closed.

Thx