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

Custom tab bar, and button in front of tabs. #5342

Closed
stormsc1 opened this issue May 23, 2022 · 6 comments
Closed

Custom tab bar, and button in front of tabs. #5342

stormsc1 opened this issue May 23, 2022 · 6 comments
Labels
docking tabs tab bars, tabs

Comments

@stormsc1
Copy link

stormsc1 commented May 23, 2022

Version/Branch of Dear ImGui:
Version: 1.88
Branch: docking

Back-end/Renderer/Compiler/OS:
Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp
Compiler: Microsoft C++ compiler (CL.exe)
Operating System: Windows 10

My Issue/Question:
We are doing a UI overhaul on our internal game engine. The UI design folks came up with some pretty nice looking workspace tab bar design, but I have no idea how to implement it? We really like the default docking behavior of ImGui but we need a way to separate workspace. So what we want to do is, like unreal, having main workspace windows facilitating one workflow made up of multiple smaller tool windows.

My main question is how i style and draw this kind of menu bars, specifically, how do i get the red button in at the start of the bar and offset the tabs to make space for it?
I believe the rest of the style can be obtained with setting imgui style setting, but where should this be done?


@stormsc1 stormsc1 changed the title Custom tab bar, and button in from of tabs. Custom tab bar, and button in front of tabs. May 23, 2022
@PathogenDavid
Copy link
Contributor

You can't currently customize the docking tab bar in this way.

What I'd probably do is modify DockNodeUpdateTabBar to replace the default dock menu button (pictured below) with your special button.

Screenshot of Dear ImGui's default dock menu button.

The button is specifically submitted here:

imgui/imgui.cpp

Lines 15291 to 15298 in 250333d

// Docking/Collapse button
if (has_window_menu_button)
{
if (CollapseButton(host_window->GetID("#COLLAPSE"), window_menu_button_pos, node)) // == DockNodeGetWindowMenuButtonId(node)
OpenPopup("#WindowMenu");
if (IsItemActive())
focus_tab_id = tab_bar->SelectedTabId;
}

Given your mockup I'm assuming you'd be disabling this button either way. It'd be easier to replace the button rather than disable it and add your own since disabling it entirely means you have to fiddle with the layout stuff in DockNodeUpdateTabBar.

(If you want your logo button to appear everywhere you probably want to edit RenderWindowTitleBarContents too since it's still used for free-floating windows. Or hijack to CollapseButton submit your button instead and always return false.)

If you plan to disable the dock menu/collapse button everywhere else, set ImGuiStyle::WindowMenuButtonPosition to ImGuiDir_Left when you submit your ImGui::DockSpace and ImGuiDir_None otherwise.

@ocornut ocornut added docking tabs tab bars, tabs labels May 23, 2022
@ocornut
Copy link
Owner

ocornut commented May 23, 2022

We have two mecanisms which could be eventually toward that:

  • It is possible to append to an existing tab bar using BeginTabBar()
  • BeginTabItem() has support for ImGuiTabItemFlags_Leading and ImGuiTabItemFlags_Trailing flag has well as there is a TabItemButton() function. I believe the later could be reworked into a way to request leading/trailing space.

@stormsc1
Copy link
Author

stormsc1 commented May 24, 2022

@PathogenDavid This is interesting, I haven't tough of hijacking CollapseButton - that might actually be the play here. It could properly be done with some #define overrides on include, I'll have to look into that.

How would you do it to avoid changing the ImGui source directly (I keep it as a git submodule)?

@PathogenDavid
Copy link
Contributor

How would you do it to avoid changing the ImGui source directly (I keep it as a git submodule)?

I'd recommend just doing a fork via GitHub and pointing your submodule to that instead. GitHub makes it pretty easy to keep it up to date with upstream:

Screenshot of GitHub UI for fetching upstream changes in a fork.

I can think of ways to avoid the fork using preprocessor shenanigans, but they'd be pretty brittle and I think they'd just be a needless source of confusion down the line.

@stormsc1
Copy link
Author

stormsc1 commented Jul 18, 2022

We have two mecanisms which could be eventually toward that:

* It is possible to append to an existing tab bar using `BeginTabBar()`

* `BeginTabItem()` has support for `ImGuiTabItemFlags_Leading` and `ImGuiTabItemFlags_Trailing` flag has well as there is a `TabItemButton()` function. I believe the later could be reworked into a way to request leading/trailing space.

Would you be able to provide an example on how this would work in the context of a dockspace tab bar?

This looks promising, but input is not working.

ImGuiID dockspace_id = ImGui::GetID("DockSpace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags, window_class);

ImGuiDockNode* node = (ImGuiDockNode*)GImGui->DockContext.Nodes.GetVoidPtr(dockspace_id);
if (node && node->TabBar)
{
   ImGui::TabItemEx(node->TabBar, "X", nullptr, ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, nullptr);
   ImGui::TabItemEx(node->TabBar, "Trailing", nullptr, ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, nullptr);
}

I don't really see how I would use BeginTabBar when I only have a ImGuiDockNode*, no string id. BeginTabBarEx crashes since I can't close it without setting an ID (tab_bar->ID = id;), it seems; and I'm not sure where to get ID from since it's locked behind the DockSpace's internal code?..

@ocornut
Copy link
Owner

ocornut commented Jan 24, 2023

Would you be able to provide an example on how this would work in the context of a dockspace tab bar?

FYI I think you figured this out as per your post #5515 but to answer this: DockNodeBeginAmendTabBar()/``DockNodeEndAmendTabBar()` can be used.

@ocornut ocornut closed this as completed Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docking tabs tab bars, tabs
Projects
None yet
Development

No branches or pull requests

3 participants