Skip to content

Commit

Permalink
Drag and Drop: Payload stays available and under the mouse if the sou…
Browse files Browse the repository at this point in the history
…rce stops being submitted, however the tooltip is replaced by "..." + moved FrameScopeActive = false at the bottom of EndFrame() for safety. (#1725)
  • Loading branch information
ocornut committed Jul 31, 2018
1 parent f88bf9c commit e13e598
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Other Changes:
- 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.
Expand Down
37 changes: 28 additions & 9 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3903,6 +3903,10 @@ void ImGui::NewFrame()
// 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;
Expand All @@ -3924,13 +3928,7 @@ void ImGui::NewFrame()
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;
Expand Down Expand Up @@ -4426,7 +4424,6 @@ void ImGui::EndFrame()
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)
Expand All @@ -4445,6 +4442,22 @@ void ImGui::EndFrame()
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)
{
Expand Down Expand Up @@ -4505,6 +4518,7 @@ void ImGui::EndFrame()
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;
}

Expand Down Expand Up @@ -5277,7 +5291,11 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_

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();
}
Expand Down Expand Up @@ -13689,6 +13707,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
g.DragDropSourceFlags = flags;
g.DragDropMouseButton = mouse_button;
}
g.DragDropSourceFrameCount = g.FrameCount;
g.DragDropWithinSourceOrTarget = true;

if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
Expand Down
2 changes: 2 additions & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ struct ImGuiContext
bool DragDropActive;
bool DragDropWithinSourceOrTarget;
ImGuiDragDropFlags DragDropSourceFlags;
int DragDropSourceFrameCount;
int DragDropMouseButton;
ImGuiPayload DragDropPayload;
ImRect DragDropTargetRect;
Expand Down Expand Up @@ -830,6 +831,7 @@ struct ImGuiContext

DragDropActive = DragDropWithinSourceOrTarget = false;
DragDropSourceFlags = 0;
DragDropSourceFrameCount = -1;
DragDropMouseButton = -1;
DragDropTargetId = 0;
DragDropAcceptFlags = 0;
Expand Down

0 comments on commit e13e598

Please sign in to comment.