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) + additional safety checks.

This commit is contained in:
omar 2018-07-08 20:04:49 +02:00
parent 64938178b7
commit bd6097ac6f
3 changed files with 35 additions and 27 deletions

View File

@ -47,6 +47,8 @@ Other Changes:
- Drag and Drop: Fixed an incorrect assert when dropping a source that is submitted after the target (bug introduced with 1.62 changes - Drag and Drop: Fixed an incorrect assert when dropping a source that is submitted after the target (bug introduced with 1.62 changes
related to the addition of IsItemDeactivated()). (#1875, #143) related to the addition of IsItemDeactivated()). (#1875, #143)
- Drag and Drop: Fixed ImGuiDragDropFlags_SourceNoDisableHover to affect hovering state prior to calling IsItemHovered() + fixed description. (#143) - 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)
- Misc: Added ImGuiMouseCursor_Hand cursor enum + corresponding software cursor. (#1913, 1914) [@aiekick, @ocornut] - 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. - Misc: Tweaked software mouse cursor offset to match the offset of the corresponding Windows 10 cursors.
- Fixed a include build issue for Cygwin in non-POSIX (Win32) mode. (#1917, #1319, #276) - Fixed a include build issue for Cygwin in non-POSIX (Win32) mode. (#1917, #1319, #276)

View File

@ -3790,6 +3790,7 @@ void ImGui::NewFrame()
g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr;
g.DragDropAcceptIdCurr = 0; g.DragDropAcceptIdCurr = 0;
g.DragDropAcceptIdCurrRectSurface = FLT_MAX; g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
g.DragDropWithinSourceOrTarget = false;
// Update keyboard input state // Update keyboard input state
memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration));
@ -5158,7 +5159,23 @@ void ImGui::SetTooltip(const char* fmt, ...)
void ImGui::BeginTooltip() void ImGui::BeginTooltip()
{ {
ImGuiContext& g = *GImGui;
if (g.DragDropWithinSourceOrTarget)
{
// The default tooltip position is a little offset to give space to see the context menu (it's also clamped within the current viewport/monitor)
// In the context of a dragging tooltip we try to reduce that offset and we enforce following the cursor.
// Whatever we do we want to call SetNextWindowPos() to enforce a tooltip position and disable clipping the tooltip without our display area, like regular tooltip do.
//ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding;
ImVec2 tooltip_pos = g.IO.MousePos + ImVec2(16 * g.Style.MouseCursorScale, 8 * g.Style.MouseCursorScale);
SetNextWindowPos(tooltip_pos);
SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f);
//PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :(
BeginTooltipEx(0, true);
}
else
{
BeginTooltipEx(0, false); BeginTooltipEx(0, false);
}
} }
void ImGui::EndTooltip() void ImGui::EndTooltip()
@ -13521,12 +13538,13 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
g.DragDropSourceFlags = flags; g.DragDropSourceFlags = flags;
g.DragDropMouseButton = mouse_button; g.DragDropMouseButton = mouse_button;
} }
g.DragDropWithinSourceOrTarget = true;
if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
{ {
// Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit) // Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit)
// We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents. // We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents.
BeginDragDropTooltip(); BeginTooltip();
if (g.DragDropActive && g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) if (g.DragDropActive && g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip))
{ {
ImGuiWindow* tooltip_window = g.CurrentWindow; ImGuiWindow* tooltip_window = g.CurrentWindow;
@ -13547,32 +13565,15 @@ void ImGui::EndDragDropSource()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(g.DragDropActive); IM_ASSERT(g.DragDropActive);
IM_ASSERT(g.DragDropWithinSourceOrTarget && "Not after a BeginDragDropSource()?");
if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
EndDragDropTooltip(); EndTooltip();
// Discard the drag if have not called SetDragDropPayload() // Discard the drag if have not called SetDragDropPayload()
if (g.DragDropPayload.DataFrameCount == -1) if (g.DragDropPayload.DataFrameCount == -1)
ClearDragDrop(); ClearDragDrop();
} g.DragDropWithinSourceOrTarget = false;
void ImGui::BeginDragDropTooltip()
{
// The default tooltip position is a little offset to give space to see the context menu (it's also clamped within the current viewport/monitor)
// In the context of a dragging tooltip we try to reduce that offset and we enforce following the cursor.
// Whatever we do we want to call SetNextWindowPos() to enforce a tooltip position and disable clipping the tooltip without our display area, like regular tooltip do.
ImGuiContext& g = *GImGui;
//ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding;
ImVec2 tooltip_pos = g.IO.MousePos + ImVec2(16 * g.Style.MouseCursorScale, 8 * g.Style.MouseCursorScale);
SetNextWindowPos(tooltip_pos);
SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f);
//PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :(
BeginTooltipEx(0, true);
}
void ImGui::EndDragDropTooltip()
{
EndTooltip();
} }
// Use 'cond' to choose to submit payload on drag start or every frame // Use 'cond' to choose to submit payload on drag start or every frame
@ -13632,8 +13633,10 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId)) if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId))
return false; return false;
IM_ASSERT(g.DragDropWithinSourceOrTarget == false);
g.DragDropTargetRect = bb; g.DragDropTargetRect = bb;
g.DragDropTargetId = id; g.DragDropTargetId = id;
g.DragDropWithinSourceOrTarget = true;
return true; return true;
} }
@ -13660,8 +13663,10 @@ bool ImGui::BeginDragDropTarget()
if (g.DragDropPayload.SourceId == id) if (g.DragDropPayload.SourceId == id)
return false; return false;
IM_ASSERT(g.DragDropWithinSourceOrTarget == false);
g.DragDropTargetRect = display_rect; g.DragDropTargetRect = display_rect;
g.DragDropTargetId = id; g.DragDropTargetId = id;
g.DragDropWithinSourceOrTarget = true;
return true; return true;
} }
@ -13717,8 +13722,10 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
// We don't really use/need this now, but added it for the sake of consistency and because we might need it later. // We don't really use/need this now, but added it for the sake of consistency and because we might need it later.
void ImGui::EndDragDropTarget() void ImGui::EndDragDropTarget()
{ {
ImGuiContext& g = *GImGui; (void)g; ImGuiContext& g = *GImGui;
IM_ASSERT(g.DragDropActive); IM_ASSERT(g.DragDropActive);
IM_ASSERT(g.DragDropWithinSourceOrTarget);
g.DragDropWithinSourceOrTarget = false;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -13944,7 +13951,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
(flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "", (flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "",
(flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : ""); (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : "");
ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window)); ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window));
ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active || window->WasActive, window->WriteAccessed);
ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL");
if (!window->NavRectRel[0].IsInverted()) if (!window->NavRectRel[0].IsInverted())

