| 21315 | } |
| 21316 | |
| 21317 | void ImGui::BeginDockableDragDropTarget(ImGuiWindow* window) |
| 21318 | { |
| 21319 | ImGuiContext& g = *GImGui; |
| 21320 | |
| 21321 | //IM_ASSERT(window->RootWindowDockTree == window); // May also be a DockSpace |
| 21322 | IM_ASSERT((window->Flags & ImGuiWindowFlags_NoDocking) == 0); |
| 21323 | if (!g.DragDropActive) |
| 21324 | return; |
| 21325 | //GetForegroundDrawList(window)->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); |
| 21326 | if (!BeginDragDropTargetCustom(window->Rect(), window->ID)) |
| 21327 | return; |
| 21328 | |
| 21329 | // Peek into the payload before calling AcceptDragDropPayload() so we can handle overlapping dock nodes with filtering |
| 21330 | // (this is a little unusual pattern, normally most code would call AcceptDragDropPayload directly) |
| 21331 | const ImGuiPayload* payload = &g.DragDropPayload; |
| 21332 | if (!payload->IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW) || !DockNodeIsDropAllowed(window, *(ImGuiWindow**)payload->Data)) |
| 21333 | { |
| 21334 | EndDragDropTarget(); |
| 21335 | return; |
| 21336 | } |
| 21337 | |
| 21338 | ImGuiWindow* payload_window = *(ImGuiWindow**)payload->Data; |
| 21339 | if (AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect)) |
| 21340 | { |
| 21341 | // Select target node |
| 21342 | // (Important: we cannot use g.HoveredDockNode here! Because each of our target node have filters based on payload, each candidate drop target will do its own evaluation) |
| 21343 | bool dock_into_floating_window = false; |
| 21344 | ImGuiDockNode* node = NULL; |
| 21345 | if (window->DockNodeAsHost) |
| 21346 | { |
| 21347 | // Cannot assume that node will != NULL even though we passed the rectangle test: it depends on padding/spacing handled by DockNodeTreeFindVisibleNodeByPos(). |
| 21348 | node = DockNodeTreeFindVisibleNodeByPos(window->DockNodeAsHost, g.IO.MousePos); |
| 21349 | |
| 21350 | // There is an edge case when docking into a dockspace which only has _inactive_ nodes (because none of the windows are active) |
| 21351 | // In this case we need to fallback into any leaf mode, possibly the central node. |
| 21352 | // FIXME-20181220: We should not have to test for IsLeafNode() here but we have another bug to fix first. |
| 21353 | if (node && node->IsDockSpace() && node->IsRootNode()) |
| 21354 | node = (node->CentralNode && node->IsLeafNode()) ? node->CentralNode : DockNodeTreeFindFallbackLeafNode(node); |
| 21355 | } |
| 21356 | else |
| 21357 | { |
| 21358 | if (window->DockNode) |
| 21359 | node = window->DockNode; |
| 21360 | else |
| 21361 | dock_into_floating_window = true; // Dock into a regular window |
| 21362 | } |
| 21363 | |
| 21364 | const ImRect explicit_target_rect = (node && node->TabBar && !node->IsHiddenTabBar() && !node->IsNoTabBar()) ? node->TabBar->BarRect : ImRect(window->Pos, window->Pos + ImVec2(window->Size.x, GetFrameHeight())); |
| 21365 | const bool is_explicit_target = g.IO.ConfigDockingWithShift || IsMouseHoveringRect(explicit_target_rect.Min, explicit_target_rect.Max); |
| 21366 | |
| 21367 | // Preview docking request and find out split direction/ratio |
| 21368 | //const bool do_preview = true; // Ignore testing for payload->IsPreview() which removes one frame of delay, but breaks overlapping drop targets within the same window. |
| 21369 | const bool do_preview = payload->IsPreview() || payload->IsDelivery(); |
| 21370 | if (do_preview && (node != NULL || dock_into_floating_window)) |
| 21371 | { |
| 21372 | // If we have a non-leaf node it means we are hovering the border of a parent node, in which case only outer markers will appear. |
| 21373 | ImGuiDockPreviewData split_inner; |
| 21374 | ImGuiDockPreviewData split_outer; |
nothing calls this directly
no test coverage detected