Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_widgets.cpp
This commit is contained in:
ocornut
2023-06-28 14:56:02 +02:00
7 changed files with 150 additions and 90 deletions

View File

@@ -405,6 +405,9 @@ CODE
- likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2023/06/28 (1.89.7) - overlapping items: obsoleted 'SetItemAllowOverlap()' (called after item) in favor of calling 'SetNextItemAllowOverlap()' (called before item). 'SetItemAllowOverlap()' didn't and couldn't work reliably since 1.89 (2022-11-15).
- 2023/06/28 (1.89.7) - overlapping items: renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap', 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'. Kept redirecting enums (will obsolete).
- 2023/06/28 (1.89.7) - overlapping items: IsItemHovered() now by default return false when querying an item using AllowOverlap mode which is being overlapped. Use ImGuiHoveredFlags_AllowWhenOverlappedByItem to revert to old behavior.
- 2023/06/20 (1.89.7) - moved io.HoverDelayShort/io.HoverDelayNormal to style.HoverDelayShort/style.HoverDelayNormal. As the fields were added in 1.89 and expected to be left unchanged by most users, or only tweaked once during app initialization, we are exceptionally accepting the breakage.
- 2023/05/30 (1.89.6) - backends: renamed "imgui_impl_sdlrenderer.cpp" to "imgui_impl_sdlrenderer2.cpp" and "imgui_impl_sdlrenderer.h" to "imgui_impl_sdlrenderer2.h". This is in prevision for the future release of SDL3.
- 2023/05/22 (1.89.6) - listbox: commented out obsolete/redirecting functions that were marked obsolete more than two years ago:
@@ -4074,12 +4077,13 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
// to use IsItemHovered() after EndChild() itself. Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was
// the test that has been running for a long while.
if (g.HoveredWindow != window && (status_flags & ImGuiItemStatusFlags_HoveredWindow) == 0)
if ((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0)
if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByWindow) == 0)
return false;
// Test if another item is active (e.g. being dragged)
const ImGuiID id = g.LastItemData.ID;
if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0)
if (g.ActiveId != 0 && g.ActiveId != g.LastItemData.ID && !g.ActiveIdAllowOverlap)
if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
if (g.ActiveId != window->MoveId && g.ActiveId != window->TabId)
return false;
@@ -4095,8 +4099,14 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
// Special handling for calling after Begin() which represent the title bar or tab.
// When the window is skipped/collapsed (SkipItems==true) that last item (always ->MoveId submitted by Begin)
// will never be overwritten so we need to detect the case.
if (g.LastItemData.ID == window->MoveId && window->WriteAccessed)
if (id == window->MoveId && window->WriteAccessed)
return false;
// Test if using AllowOverlap and overlapped
if ((g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap) && id != 0)
if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByItem) == 0)
if (g.HoveredIdPreviousFrame != g.LastItemData.ID)
return false;
}
// Handle hover delay
@@ -4123,22 +4133,22 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
}
// Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered().
bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
// (this does not rely on LastItemData it can be called from a ButtonBehavior() call not following an ItemAdd() call)
bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags)
{
ImGuiContext& g = *GImGui;
if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap)
return false;
ImGuiWindow* window = g.CurrentWindow;
if (g.HoveredWindow != window)
return false;
if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
return false;
if (!IsMouseHoveringRect(bb.Min, bb.Max))
return false;
if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap)
return false;
if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
return false;
// Done with rectangle culling so we can perform heavier checks now.
ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
{
g.HoveredIdDisabled = true;
@@ -4148,13 +4158,28 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level
// hover test in widgets code. We could also decide to split this function is two.
if (id != 0)
{
// Drag source doesn't report as hovered
if (g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover))
return false;
SetHoveredID(id);
// AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match.
// This allows using patterns where a later submitted widget overlaps a previous one. Generally perceived as a front-to-back hit-test.
if (item_flags & ImGuiItemflags_AllowOverlap)
{
g.HoveredIdAllowOverlap = true;
if (g.HoveredIdPreviousFrame != id)
return false;
}
}
// When disabled we'll return false but still set HoveredId
if (item_flags & ImGuiItemFlags_Disabled)
{
// Release active id if turning disabled
if (g.ActiveId == id)
if (g.ActiveId == id && id != 0)
ClearActiveID();
g.HoveredIdDisabled = true;
return false;
@@ -5548,17 +5573,28 @@ bool ImGui::IsItemEdited()
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Edited) != 0;
}
// Allow next item to be overlapped by subsequent items.
// This works by requiring HoveredId to match for two subsequent frames,
// so if a following items overwrite it our interactions will naturally be disabled.
void ImGui::SetNextItemAllowOverlap()
{
ImGuiContext& g = *GImGui;
g.NextItemData.ItemFlags |= ImGuiItemflags_AllowOverlap;
}
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
// FIXME: Although this is exposed, its interaction and ideal idiom with using ImGuiButtonFlags_AllowItemOverlap flag are extremely confusing, need rework.
// FIXME-LEGACY: Use SetNextItemAllowOverlap() *before* your item instead.
void ImGui::SetItemAllowOverlap()
{
ImGuiContext& g = *GImGui;
ImGuiID id = g.LastItemData.ID;
if (g.HoveredId == id)
g.HoveredIdAllowOverlap = true;
if (g.ActiveId == id)
if (g.ActiveId == id) // Before we made this obsolete, most calls to SetItemAllowOverlap() used to avoid this path by testing g.ActiveId != id.
g.ActiveIdAllowOverlap = true;
}
#endif
// FIXME: It might be undesirable that this will likely disable KeyOwner-aware shortcuts systems. Consider a more fine-tuned version for the two users of this function.
void ImGui::SetActiveIdUsingAllKeyboardKeys()
@@ -10082,7 +10118,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
g.LastItemData.ID = id;
g.LastItemData.Rect = bb;
g.LastItemData.NavRect = nav_bb_arg ? *nav_bb_arg : bb;
g.LastItemData.InFlags = g.CurrentItemFlags | extra_flags;
g.LastItemData.InFlags = g.CurrentItemFlags | g.NextItemData.ItemFlags | extra_flags;
g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None;
// Directional navigation processing
@@ -10114,6 +10150,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!");
}
g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
g.NextItemData.ItemFlags = ImGuiItemFlags_None;
#ifdef IMGUI_ENABLE_TEST_ENGINE
if (id != 0)
@@ -13008,7 +13045,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
// Rely on keeping other window->LastItemXXX fields intact.
source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect);
KeepAliveID(source_id);
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id);
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id, g.LastItemData.InFlags);
if (is_hovered && g.IO.MouseClicked[mouse_button])
{
SetActiveID(source_id, window);
@@ -16857,15 +16894,14 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
ImGuiID title_bar_id = host_window->GetID("#TITLEBAR");
if (g.HoveredId == 0 || g.HoveredId == title_bar_id || g.ActiveId == title_bar_id)
{
// AllowItem mode required for appending into dock node tab bar,
// otherwise dragging window will steal HoveredId and amended tabs cannot get them.
bool held;
KeepAliveID(title_bar_id);
ButtonBehavior(title_bar_rect, title_bar_id, NULL, &held, ImGuiButtonFlags_AllowItemOverlap);
ButtonBehavior(title_bar_rect, title_bar_id, NULL, &held, ImGuiButtonFlags_AllowOverlap);
if (g.HoveredId == title_bar_id)
{
// ImGuiButtonFlags_AllowItemOverlap + SetItemAllowOverlap() required for appending into dock node tab bar,
// otherwise dragging window will steal HoveredId and amended tabs cannot get them.
g.LastItemData.ID = title_bar_id;
SetItemAllowOverlap();
}
if (held)
{