View File

@ -692,6 +692,7 @@ struct ImGuiContext
// Drag and Drop // Drag and Drop
bool DragDropActive; bool DragDropActive;
bool DragDropWithinSourceOrTarget;
ImGuiDragDropFlags DragDropSourceFlags; ImGuiDragDropFlags DragDropSourceFlags;
int DragDropMouseButton; int DragDropMouseButton;
ImGuiPayload DragDropPayload; ImGuiPayload DragDropPayload;
@ -810,7 +811,7 @@ struct ImGuiContext
OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging
MouseCursor = ImGuiMouseCursor_Arrow; MouseCursor = ImGuiMouseCursor_Arrow;
DragDropActive = false; DragDropActive = DragDropWithinSourceOrTarget = false;
DragDropSourceFlags = 0; DragDropSourceFlags = 0;
DragDropMouseButton = -1; DragDropMouseButton = -1;
DragDropTargetId = 0; DragDropTargetId = 0;
@ -1130,8 +1131,6 @@ namespace ImGui
IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
IMGUI_API void ClearDragDrop(); IMGUI_API void ClearDragDrop();
IMGUI_API bool IsDragDropPayloadBeingAccepted(); IMGUI_API bool IsDragDropPayloadBeingAccepted();
IMGUI_API void BeginDragDropTooltip();
IMGUI_API void EndDragDropTooltip();
// FIXME-WIP: New Columns API // FIXME-WIP: New Columns API
IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().