Drag and Drop: Added ImGuiDragDropFlags_SourceExtern to facilitate interfacing with WM_DROPFILES (#143)

This commit is contained in:
omar 2017-12-15 11:16:10 +01:00
parent 6effcf21d6
commit 0c6e260f73
2 changed files with 51 additions and 33 deletions

View File

@ -11220,11 +11220,19 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
bool source_drag_active = false;
ImGuiID source_id = 0;
ImGuiID source_parent_id = 0;
if (!(flags & ImGuiDragDropFlags_SourceExtern))
{
source_id = window->DC.LastItemId;
if (source_id != 0 && g.ActiveId != source_id) // Early out for most common case
return false;
if (g.IO.MouseDown[mouse_button] == false) if (g.IO.MouseDown[mouse_button] == false)
return false; return false;
ImGuiID id = window->DC.LastItemId; if (source_id == 0)
if (id == 0)
{ {
// If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to:
// A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride.
@ -11241,29 +11249,38 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button)
bool is_hovered = window->DC.LastItemRectHoveredRect; bool is_hovered = window->DC.LastItemRectHoveredRect;
if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window))
return false; return false;
id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect); source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect);
if (is_hovered) if (is_hovered)
SetHoveredID(id); SetHoveredID(source_id);
if (is_hovered && g.IO.MouseClicked[mouse_button]) if (is_hovered && g.IO.MouseClicked[mouse_button])
{ {
SetActiveID(id, window); SetActiveID(source_id, window);
FocusWindow(window); FocusWindow(window);
} }
if (g.ActiveId == id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. if (g.ActiveId == source_id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker.
g.ActiveIdAllowOverlap = is_hovered; g.ActiveIdAllowOverlap = is_hovered;
} }
if (g.ActiveId != id) if (g.ActiveId != source_id)
return false; return false;
source_parent_id = window->IDStack.back();
source_drag_active = IsMouseDragging(mouse_button);
}
else
{
window = NULL;
source_id = ImHash("#SourceExtern", 0);
source_drag_active = true;
}
if (IsMouseDragging(mouse_button)) if (source_drag_active)
{ {
if (!g.DragDropActive) if (!g.DragDropActive)
{ {
IM_ASSERT(id != 0); IM_ASSERT(source_id != 0);
ClearDragDrop(); ClearDragDrop();
ImGuiPayload& payload = g.DragDropPayload; ImGuiPayload& payload = g.DragDropPayload;
payload.SourceId = id; payload.SourceId = source_id;
payload.SourceParentId = window->IDStack.back(); payload.SourceParentId = source_parent_id;
g.DragDropActive = true; g.DragDropActive = true;
g.DragDropSourceFlags = flags; g.DragDropSourceFlags = flags;
g.DragDropMouseButton = mouse_button; g.DragDropMouseButton = mouse_button;
@ -11279,7 +11296,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button)
BeginTooltipEx(ImGuiWindowFlags_NoInputs); BeginTooltipEx(ImGuiWindowFlags_NoInputs);
} }
if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover)) if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern))
window->DC.LastItemRectHoveredRect = false; window->DC.LastItemRectHoveredRect = false;
return true; return true;
@ -11434,7 +11451,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
} }
g.DragDropAcceptFrameCount = g.FrameCount; g.DragDropAcceptFrameCount = g.FrameCount;
payload.Delivery = was_accepted_previously && IsMouseReleased(g.DragDropMouseButton); 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()
if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery))
return NULL; return NULL;

View File

@ -643,6 +643,7 @@ enum ImGuiDragDropFlags_
ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item.
ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item.
ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit.
ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously.
// AcceptDragDropPayload() flags // AcceptDragDropPayload() flags
ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered.
ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target.