mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 11:39:15 +08:00
Docking: Added ImGuiDockNodeFlags_NoResize. (#2109)
This commit is contained in:
parent
b8d9c5c130
commit
962dcb466d
134
imgui.cpp
134
imgui.cpp
@ -11618,82 +11618,90 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node)
|
||||
bb.Max[axis ^ 1] += child_1->Size[axis ^ 1];
|
||||
//if (g.IO.KeyCtrl) GetOverlayDrawList(g.CurrentWindow->Viewport)->AddRect(bb.Min, bb.Max, IM_COL32(255,0,255,255));
|
||||
|
||||
//bb.Min[axis] += 1; // Display a little inward so highlight doesn't connect with nearby tabs on the neighbor node.
|
||||
//bb.Max[axis] -= 1;
|
||||
PushID(node->ID);
|
||||
|
||||
// Gather list of nodes that are touching the splitter line. Find resizing limits based on those nodes.
|
||||
ImVector<ImGuiDockNode*> touching_nodes[2];
|
||||
float min_size = g.Style.WindowMinSize[axis];
|
||||
float resize_limits[2];
|
||||
resize_limits[0] = node->ChildNodes[0]->Pos[axis] + min_size;
|
||||
resize_limits[1] = node->ChildNodes[1]->Pos[axis] + node->ChildNodes[1]->Size[axis] - min_size;
|
||||
|
||||
ImGuiID splitter_id = GetID("##Splitter");
|
||||
if (g.ActiveId == splitter_id)
|
||||
if (node->Flags & ImGuiDockNodeFlags_NoResize)
|
||||
{
|
||||
// Only process when splitter is active
|
||||
DockNodeTreeUpdateSplitterFindTouchingNode(child_0, axis, 1, &touching_nodes[0]);
|
||||
DockNodeTreeUpdateSplitterFindTouchingNode(child_1, axis, 0, &touching_nodes[1]);
|
||||
for (int touching_node_n = 0; touching_node_n < touching_nodes[0].Size; touching_node_n++)
|
||||
resize_limits[0] = ImMax(resize_limits[0], touching_nodes[0][touching_node_n]->Rect().Min[axis] + min_size);
|
||||
for (int touching_node_n = 0; touching_node_n < touching_nodes[1].Size; touching_node_n++)
|
||||
resize_limits[1] = ImMin(resize_limits[1], touching_nodes[1][touching_node_n]->Rect().Max[axis] - min_size);
|
||||
|
||||
/*
|
||||
// [DEBUG] Render limits
|
||||
ImDrawList* draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport());
|
||||
for (int n = 0; n < 2; n++)
|
||||
if (axis == ImGuiAxis_X)
|
||||
draw_list->AddLine(ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y), ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y + node->ChildNodes[n]->Size.y), IM_COL32(255, 0, 255, 255), 3.0f);
|
||||
else
|
||||
draw_list->AddLine(ImVec2(node->ChildNodes[n]->Pos.x, resize_limits[n]), ImVec2(node->ChildNodes[n]->Pos.x + node->ChildNodes[n]->Size.x, resize_limits[n]), IM_COL32(255, 0, 255, 255), 3.0f);
|
||||
*/
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator), g.Style.FrameRounding);
|
||||
}
|
||||
|
||||
// Use a short delay before highlighting the splitter (and changing the mouse cursor) in order for regular mouse movement to not highlight many splitters
|
||||
float cur_size_0 = child_0->Size[axis];
|
||||
float cur_size_1 = child_1->Size[axis];
|
||||
float min_size_0 = resize_limits[0] - child_0->Pos[axis];
|
||||
float min_size_1 = child_1->Pos[axis] + child_1->Size[axis] - resize_limits[1];
|
||||
if (SplitterBehavior(bb, GetID("##Splitter"), axis, &cur_size_0, &cur_size_1, min_size_0, min_size_1, RESIZE_WINDOWS_FROM_EDGES_HALF_THICKNESS, RESIZE_WINDOWS_FROM_EDGES_FEEDBACK_TIMER))
|
||||
else
|
||||
{
|
||||
if (touching_nodes[0].Size > 0 && touching_nodes[1].Size > 0)
|
||||
{
|
||||
child_0->Size[axis] = child_0->SizeRef[axis] = cur_size_0;
|
||||
child_1->Pos[axis] -= cur_size_1 - child_1->Size[axis];
|
||||
child_1->Size[axis] = child_1->SizeRef[axis] = cur_size_1;
|
||||
//bb.Min[axis] += 1; // Display a little inward so highlight doesn't connect with nearby tabs on the neighbor node.
|
||||
//bb.Max[axis] -= 1;
|
||||
PushID(node->ID);
|
||||
|
||||
// Lock the size of every node that is a sibling of the node we are touching
|
||||
// This might be less desirable if we can merge sibling of a same axis into the same parental level.
|
||||
// Gather list of nodes that are touching the splitter line. Find resizing limits based on those nodes.
|
||||
ImVector<ImGuiDockNode*> touching_nodes[2];
|
||||
float min_size = g.Style.WindowMinSize[axis];
|
||||
float resize_limits[2];
|
||||
resize_limits[0] = node->ChildNodes[0]->Pos[axis] + min_size;
|
||||
resize_limits[1] = node->ChildNodes[1]->Pos[axis] + node->ChildNodes[1]->Size[axis] - min_size;
|
||||
|
||||
ImGuiID splitter_id = GetID("##Splitter");
|
||||
if (g.ActiveId == splitter_id)
|
||||
{
|
||||
// Only process when splitter is active
|
||||
DockNodeTreeUpdateSplitterFindTouchingNode(child_0, axis, 1, &touching_nodes[0]);
|
||||
DockNodeTreeUpdateSplitterFindTouchingNode(child_1, axis, 0, &touching_nodes[1]);
|
||||
for (int touching_node_n = 0; touching_node_n < touching_nodes[0].Size; touching_node_n++)
|
||||
resize_limits[0] = ImMax(resize_limits[0], touching_nodes[0][touching_node_n]->Rect().Min[axis] + min_size);
|
||||
for (int touching_node_n = 0; touching_node_n < touching_nodes[1].Size; touching_node_n++)
|
||||
resize_limits[1] = ImMin(resize_limits[1], touching_nodes[1][touching_node_n]->Rect().Max[axis] - min_size);
|
||||
|
||||
/*
|
||||
// [DEBUG] Render limits
|
||||
ImDrawList* draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport());
|
||||
for (int n = 0; n < 2; n++)
|
||||
if (axis == ImGuiAxis_X)
|
||||
draw_list->AddLine(ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y), ImVec2(resize_limits[n], node->ChildNodes[n]->Pos.y + node->ChildNodes[n]->Size.y), IM_COL32(255, 0, 255, 255), 3.0f);
|
||||
else
|
||||
draw_list->AddLine(ImVec2(node->ChildNodes[n]->Pos.x, resize_limits[n]), ImVec2(node->ChildNodes[n]->Pos.x + node->ChildNodes[n]->Size.x, resize_limits[n]), IM_COL32(255, 0, 255, 255), 3.0f);
|
||||
*/
|
||||
}
|
||||
|
||||
// Use a short delay before highlighting the splitter (and changing the mouse cursor) in order for regular mouse movement to not highlight many splitters
|
||||
float cur_size_0 = child_0->Size[axis];
|
||||
float cur_size_1 = child_1->Size[axis];
|
||||
float min_size_0 = resize_limits[0] - child_0->Pos[axis];
|
||||
float min_size_1 = child_1->Pos[axis] + child_1->Size[axis] - resize_limits[1];
|
||||
if (SplitterBehavior(bb, GetID("##Splitter"), axis, &cur_size_0, &cur_size_1, min_size_0, min_size_1, RESIZE_WINDOWS_FROM_EDGES_HALF_THICKNESS, RESIZE_WINDOWS_FROM_EDGES_FEEDBACK_TIMER))
|
||||
{
|
||||
if (touching_nodes[0].Size > 0 && touching_nodes[1].Size > 0)
|
||||
{
|
||||
child_0->Size[axis] = child_0->SizeRef[axis] = cur_size_0;
|
||||
child_1->Pos[axis] -= cur_size_1 - child_1->Size[axis];
|
||||
child_1->Size[axis] = child_1->SizeRef[axis] = cur_size_1;
|
||||
|
||||
// Lock the size of every node that is a sibling of the node we are touching
|
||||
// This might be less desirable if we can merge sibling of a same axis into the same parental level.
|
||||
#if 1
|
||||
for (int side_n = 0; side_n < 2; side_n++)
|
||||
for (int touching_node_n = 0; touching_node_n < touching_nodes[side_n].Size; touching_node_n++)
|
||||
{
|
||||
ImGuiDockNode* touching_node = touching_nodes[side_n][touching_node_n];
|
||||
//ImDrawList* draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport());
|
||||
//draw_list->AddRect(touching_node->Pos, touching_node->Pos + touching_node->Size, IM_COL32(255, 128, 0, 255));
|
||||
while (touching_node->ParentNode != node)
|
||||
for (int side_n = 0; side_n < 2; side_n++)
|
||||
for (int touching_node_n = 0; touching_node_n < touching_nodes[side_n].Size; touching_node_n++)
|
||||
{
|
||||
if (touching_node->ParentNode->SplitAxis == axis)
|
||||
ImGuiDockNode* touching_node = touching_nodes[side_n][touching_node_n];
|
||||
//ImDrawList* draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport());
|
||||
//draw_list->AddRect(touching_node->Pos, touching_node->Pos + touching_node->Size, IM_COL32(255, 128, 0, 255));
|
||||
while (touching_node->ParentNode != node)
|
||||
{
|
||||
// Mark other node so its size will be preserved during the upcoming call to DockNodeTreeUpdatePosSize().
|
||||
ImGuiDockNode* node_to_preserve = touching_node->ParentNode->ChildNodes[side_n];
|
||||
node_to_preserve->WantLockSizeOnce = true;
|
||||
//draw_list->AddRect(touching_node->Pos, touching_node->Rect().Max, IM_COL32(255, 0, 0, 255));
|
||||
//draw_list->AddRectFilled(node_to_preserve->Pos, node_to_preserve->Rect().Max, IM_COL32(0, 255, 0, 100));
|
||||
if (touching_node->ParentNode->SplitAxis == axis)
|
||||
{
|
||||
// Mark other node so its size will be preserved during the upcoming call to DockNodeTreeUpdatePosSize().
|
||||
ImGuiDockNode* node_to_preserve = touching_node->ParentNode->ChildNodes[side_n];
|
||||
node_to_preserve->WantLockSizeOnce = true;
|
||||
//draw_list->AddRect(touching_node->Pos, touching_node->Rect().Max, IM_COL32(255, 0, 0, 255));
|
||||
//draw_list->AddRectFilled(node_to_preserve->Pos, node_to_preserve->Rect().Max, IM_COL32(0, 255, 0, 100));
|
||||
}
|
||||
touching_node = touching_node->ParentNode;
|
||||
}
|
||||
touching_node = touching_node->ParentNode;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DockNodeTreeUpdatePosSize(child_0, child_0->Pos, child_0->Size);
|
||||
DockNodeTreeUpdatePosSize(child_1, child_1->Pos, child_1->Size);
|
||||
MarkIniSettingsDirty();
|
||||
DockNodeTreeUpdatePosSize(child_0, child_0->Pos, child_0->Size);
|
||||
DockNodeTreeUpdatePosSize(child_1, child_1->Pos, child_1->Size);
|
||||
MarkIniSettingsDirty();
|
||||
}
|
||||
}
|
||||
PopID();
|
||||
}
|
||||
PopID();
|
||||
}
|
||||
|
||||
if (child_0->IsVisible)
|
||||
|
9
imgui.h
9
imgui.h
@ -800,16 +800,17 @@ enum ImGuiTabItemFlags_
|
||||
ImGuiTabItemFlags_NoPushId = 1 << 3 // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
|
||||
};
|
||||
|
||||
// Flags for ImGui::DockSpace()
|
||||
// Flags for ImGui::DockSpace(), inherited by child nodes.
|
||||
enum ImGuiDockNodeFlags_
|
||||
{
|
||||
ImGuiDockNodeFlags_None = 0,
|
||||
ImGuiDockNodeFlags_KeepAliveOnly = 1 << 0, // Don't display the dockspace node but keep it alive. Windows docked into this dockspace node won't be undocked.
|
||||
ImGuiDockNodeFlags_NoSplit = 1 << 1, // Disable splitting the node into smaller nodes. Useful e.g. when embedding dockspaces into a main root one (the root one may have splitting disabled to reduce confusion)
|
||||
//ImGuiDockNodeFlags_NoCentralNode = 1 << 2, // Disable Central Node (the node which can stay empty)
|
||||
//ImGuiDockNodeFlags_NoOuterBorder = 1 << 3, // Disable outer border on a DockSpace() node.
|
||||
ImGuiDockNodeFlags_NoDockingInCentralNode = 1 << 4, // Disable docking inside the Central Node, which will be always kept empty.
|
||||
ImGuiDockNodeFlags_PassthruDockspace = 1 << 5 // 1) DockSpace() will render a ImGuiCol_WindowBg background covering everything excepted the Central Node when empty. Meaning the host window should probably use SetNextWindowBgAlpha(0.0f) prior to Begin() when using this. 2) When Central Node is empty: let inputs pass-through + won't display a DockingEmptyBg background.
|
||||
ImGuiDockNodeFlags_NoDockingInCentralNode = 1 << 3, // Disable docking inside the Central Node, which will be always kept empty.
|
||||
//ImGuiDockNodeFlags_NoLayoutChanges = 1 << 4, // Disable adding/removing nodes interactively. Useful with programatically setup dockspaces.
|
||||
ImGuiDockNodeFlags_NoResize = 1 << 5, // Disable resizing child nodes using the splitter/separators. Useful with programatically setup dockspaces.
|
||||
ImGuiDockNodeFlags_PassthruDockspace = 1 << 6 // 1) DockSpace() will render a ImGuiCol_WindowBg background covering everything excepted the Central Node when empty. Meaning the host window should probably use SetNextWindowBgAlpha(0.0f) prior to Begin() when using this. 2) When Central Node is empty: let inputs pass-through + won't display a DockingEmptyBg background.
|
||||
};
|
||||
|
||||
// Flags for ImGui::IsWindowFocused()
|
||||
|
@ -3831,9 +3831,10 @@ void ShowExampleAppDockSpace(bool* p_open)
|
||||
// which we can't undo at the moment without finer window depth/z control.
|
||||
//ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen_persistant);
|
||||
|
||||
if (ImGui::MenuItem("Flag: NoSplit", "", (opt_flags & ImGuiDockNodeFlags_NoSplit) != 0)) opt_flags ^= ImGuiDockNodeFlags_NoSplit;
|
||||
if (ImGui::MenuItem("Flag: NoDockingInCentralNode", "", (opt_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) != 0)) opt_flags ^= ImGuiDockNodeFlags_NoDockingInCentralNode;
|
||||
if (ImGui::MenuItem("Flag: PassthruDockspace", "", (opt_flags & ImGuiDockNodeFlags_PassthruDockspace) != 0)) opt_flags ^= ImGuiDockNodeFlags_PassthruDockspace;
|
||||
if (ImGui::MenuItem("Flag: NoSplit", "", (opt_flags & ImGuiDockNodeFlags_NoSplit) != 0)) opt_flags ^= ImGuiDockNodeFlags_NoSplit;
|
||||
if (ImGui::MenuItem("Flag: NoDockingInCentralNode", "", (opt_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) != 0)) opt_flags ^= ImGuiDockNodeFlags_NoDockingInCentralNode;
|
||||
if (ImGui::MenuItem("Flag: NoResize", "", (opt_flags & ImGuiDockNodeFlags_NoResize) != 0)) opt_flags ^= ImGuiDockNodeFlags_NoResize;
|
||||
if (ImGui::MenuItem("Flag: PassthruDockspace", "", (opt_flags & ImGuiDockNodeFlags_PassthruDockspace) != 0)) opt_flags ^= ImGuiDockNodeFlags_PassthruDockspace;
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Close DockSpace", NULL, false, p_open != NULL))
|
||||
*p_open = false;
|
||||
|
Loading…
Reference in New Issue
Block a user