ocornut / imgui

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

Docking layout without Docking actions #2999

Open manuliner opened 4 years ago

manuliner commented 4 years ago

Version/Branch of Dear ImGui:

Version: 1.74 Branch: docking

My Issue/Question:

Hello,

i want to use only the layout feature of the docking branch do give my application different layouts and doens't allow the use to undock and dock the windows, resulting a change of the layout.

Actually i just want to always hide the Titlebar of my windows and keep the Vertical and Horizontal Handles for resizing.

Currently i use DockBuilder to build my Layouts on demand by deleting the old Layout and then building the desired new layout.

to hide the titlebar i tried the "ImGuiWindowFlags_NoTitleBar" flag, and it is working as long the window is floating. But for docked windows it is not working, which makes sense, as they need an handle to undock.

is there another way to achieve this as copying Begin() and delete the code parts, which are needed for rendering the titlebar?

thank you very much.

How i Build a layout Standalone, minimal, complete and verifiable example:

ImGui::DockBuilderRemoveNode(dockSpaceId_m); // Clear out existing layout
ImGui::DockBuilderAddNode(dockSpaceId_m); // Add empty node
ImGui::DockBuilderSetNodeSize(dockSpaceId_m, {getWidgetArea()->getWidth(), getWidgetArea()->getHeight()}); // Add empty node

ImGuiID right;
ImGuiID left;

ImGui::DockBuilderSplitNode(dockSpaceId_m, ImGuiDir_Right, 0.7f, &right, &left);
ImGui::DockBuilderDockWindow("ImageView", right);
ImGui::DockBuilderDockWindow("ImportView", left);

ImGui::DockBuilderFinish(dockSpaceId_m);
ocornut commented 4 years ago

Create your nodes with ImGuiDockNodeFlags_NoDocking | ImGuiDockNodeFlags_NoSplit and ImGuiDockNodeFlags_HiddenTabBar.

manuliner commented 4 years ago

thank you for fast response.

i did totally oversee those flags. Sadly it won't make any change.

ImGuiDockNodeFlags dockNodeFlags = ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoDocking | ImGuiDockNodeFlags_NoSplit | ImGuiDockNodeFlags_HiddenTabBar;

if( firstCall){
ImGui::DockBuilderRemoveNode(dockSpaceId_m); // Clear out existing layout
ImGui::DockBuilderAddNode(dockSpaceId_m,dockNodeFlags ); // Add empty node
ImGui::DockBuilderSetNodeSize(dockSpaceId_m, {getWidgetArea()->getWidth(), getWidgetArea()->getHeight()}); // Add empty node

ImGuiID right;
ImGuiID left;

ImGui::DockBuilderSplitNode(dockSpaceId_m, ImGuiDir_Right, 0.7f, &right, &left);
ImGui::DockBuilderDockWindow("ImageView", right);
ImGui::DockBuilderDockWindow("ImportView", left);

ImGui::DockBuilderFinish(dockSpaceId_m,dockNodeFlags ); }

ImGui::DockSpace(dockSpaceId_m, ImVec2(0.0f, 0.0f), dockNodeFlags); //called every frame
ocornut commented 4 years ago

That code won't compile (DockBuilderFinish doesn't take two parameters) so I don't think you tried to investigate this enough, also it doesn't need to be called everyframe.

Check in Metrics>Docks to see how flags are inherited and in imgui.ini file how they are saved.

manuliner commented 4 years ago

sorry my mistake, copy paste error

manuliner commented 4 years ago

below is an more accurate code of my layouting mechanism.

after further investigation in Metrics>Docks it seems that only the Window with the id leftUp receives the dockNodeFlags

all other "local flags" of the different nodes are unchecked

is there a way to set the dockNodeFlags when/before calling Begin() ?


ImGuiDockNodeFlags dockNodeFlags = ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoDocking | ImGuiDockNodeFlags_NoSplit | ImGuiDockNodeFlags_NoTabBar;

if( firstCall){
    ImGui::DockBuilderRemoveNode(dockSpaceId_m); // Clear out existing layout
    ImGui::DockBuilderAddNode(dockSpaceId_m,dockNodeFlags ); // Add empty node
    ImGui::DockBuilderSetNodeSize(dockSpaceId_m, getWidgetArea()->getWidth(),getWidgetArea()->getHeight()}); // Add empty node

    ImGuiID dock_main_id = ImGui::GetID("main);
    ImGuiID rightUp = ImGui::GetID("rightUp");
    ImGuiID rightDown = ImGui::GetID("rightDown");
    ImGuiID leftUp = ImGui::GetID("leftUp");
    ImGuiID right;  
    ImGuiID leftUp;
    ImGuiID leftDown;

    ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Right, 0.4f, &right, &left);

    ImGui::DockBuilderSplitNode(right, ImGuiDir_Down, 0.30f, &rightDown, &rightUp);
    ImGui::DockBuilderSplitNode(left, ImGuiDir_Down, 0.30f, &leftDown, &leftUp);
    ImGui::DockBuilderDockWindow("rightUp", rightUp);
    ImGui::DockBuilderDockWindow("leftUp", leftUp);
    ImGui::DockBuilderDockWindow("rightDown", rightDown);

    ImGui::DockBuilderFinish(dock_main_id);
 }

ImGui::DockSpace(dock_main_id, ImVec2(0.0f, 0.0f), dockNodeFlags); //called every frame
ocornut commented 4 years ago

after further investigation in Metrics>Docks it seems that only the Window with the id leftUp receives the dockNodeFlags

How dock node flags are inherited is still a tricky topic I haven't found the right design for. I cannot test your code since it isn't a standalone-pastable repro, however if I skim at the code (and grep ImGuiDockNodeFlags_LocalFlagsMask_, ImGuiDockNodeFlags_LocalFlagsTransferMask_) I can see the ImGuiDockNodeFlags_NoSplit and ImGuiDockNodeFlags_NoDocking flags are meant to be inherited by children when splitting. You can see it in the DockNodeTreeSplit() function.

is there a way to set the dockNodeFlags when/before calling Begin() ?

I pushed a way I was experimenting with for another feature, you can now use the DockNodeFlagsOverrideSet and DockNodeFlagsOverrideClear flags of ImGuiWindowClass along with SetNextWindowClass(). Please note that this generally only makes sense if you have a single window in the dock node.

In your situation I think you could either rely on inheritance + persistance .ini savin, or apply manually to each node + persistance .ini saving. But going the route of having window apply to each host node is going to be bizarre.

Please also note this is all highly WIP api, things are likely to evolve in the future but if you start using that stuff you are to be wary of that.

manuliner commented 4 years ago

I was able to achieve it with calling ImGui::GetCurrentWindow()->DockNode->LocalFlags |= ImGuiDockNodeFlags_NoTabBar; after ImGui::Begin(...)

ocornut commented 4 years ago

It's still an open topic IHMO as to how we inherit and expose dock nodes flags.