Skip to content

Commit 4a555d3

Browse files
committed
IsWindowHovered(): split ImGuiHoveredFlags_FlattenChild into separate ChildWindows and RootWindow flags. Allowing more combination and a better symetry with IsWindowFocused() flags. (#1382)
1 parent 185c1ea commit 4a555d3

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

imgui.cpp

+29-6
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@
221221
- 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency.
222222
- 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg.
223223
- 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding.
224-
- 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_FlattenChilds);
224+
- 2017/11/02 (1.53) - marked IsRootWindowOrAnyChildHovered() as obsolete is favor of using IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows);
225225
- 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency.
226226
- 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it.
227227
- 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details.
@@ -2032,7 +2032,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
20322032
// Test for bounding box overlap, as updated as ItemAdd()
20332033
if (!window->DC.LastItemRectHoveredRect)
20342034
return false;
2035-
IM_ASSERT((flags & ImGuiHoveredFlags_FlattenChilds) == 0); // Flags not supported by this function
2035+
IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function
20362036

20372037
// Test if we are hovering the right window (our window could be behind another window)
20382038
// [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself.
@@ -5440,20 +5440,43 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
54405440
return "Unknown";
54415441
}
54425442

5443+
bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent)
5444+
{
5445+
if (window->RootWindow == potential_parent)
5446+
return true;
5447+
while (window != NULL)
5448+
{
5449+
if (window == potential_parent)
5450+
return true;
5451+
window = window->ParentWindow;
5452+
}
5453+
return false;
5454+
}
5455+
54435456
bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
54445457
{
54455458
IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function
54465459
ImGuiContext& g = *GImGui;
5447-
if (flags & ImGuiHoveredFlags_FlattenChilds)
5460+
switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows))
54485461
{
5462+
case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows:
54495463
if (g.HoveredRootWindow != g.CurrentWindow->RootWindow)
54505464
return false;
5451-
}
5452-
else
5453-
{
5465+
break;
5466+
case ImGuiHoveredFlags_RootWindow:
5467+
if (g.HoveredWindow != g.CurrentWindow->RootWindow)
5468+
return false;
5469+
break;
5470+
case ImGuiHoveredFlags_ChildWindows:
5471+
if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow))
5472+
return false;
5473+
break;
5474+
default:
54545475
if (g.HoveredWindow != g.CurrentWindow)
54555476
return false;
5477+
break;
54565478
}
5479+
54575480
if (!IsWindowContentHoverable(g.HoveredRootWindow, flags))
54585481
return false;
54595482
if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))

imgui.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,8 @@ enum ImGuiHoveredFlags_
607607
//ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 1, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.
608608
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 2, // Return true even if an active item is blocking access to this item/window
609609
ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 3, // Return true even if the position is overlapped by another window
610-
ImGuiHoveredFlags_FlattenChilds = 1 << 4, // Treat all child windows as the same window (for IsWindowHovered())
610+
ImGuiHoveredFlags_ChildWindows = 1 << 4, // IsWindowHovered() only: Return true if any children of the window is hovered
611+
ImGuiHoveredFlags_RootWindow = 1 << 5, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy)
611612
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped
612613
};
613614

@@ -937,8 +938,8 @@ struct ImGuiIO
937938
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
938939
namespace ImGui
939940
{
940-
static inline void SetNextWindowContentWidth(float width) { ImGui::SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize())
941-
static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_FlattenChilds); } // OBSOLETE 1.53+ use flags directly
941+
static inline void SetNextWindowContentWidth(float width) { SetNextWindowContentSize(ImVec2(width, 0.0f)); } // OBSOLETE 1.53+ (nb: original version preserved last Y value set by SetNextWindowContentSize())
942+
static inline bool IsRootWindowOrAnyChildHovered(ImGuiHoveredFlags flags = 0) { return IsItemHovered(flags | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows); } // OBSOLETE 1.53+ use flags directly
942943
bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE 1.52+. use SetNextWindowSize() instead if you want to set a window size.
943944
static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETE 1.52+
944945
static inline void SetNextWindowPosCenter(ImGuiCond cond = 0) { SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), cond, ImVec2(0.5f, 0.5f)); } // OBSOLETE 1.52+

imgui_demo.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -1788,11 +1788,15 @@ void ImGui::ShowTestWindow(bool* p_open)
17881788
"IsWindowHovered() = %d\n"
17891789
"IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n"
17901790
"IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n"
1791-
"IsWindowHovered(_FlattenChilds) = %d\n",
1791+
"IsWindowHovered(_ChildWindows) = %d\n"
1792+
"IsWindowHovered(_ChildWindows|_RootWindow) = %d\n"
1793+
"IsWindowHovered(_RootWindow) = %d\n",
17921794
ImGui::IsWindowHovered(),
17931795
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
17941796
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
1795-
ImGui::IsWindowHovered(ImGuiHoveredFlags_FlattenChilds));
1797+
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows),
1798+
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow),
1799+
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow));
17961800

17971801
// Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code)
17981802
ImGui::Button("ITEM");
@@ -1808,6 +1812,10 @@ void ImGui::ShowTestWindow(bool* p_open)
18081812
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
18091813
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly));
18101814

1815+
ImGui::BeginChild("child", ImVec2(0,50), true);
1816+
ImGui::Text("This is a child window for testing IsWindowHovered() flags.");
1817+
ImGui::EndChild();
1818+
18111819
ImGui::TreePop();
18121820
}
18131821

imgui_internal.h

+1
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ namespace ImGui
804804
IMGUI_API void FocusWindow(ImGuiWindow* window);
805805
IMGUI_API void BringWindowToFront(ImGuiWindow* window);
806806
IMGUI_API void BringWindowToBack(ImGuiWindow* window);
807+
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
807808

808809
IMGUI_API void Initialize();
809810

0 commit comments

Comments
 (0)