mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-21 19:37:01 +00:00
Drag and Drop: Fixed drop target highlight on items temporarily pushing a widened clip rect. (#7049, #4281, #3272)
This commit is contained in:
parent
65a10410e3
commit
bce4db00bc
@ -44,6 +44,9 @@ Breaking changes:
|
|||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
|
|
||||||
|
- Drag and Drop: Fixed drop target highlight on items temporarily pushing a widened clip rect
|
||||||
|
(namely Selectables and Treenodes using SpanAllColumn flag) so the highlight properly covers
|
||||||
|
all columns. (#7049, #4281, #3272)
|
||||||
- Misc: Fixed text functions fast-path for handling "%s" and "%.*s" to handle null pointers gracefully,
|
- Misc: Fixed text functions fast-path for handling "%s" and "%.*s" to handle null pointers gracefully,
|
||||||
like most printf implementations. (#7016, #3466, #6846) [@codefrog2002]
|
like most printf implementations. (#7016, #3466, #6846) [@codefrog2002]
|
||||||
- Misc: Renamed some defines in imstb_textedit.h to avoid conflicts when using unity/jumbo builds
|
- Misc: Renamed some defines in imstb_textedit.h to avoid conflicts when using unity/jumbo builds
|
||||||
|
10
imgui.cpp
10
imgui.cpp
@ -12778,13 +12778,14 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
|
|||||||
|
|
||||||
IM_ASSERT(g.DragDropWithinTarget == false);
|
IM_ASSERT(g.DragDropWithinTarget == false);
|
||||||
g.DragDropTargetRect = bb;
|
g.DragDropTargetRect = bb;
|
||||||
|
g.DragDropTargetClipRect = window->ClipRect; // May want to be overriden by user depending on use case?
|
||||||
g.DragDropTargetId = id;
|
g.DragDropTargetId = id;
|
||||||
g.DragDropWithinTarget = true;
|
g.DragDropWithinTarget = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't use BeginDragDropTargetCustom() and duplicate its code because:
|
// We don't use BeginDragDropTargetCustom() and duplicate its code because:
|
||||||
// 1) we use LastItemRectHoveredRect which handles items that push a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them.
|
// 1) we use LastItemData's ImGuiItemStatusFlags_HoveredRect which handles items that push a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them.
|
||||||
// 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can.
|
// 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can.
|
||||||
// Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case)
|
// Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case)
|
||||||
bool ImGui::BeginDragDropTarget()
|
bool ImGui::BeginDragDropTarget()
|
||||||
@ -12812,6 +12813,7 @@ bool ImGui::BeginDragDropTarget()
|
|||||||
|
|
||||||
IM_ASSERT(g.DragDropWithinTarget == false);
|
IM_ASSERT(g.DragDropWithinTarget == false);
|
||||||
g.DragDropTargetRect = display_rect;
|
g.DragDropTargetRect = display_rect;
|
||||||
|
g.DragDropTargetClipRect = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect : window->ClipRect;
|
||||||
g.DragDropTargetId = id;
|
g.DragDropTargetId = id;
|
||||||
g.DragDropWithinTarget = true;
|
g.DragDropWithinTarget = true;
|
||||||
return true;
|
return true;
|
||||||
@ -12849,7 +12851,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
|||||||
payload.Preview = was_accepted_previously;
|
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)
|
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)
|
if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview)
|
||||||
RenderDragDropTargetRect(r);
|
RenderDragDropTargetRect(r, g.DragDropTargetClipRect);
|
||||||
|
|
||||||
g.DragDropAcceptFrameCount = g.FrameCount;
|
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()
|
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()
|
||||||
@ -12861,12 +12863,12 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME-STYLE 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)
|
void ImGui::RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImRect bb_display = bb;
|
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.ClipWith(item_clip_rect); // Clip THEN expand so we have a way to visualize that target is not entirely visible.
|
||||||
bb_display.Expand(3.5f);
|
bb_display.Expand(3.5f);
|
||||||
bool push_clip_rect = !window->ClipRect.Contains(bb_display);
|
bool push_clip_rect = !window->ClipRect.Contains(bb_display);
|
||||||
if (push_clip_rect)
|
if (push_clip_rect)
|
||||||
|
@ -837,6 +837,7 @@ enum ImGuiItemStatusFlags_
|
|||||||
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
|
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
|
||||||
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
|
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
|
||||||
ImGuiItemStatusFlags_Visible = 1 << 9, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()).
|
ImGuiItemStatusFlags_Visible = 1 << 9, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()).
|
||||||
|
ImGuiItemStatusFlags_HasClipRect = 1 << 10, // g.LastItemData.ClipRect is valid
|
||||||
|
|
||||||
// Additional status + semantic for ImGuiTestEngine
|
// Additional status + semantic for ImGuiTestEngine
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
@ -1221,7 +1222,9 @@ struct ImGuiLastItemData
|
|||||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||||
ImRect Rect; // Full rectangle
|
ImRect Rect; // Full rectangle
|
||||||
ImRect NavRect; // Navigation scoring rectangle (not displayed)
|
ImRect NavRect; // Navigation scoring rectangle (not displayed)
|
||||||
ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set)
|
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags is set.
|
||||||
|
ImRect DisplayRect; // Display rectangle (ONLY VALID IF ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||||
|
ImRect ClipRect; // Clip rectangle at the time of submitting item (ONLY VALID IF ImGuiItemStatusFlags_HasClipRect is set)
|
||||||
|
|
||||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@ -2038,6 +2041,7 @@ struct ImGuiContext
|
|||||||
int DragDropMouseButton;
|
int DragDropMouseButton;
|
||||||
ImGuiPayload DragDropPayload;
|
ImGuiPayload DragDropPayload;
|
||||||
ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping)
|
ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping)
|
||||||
|
ImRect DragDropTargetClipRect; // Store ClipRect at the time of item's drawing
|
||||||
ImGuiID DragDropTargetId;
|
ImGuiID DragDropTargetId;
|
||||||
ImGuiDragDropFlags DragDropAcceptFlags;
|
ImGuiDragDropFlags DragDropAcceptFlags;
|
||||||
float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface)
|
float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface)
|
||||||
@ -3168,7 +3172,7 @@ 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 RenderDragDropTargetRect(const ImRect& bb);
|
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect);
|
||||||
|
|
||||||
// Typing-Select API
|
// Typing-Select API
|
||||||
IMGUI_API ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None);
|
IMGUI_API ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None);
|
||||||
|
@ -6232,7 +6232,11 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (span_all_columns)
|
if (span_all_columns)
|
||||||
|
{
|
||||||
TablePushBackgroundChannel();
|
TablePushBackgroundChannel();
|
||||||
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasClipRect;
|
||||||
|
g.LastItemData.ClipRect = window->ClipRect;
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
|
ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
|
||||||
if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap))
|
if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap))
|
||||||
@ -6562,10 +6566,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
|
|
||||||
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
||||||
// which would be advantageous since most selectable are not selected.
|
// which would be advantageous since most selectable are not selected.
|
||||||
if (span_all_columns && window->DC.CurrentColumns)
|
if (span_all_columns)
|
||||||
PushColumnsBackground();
|
{
|
||||||
else if (span_all_columns && g.CurrentTable)
|
if (g.CurrentTable)
|
||||||
TablePushBackgroundChannel();
|
TablePushBackgroundChannel();
|
||||||
|
else if (window->DC.CurrentColumns)
|
||||||
|
PushColumnsBackground();
|
||||||
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasClipRect;
|
||||||
|
g.LastItemData.ClipRect = window->ClipRect;
|
||||||
|
}
|
||||||
|
|
||||||
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
|
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
|
||||||
ImGuiButtonFlags button_flags = 0;
|
ImGuiButtonFlags button_flags = 0;
|
||||||
@ -6616,10 +6625,13 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
if (g.NavId == id)
|
if (g.NavId == id)
|
||||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
||||||
|
|
||||||
if (span_all_columns && window->DC.CurrentColumns)
|
if (span_all_columns)
|
||||||
PopColumnsBackground();
|
{
|
||||||
else if (span_all_columns && g.CurrentTable)
|
if (g.CurrentTable)
|
||||||
TablePopBackgroundChannel();
|
TablePopBackgroundChannel();
|
||||||
|
else if (window->DC.CurrentColumns)
|
||||||
|
PopColumnsBackground();
|
||||||
|
}
|
||||||
|
|
||||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user