Drag and Drop: Payload stays available and under the mouse if the source stops being submitted, however the tooltip is replaced by "..." + moved FrameScopeActive = false at the bottom of EndFrame() for safety. (#1725)
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 29a736c..d9936f3 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -53,6 +53,7 @@
- Drag and Drop: Fixed ImGuiDragDropFlags_SourceNoDisableHover to affect hovering state prior to calling IsItemHovered() + fixed description. (#143)
- Drag and Drop: Calling BeginTooltip() between a BeginDragSource()/EndDragSource() or BeginDropTarget()/EndDropTarget() uses adjusted tooltip
settings matching the one created when calling BeginDragSource() without the ImGuiDragDropFlags_SourceNoPreviewTooltip flag. (#143)
+ - Drag and Drop: Payload stays available and under the mouse if the source stops being submitted, however the tooltip is replaced by "...". (#1725)
- IsItemHovered(): Added ImGuiHoveredFlags_AllowWhenDisabled flag to query hovered status on disabled items. (#1940, #211)
- Misc: Added ImGuiMouseCursor_Hand cursor enum + corresponding software cursor. (#1913, 1914) [@aiekick, @ocornut]
- Misc: Tweaked software mouse cursor offset to match the offset of the corresponding Windows 10 cursors.
diff --git a/imgui.cpp b/imgui.cpp
index 594d5fe..5b99a98 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -3903,6 +3903,10 @@
// Mark rendering data as invalid to prevent user who may have a handle on it to use it
g.DrawData.Clear();
+ // Drag and drop keep the source ID alive so even if the source disappear our state is consistent
+ if (g.DragDropActive && g.DragDropPayload.SourceId == g.ActiveId)
+ KeepAliveID(g.DragDropPayload.SourceId);
+
// Clear reference to active widget if the widget isn't alive anymore
if (!g.HoveredIdPreviousFrame)
g.HoveredIdTimer = 0.0f;
@@ -3924,13 +3928,7 @@
if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId)
g.ScalarAsInputTextId = 0;
- // Elapse drag & drop payload
- if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount)
- {
- ClearDragDrop();
- g.DragDropPayloadBufHeap.clear();
- memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal));
- }
+ // Drag and drop
g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr;
g.DragDropAcceptIdCurr = 0;
g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
@@ -4426,7 +4424,6 @@
if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times.
return;
IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()");
- g.FrameScopeActive = false;
// Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f)
@@ -4445,6 +4442,22 @@
if (g.NavWindowingTarget)
NavUpdateWindowingList();
+ // Drag and Drop: Elapse payload at the end of the frame if mouse has been released
+ if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount && !IsMouseDown(g.DragDropMouseButton))
+ {
+ ClearDragDrop();
+ g.DragDropPayloadBufHeap.clear();
+ memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal));
+ }
+
+ // Drag and Drop: Fallback for source tooltip. This is not ideal but better than nothing.
+ if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount)
+ {
+ g.DragDropWithinSourceOrTarget = true;
+ SetTooltip("...");
+ g.DragDropWithinSourceOrTarget = false;
+ }
+
// Initiate moving window
if (g.ActiveId == 0 && g.HoveredId == 0)
{
@@ -4505,6 +4518,7 @@
memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
+ g.FrameScopeActive = false;
g.FrameCountEnded = g.FrameCount;
}
@@ -5277,7 +5291,11 @@
void ImGui::SetTooltipV(const char* fmt, va_list args)
{
- BeginTooltipEx(0, true);
+ ImGuiContext& g = *GImGui;
+ if (g.DragDropWithinSourceOrTarget)
+ BeginTooltip();
+ else
+ BeginTooltipEx(0, true);
TextV(fmt, args);
EndTooltip();
}
@@ -13689,6 +13707,7 @@
g.DragDropSourceFlags = flags;
g.DragDropMouseButton = mouse_button;
}
+ g.DragDropSourceFrameCount = g.FrameCount;
g.DragDropWithinSourceOrTarget = true;
if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
diff --git a/imgui_internal.h b/imgui_internal.h
index 1adfde1..cdabcd3 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -710,6 +710,7 @@
bool DragDropActive;
bool DragDropWithinSourceOrTarget;
ImGuiDragDropFlags DragDropSourceFlags;
+ int DragDropSourceFrameCount;
int DragDropMouseButton;
ImGuiPayload DragDropPayload;
ImRect DragDropTargetRect;
@@ -830,6 +831,7 @@
DragDropActive = DragDropWithinSourceOrTarget = false;
DragDropSourceFlags = 0;
+ DragDropSourceFrameCount = -1;
DragDropMouseButton = -1;
DragDropTargetId = 0;
DragDropAcceptFlags = 0;