diff --git a/imgui.cpp b/imgui.cpp index 61550831c..e7c233166 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1606,7 +1606,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window = NULL) { ImGuiState& g = *GImGui; g.ActiveId = id; - g.ActiveIdAllowHoveringOthers = false; + g.ActiveIdAllowOverlap = false; g.ActiveIdIsJustActivated = true; g.ActiveIdWindow = window; } @@ -1615,7 +1615,7 @@ void ImGui::SetHoveredID(ImGuiID id) { ImGuiState& g = *GImGui; g.HoveredId = id; - g.HoveredIdAllowHoveringOthers = false; + g.HoveredIdAllowOverlap = false; } void ImGui::KeepAliveID(ImGuiID id) @@ -1676,7 +1676,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) window->DC.LastItemHoveredRect = true; window->DC.LastItemHoveredAndUsable = false; if (g.HoveredRootWindow == window->RootWindow) - if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowHoveringOthers || (g.ActiveId == window->MoveID)) + if (g.ActiveId == 0 || (id && g.ActiveId == *id) || g.ActiveIdAllowOverlap || (g.ActiveId == window->MoveID)) if (IsWindowContentHoverable(window)) window->DC.LastItemHoveredAndUsable = true; } @@ -1705,11 +1705,11 @@ bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when bool ImGui::IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs) { ImGuiState& g = *GImGui; - if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowHoveringOthers) + if (g.HoveredId == 0 || g.HoveredId == id || g.HoveredIdAllowOverlap) { ImGuiWindow* window = GetCurrentWindowRead(); if (g.HoveredWindow == window || (flatten_childs && g.HoveredRootWindow == window->RootWindow)) - if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowHoveringOthers) && ImGui::IsMouseHoveringRect(bb.Min, bb.Max)) + if ((g.ActiveId == 0 || g.ActiveId == id || g.ActiveIdAllowOverlap) && ImGui::IsMouseHoveringRect(bb.Min, bb.Max)) if (IsWindowContentHoverable(g.HoveredRootWindow)) return true; } @@ -1937,7 +1937,7 @@ void ImGui::NewFrame() // Clear reference to active widget if the widget isn't alive anymore g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredId = 0; - g.HoveredIdAllowHoveringOthers = false; + g.HoveredIdAllowOverlap = false; if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) SetActiveID(0); g.ActiveIdPreviousFrame = g.ActiveId; @@ -3027,6 +3027,16 @@ bool ImGui::IsItemVisible() return r.Overlaps(window->DC.LastItemRect); } +// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. +void ImGui::SetItemAllowOverlap() +{ + ImGuiState& g = *GImGui; + if (g.HoveredId == g.CurrentWindow->DC.LastItemID) + g.HoveredIdAllowOverlap = true; + if (g.ActiveId == g.CurrentWindow->DC.LastItemID) + g.ActiveIdAllowOverlap = true; +} + ImVec2 ImGui::GetItemRectMin() { ImGuiWindow* window = GetCurrentWindowRead(); @@ -7279,7 +7289,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. // Down the line we should have a cleaner library-wide concept of Selected vs Active. - g.ActiveIdAllowHoveringOthers = !io.MouseDown[0]; + g.ActiveIdAllowOverlap = !io.MouseDown[0]; // Edit in progress const float mouse_x = (g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; diff --git a/imgui_internal.h b/imgui_internal.h index c58d903eb..7a56e85fe 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -360,13 +360,13 @@ struct ImGuiState ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) ImGuiID HoveredId; // Hovered widget - bool HoveredIdAllowHoveringOthers; + bool HoveredIdAllowOverlap; ImGuiID HoveredIdPreviousFrame; ImGuiID ActiveId; // Active widget ImGuiID ActiveIdPreviousFrame; bool ActiveIdIsAlive; bool ActiveIdIsJustActivated; // Set at the time of activation for one frame - bool ActiveIdAllowHoveringOthers; // Set only by active widget + bool ActiveIdAllowOverlap; // Set only by active widget ImGuiWindow* ActiveIdWindow; ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window. Pointer is only valid if ActiveID is the "#MOVE" identifier of a window. ImVector Settings; // .ini Settings @@ -445,13 +445,13 @@ struct ImGuiState HoveredWindow = NULL; HoveredRootWindow = NULL; HoveredId = 0; - HoveredIdAllowHoveringOthers = false; + HoveredIdAllowOverlap = false; HoveredIdPreviousFrame = 0; ActiveId = 0; ActiveIdPreviousFrame = 0; ActiveIdIsAlive = false; ActiveIdIsJustActivated = false; - ActiveIdAllowHoveringOthers = false; + ActiveIdAllowOverlap = false; ActiveIdWindow = NULL; MovedWindow = NULL; SettingsDirtyTimer = 0.0f; @@ -683,6 +683,7 @@ namespace ImGui IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); + IMGUI_API void SetItemAllowOverlap(); // Allow last item to be overlapped by a subsequent item // NB: All position are in absolute pixels coordinates (not window coordinates) IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);