From 085ed7bfbeb427d79fa3d6e36639b902b0b62213 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 5 Oct 2023 14:13:27 +0200 Subject: [PATCH] Drag and Drop: Rework drop target highlight. (#4281, #3272) Amend 4ddb6b46, 4b94738c7 --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 17 +++++++++++++---- imgui_demo.cpp | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 673ec1c2e741..b3a64111ea1f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -87,6 +87,8 @@ Other changes: - Mostly legacy behavior when used inside old Columns(), as we favored that idiom back then, only different is left position follows indentation level, to match calling a Separator() inside or outside Columns(). +- Drag and Drop: Rework drop target highlight: reduce rectangle to its visible portion, and + then expand slightly. A full rectangle is always visible and it may protrude slightly. (#4281, #3272) - Drag and Drop: Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload() with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually. - Tables: Fixed an edge-case when no columns are visible + table scrollbar is visible + user diff --git a/imgui.cpp b/imgui.cpp index 77bc5f17cb88..23363af360e7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12656,7 +12656,6 @@ bool ImGui::IsDragDropPayloadBeingAccepted() const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; ImGuiPayload& payload = g.DragDropPayload; IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ? @@ -12680,7 +12679,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop payload.Preview = was_accepted_previously; flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that live for 1 frame) if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) - window->DrawList->AddRect(r.Min - ImVec2(3.5f,3.5f), r.Max + ImVec2(3.5f, 3.5f), GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); + RenderDragDropTargetRect(r); g.DragDropAcceptFrameCount = g.FrameCount; payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting OS window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() @@ -12691,10 +12690,20 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop return &payload; } -// FIXME-DRAGDROP: Settle on a proper default visuals for drop target. +// FIXME-STYLE FIXME-DRAGDROP: Settle on a proper default visuals for drop target. void ImGui::RenderDragDropTargetRect(const ImRect& bb) { - GetWindowDrawList()->AddRect(bb.Min - ImVec2(3.5f, 3.5f), bb.Max + ImVec2(3.5f, 3.5f), GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImRect bb_display = bb; + bb_display.ClipWith(window->ClipRect); // Clip THEN expand so we have a way to visualize that target is not entirely visible. + bb_display.Expand(3.5f); + bool push_clip_rect = !window->ClipRect.Contains(bb_display); + if (push_clip_rect) + window->DrawList->PushClipRectFullScreen(); + window->DrawList->AddRect(bb_display.Min, bb_display.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); + if (push_clip_rect) + window->DrawList->PopClipRect(); } const ImGuiPayload* ImGui::GetDragDropPayload() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e66b10e3a322..8cc4410823d7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2437,6 +2437,7 @@ static void ShowDemoWindowWidgets() ImGuiDragDropFlags drop_target_flags = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoPreviewTooltip; if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, drop_target_flags)) { + IM_UNUSED(payload); ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed); ImGui::BeginTooltip(); ImGui::Text("Cannot drop here!");