ocornut / imgui

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

Tabbar styling in dockspace #3521

Open dgregorius opened 3 years ago

dgregorius commented 3 years ago

Version/Branch of Dear ImGui:

Version: 1.79 Branch: Docking

Back-end/Renderer/Compiler/OS

Back-ends: imgui_impl_opengl3.cpp + imgui_impl_glfw3.cpp Operating System: Windows 10 (2004)

My Issue/Question:

I want to hide the "Hide Tab Bar" and "Close" button of dock window tabs. The only way I was able to achieve this was by overwriting the shared flags of each node using ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton. This flags are private and internal. So I am unsure if this is the correct way or if there is a better way to achieve this.

EDIT: Also, in this context I am wondering how to change the height of the tab?

Screenshots/Video

Tab

Standalone, minimal, complete and verifiable example: (see https://github.com/ocornut/imgui/issues/2261)

ImGui::DockBuilderDockWindow( RN_VIEWPORT_WINDOW, DockMainID );
ImGuiDockNode* MainNode = ImGui::DockBuilderGetNode( DockMainID );
MainNode->LocalFlags |= ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton;

If anybody tries this make sure you delete imgui.ini beforehand. Otherwise your changes might not have any effect!

vexe commented 3 years ago

I was just about to post an issue about this haha. Want to achieve the exact same effect, git rid of the close button and the hide tab button. I clicked the hide tab by accident and couldn't figure out exactly how to bring it back besides deleting the saved ini file. More exposure of this and control would be awesome!

frink commented 3 years ago

@ocornut maybe we need a few more ImGuiDockNodeFlags_ to handle this stuff.

I can work out a PR if you'd like...

ImGuiDockNodeFlags_NoCloseButton // hides the close button on the right
ImGuiDockNodeFlags_NoTabCloseButton // hides the close button on the tab
ImGuiDockNodeFlags_NoTabListPopup // hides the tab list on the left
dgregorius commented 3 years ago

Also no Tooltip if possible. I don't see any sense in showing a dumb tooltip which just repeats the text on the tab. Wrt the close button. It would be nice to have the close button on the tab and only render it while hovering the tab. Unfortunately I don't have a close button on the tab as you mention.

vexe commented 3 years ago

The other behavior I noticed, if you have two separate windows and you dock one into the other, and then move either the windows' title bar, it moves the windows as a whole unit, and if you click and drag the window from its tab, it moves it independently/splits it from being docked.

However, if you create a dockspace (like in the Dockspace example), and dock both windows under it, you can then click either the window title bar OR the tab and they will both split the window (as opposed to the previous behavior where the title bar moved everything as a whole, and the tab area did the split)

I think that behavior should be consistent and a flag to configure that would be awesome!

frink commented 3 years ago

I don't see any sense in showing a dumb tooltip which just repeats the text on the tab.

I agree completely. Ill update the list below...

It would be nice to have the close button on the tab and only render it while hovering the tab. Unfortunately I don't have a close button on the tab as you mention.

This is exposed in the TabBar API and I think it requires that you pass in bool* p_open.

However, if you create a dockspace (like in the Dockspace example), and dock both windows under it, you can then click either the window title bar OR the tab and they will both split the window (as opposed to the previous behavior where the title bar moved everything as a whole, and the tab area did the split)

I don't understand this one. What I've experienced is consistent. Maybe open a different issue with screenshots to explain what's going on in more detail...


I have updated list of new flags needed based on the comment above...


ImGuiDockNodeFlags_NoCloseButton // hides the close button on the right
ImGuiDockNodeFlags_NoTabCloseButton // hides the close button on the tab
ImGuiDockNodeFlags_NoTabListPopup // hides the tab list on the left
ImGuiDockNodeFlags_NoTabTooltip // hides the tab tooltip
dgregorius commented 3 years ago

I think you are right and I need to pass bool p_open.

Another thing I just noticed that would be nice to have is to be able to specify which tab has the initial focus when you stack several windows on a dock node.

frink commented 3 years ago

Another thing I just noticed that would be nice to have is to be able to specify which tab has the initial focus when you stack several windows on a dock node.

I think there is a way to do this in the docking system but I'm not sure what it is...

ocornut commented 3 years ago

I want to hide the "Hide Tab Bar" and "Close" button of dock window tabs. The only way I was able to achieve this was by overwriting the shared flags of each node using ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton. This flags are private and internal. So I am unsure if this is the correct way or if there is a better way to achieve this.

I am sure you understand the problem which is that a Dock Node is a shared host for multiple window and if multiple windows can overwrite those flags then by definition there's a conflict and we need to come with a solid scheme/policies to handle that. It would be advantageous to move toward a scheme where windows can always dictate their policies over the docknode, but the problem gets more annoying when we add settings persistence into the mix (e.g. hide tab bar as a user option) and programmatically created dockspaces. Now not only we have multiple windows potentially in conflict but windows and docknodes also are in conflicts in term of who owns the data, who is authoritative etc. There's probably an elegant way to solve all of this together but don't have the bandwidth for it at the moment.

For now the slightly more legal way to do same hack as above is to set the DockNodeFlagsOverrideSet / DockNodeFlagsOverrideClear members of ImGuiWindowClass + calling SetNextWindowClass() to trigger this override but it's not solving the possibility of a conflict between multiple windows with different requests, so it'll only fully work if there are also constraints applied on how windows are docked with each others.

Just to clarify, this thread is going over multiple unrelated topics/questions, each of which is much more subtle and complex than meet the eyes (it's not a simple case of "more exposure"), and the fate of most "bundle different complicated topics in one place" threads is that they tend stall forever. So all the casual one-more-thing questions are best asked in a different threads to facilitate moving forward.

aeris170 commented 3 years ago

ImGuiDockNodeFlags_NoCloseButton // hides the close button on the right ImGuiDockNodeFlags_NoTabCloseButton // hides the close button on the tab ImGuiDockNodeFlags_NoTabListPopup // hides the tab list on the left ImGuiDockNodeFlags_NoTabTooltip // hides the tab tooltip

In case someone gets an error while trying to use these flags, #include <imgui_internal.h> (possibly unwise but 🤷)

roniabusayeed commented 1 month ago

In the recent version of Dear ImGui, the tab headers for the docked windows (not the tabs—if any—inside the docked windows themselves) are styled differently. Previously, its style could be changed by modifying the tab style.

I want to round the tab headers (which are rectangular by default—Visual Studio look) for the docked windows. How do I achieve that?

ocornut commented 1 month ago

The rounding has changed you can still round them by changing style.TabRounding, the value at the time of NewFrame() is used by docking system.

The one thing that has changed, based on a request by Dirk, if we added an overline over the selected tab. One issue is that it's difficult to decide how to display that line with rounded tabs, so we're using a bit of a heuristic/magic multiplier here. You can always set ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline to zero to disable this line.