Docking: Added Type enum in ImGuiDockRequest. Renamed fields. DockSpace() skips node update if already submitted (when transitioning from implicit -> explicit DockSpace).

This commit is contained in:
omar 2018-09-10 22:08:33 +02:00
parent d5692bff00
commit 416918429d

View File

@ -9527,23 +9527,32 @@ void ImGui::EndDragDropTarget()
static float IMGUI_DOCK_SPLITTER_SIZE = 4.0f; static float IMGUI_DOCK_SPLITTER_SIZE = 4.0f;
enum ImGuiDockRequestType
{
ImGuiDockRequestType_None = 0,
ImGuiDockRequestType_Dock,
ImGuiDockRequestType_Undock
};
struct ImGuiDockRequest struct ImGuiDockRequest
{ {
ImGuiWindow* WindowDockTarget; // Destination/Target window to dock into (may be a loose window or a DockNode) ImGuiDockRequestType Type;
ImGuiDockNode* WindowDockTargetNode; ImGuiWindow* DockTarget; // Destination/Target window to dock into (may be a loose window or a DockNode)
ImGuiWindow* WindowDockPayload; // Source/Payload window to dock (may be a loose window or a DockNode) ImGuiDockNode* DockTargetNode;
ImGuiDir WindowDockSplitDir; ImGuiWindow* DockPayload; // Source/Payload window to dock (may be a loose window or a DockNode)
float WindowDockSplitRatio; ImGuiDir DockSplitDir;
bool WindowDockSplitOuter; float DockSplitRatio;
ImGuiWindow* WindowUndock; bool DockSplitOuter;
ImGuiWindow* UndockTarget;
ImGuiDockRequest() ImGuiDockRequest()
{ {
WindowDockTarget = WindowDockPayload = WindowUndock = NULL; Type = ImGuiDockRequestType_None;
WindowDockTargetNode = NULL; DockTarget = DockPayload = UndockTarget = NULL;
WindowDockSplitDir = ImGuiDir_None; DockTargetNode = NULL;
WindowDockSplitRatio = 0.5f; DockSplitDir = ImGuiDir_None;
WindowDockSplitOuter = false; DockSplitRatio = 0.5f;
DockSplitOuter = false;
} }
}; };
@ -9669,7 +9678,10 @@ void ImGui::DockContextShutdown(ImGuiContext* imgui_context)
ImGuiDockContext* ctx = g.DockContext; ImGuiDockContext* ctx = g.DockContext;
for (int n = 0; n < ctx->Nodes.Data.Size; n++) for (int n = 0; n < ctx->Nodes.Data.Size; n++)
if (ImGuiDockNode* node = (ImGuiDockNode*)ctx->Nodes.Data[n].val_p) if (ImGuiDockNode* node = (ImGuiDockNode*)ctx->Nodes.Data[n].val_p)
{
node->ChildNodes[0] = node->ChildNodes[1] = NULL;
IM_DELETE(node); IM_DELETE(node);
}
IM_DELETE(g.DockContext); IM_DELETE(g.DockContext);
g.DockContext = NULL; g.DockContext = NULL;
} }
@ -9712,8 +9724,8 @@ void ImGui::DockContextNewFrameUpdateUndocking(ImGuiDockContext* ctx)
// Process Undocking requests (called from NewFrame before UpdateMovingWindow) // Process Undocking requests (called from NewFrame before UpdateMovingWindow)
for (int n = 0; n < ctx->Requests.Size; n++) for (int n = 0; n < ctx->Requests.Size; n++)
if (ctx->Requests[n].WindowUndock) if (ctx->Requests[n].Type == ImGuiDockRequestType_Undock)
DockContextProcessUndock(ctx, ctx->Requests[n].WindowUndock); DockContextProcessUndock(ctx, ctx->Requests[n].UndockTarget);
} }
void ImGui::DockContextNewFrameUpdateDocking(ImGuiDockContext* ctx) void ImGui::DockContextNewFrameUpdateDocking(ImGuiDockContext* ctx)
@ -9724,7 +9736,7 @@ void ImGui::DockContextNewFrameUpdateDocking(ImGuiDockContext* ctx)
// Process Docking requests // Process Docking requests
for (int n = 0; n < ctx->Requests.Size; n++) for (int n = 0; n < ctx->Requests.Size; n++)
if (ctx->Requests[n].WindowDockTarget) if (ctx->Requests[n].Type == ImGuiDockRequestType_Dock)
DockContextProcessDock(ctx, &ctx->Requests[n]); DockContextProcessDock(ctx, &ctx->Requests[n]);
ctx->Requests.resize(0); ctx->Requests.resize(0);
@ -9893,27 +9905,29 @@ void ImGui::DockContextBuildAddWindowsToNodes(ImGuiDockContext* ctx)
void ImGui::DockContextQueueDock(ImGuiDockContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer) void ImGui::DockContextQueueDock(ImGuiDockContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer)
{ {
ImGuiDockRequest req; ImGuiDockRequest req;
req.WindowDockTarget = target; req.Type = ImGuiDockRequestType_Dock;
req.WindowDockTargetNode = target_node; req.DockTarget = target;
req.WindowDockPayload = payload; req.DockTargetNode = target_node;
req.WindowDockSplitDir = split_dir; req.DockPayload = payload;
req.WindowDockSplitRatio = split_ratio; req.DockSplitDir = split_dir;
req.WindowDockSplitOuter = split_outer; req.DockSplitRatio = split_ratio;
req.DockSplitOuter = split_outer;
ctx->Requests.push_back(req); ctx->Requests.push_back(req);
} }
void ImGui::DockContextQueueUndock(ImGuiDockContext* ctx, ImGuiWindow* window) void ImGui::DockContextQueueUndock(ImGuiDockContext* ctx, ImGuiWindow* window)
{ {
ImGuiDockRequest req; ImGuiDockRequest req;
req.WindowUndock = window; req.Type = ImGuiDockRequestType_Undock;
req.UndockTarget = window;
ctx->Requests.push_back(req); ctx->Requests.push_back(req);
} }
void ImGui::DockContextProcessDock(ImGuiDockContext* ctx, ImGuiDockRequest* req) void ImGui::DockContextProcessDock(ImGuiDockContext* ctx, ImGuiDockRequest* req)
{ {
ImGuiWindow* target_window = req->WindowDockTarget; ImGuiWindow* target_window = req->DockTarget;
ImGuiWindow* payload_window = req->WindowDockPayload; ImGuiWindow* payload_window = req->DockPayload;
ImGuiDockNode* target_node = req->WindowDockTargetNode; ImGuiDockNode* target_node = req->DockTargetNode;
// Decide which Tab will be selected at the end of the operation (do it before the target/payload swap) // Decide which Tab will be selected at the end of the operation (do it before the target/payload swap)
ImGuiID next_selected_id = 0; ImGuiID next_selected_id = 0;
@ -9941,7 +9955,7 @@ void ImGui::DockContextProcessDock(ImGuiDockContext* ctx, ImGuiDockRequest* req)
} }
} }
ImGuiDir split_dir = req->WindowDockSplitDir; ImGuiDir split_dir = req->DockSplitDir;
if (split_dir == ImGuiDir_None) if (split_dir == ImGuiDir_None)
{ {
target_node->LastFocusedNodeID = target_node ? target_node->ID : 0; target_node->LastFocusedNodeID = target_node ? target_node->ID : 0;
@ -9951,7 +9965,7 @@ void ImGui::DockContextProcessDock(ImGuiDockContext* ctx, ImGuiDockRequest* req)
// Split into one, one side will be our payload node unless we are dropping a loose window // Split into one, one side will be our payload node unless we are dropping a loose window
const ImGuiAxis split_axis = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; const ImGuiAxis split_axis = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y;
const int split_inheritor_child_idx = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? 1 : 0; const int split_inheritor_child_idx = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? 1 : 0;
const float split_ratio = req->WindowDockSplitRatio; const float split_ratio = req->DockSplitRatio;
if (payload_node) if (payload_node)
DockNodeTreeSplit(ctx, target_node, split_axis, split_inheritor_child_idx, split_ratio, payload_node); DockNodeTreeSplit(ctx, target_node, split_axis, split_inheritor_child_idx, split_ratio, payload_node);
else else
@ -10056,6 +10070,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id)
ImGuiDockNode::~ImGuiDockNode() ImGuiDockNode::~ImGuiDockNode()
{ {
IM_ASSERT(ChildNodes[0] == NULL && ChildNodes[1] == NULL);
IM_DELETE(TabBar); IM_DELETE(TabBar);
TabBar = NULL; TabBar = NULL;
} }
@ -11268,6 +11283,9 @@ void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg, ImGuiDockFlags
node->UserTypeIdFilter = user_type_filter; node->UserTypeIdFilter = user_type_filter;
node->IsExplicitRoot = true; node->IsExplicitRoot = true;
if (node->LastFrameActive == g.FrameCount)
return;
const ImVec2 content_avail = GetContentRegionAvail(); const ImVec2 content_avail = GetContentRegionAvail();
ImVec2 size = ImFloor(size_arg); ImVec2 size = ImFloor(size_arg);
if (size.x <= 0.0f) if (size.x <= 0.0f)