mirror of
https://github.com/ocornut/imgui.git
synced 2026-10-22 22:44:21 +00:00
Seeking something like "IsAnyOtherItemHovered()" to fix interaction with multiple overlapping elements #3909
Labels
No labels
accidentally closed
android
backends
bug
building
clipper
coloredit
color spaces
cplusplus
data types
demo
disabled
doc
docking
dpi
drag drop
drawing/drawlist
dropped
dx12
enhancement
focus
font/text
gallery
help wanted
idle/power saving
ime
in progress
inputs
inputtext
internals
label/id and id stack
language bindings
layout
linux/bsd
menus
multi-contexts
multi-threading
multi-viewports
nav
news/info
opengl
optimization
osx/ios
overlap
plot/graph
popups
question
scrolling
selection
settings
sliders/drags
style
tables/columns
tabs
test wanted
tools
tooltips
tree
tricks & tips
useful widgets
vulkan
web
window pos/depth
window sizing
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ocornut/imgui#3909
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Version/Branch of Dear ImGui:
Version: 1.77
Branch: master
Back-end/Renderer/Compiler/OS
Back-ends: imgui.net
Operating System: win10
My Issue/Question:
I know that overlapping interactive elements are tricky to implement with a single pass immediate UI.
And I learned, that it is possible to partly resolve the inversed draw/interaction sort order by channel splitting.
I normally try to work around or ignore these problems, but for my timeline editing this get kind of annoying.
I am wondering, if there is the possibility to prevent multiple click events by something like this...
For some reason however,
somethingElseWasHoveredbecomes true even before the invisible button is being drawn. Obviously I don't understand what's going on (I guess some information from the previous frame must be used for this).IsAnyItemHovered()works? (search the documentation in imgui.h)Screenshots/Video
https://user-images.githubusercontent.com/1732545/111050991-336d8e00-8450-11eb-8616-c325f622ccdc.mp4
Yes it return true if any item has been hovered in the previous frame.
It's a 1 line function you can check the code.
The
|| g.Hovered != 0part of the test always bothered me since that part is testing for element hovered this frame but only covers what has been submitted so far.It's hard to understand what you are getting at with your question, I reckon you should be looking at
SetItemAllowOverlap()which is a mechanism to allow overlapping hit-testing.This is going to be confusing as relatively to half-implemented/designed API, but I'm still going to write it down:
When hovering in the intersection of both button:
(A) Without SetItemAllowOverlap() after Button 1
(B) With SetItemAllowOverlap() after Button 1
(C) With (internal) ImGuiButtonFlags_AllowItemOverlap flag on Button 1 + SetItemAllowOverlap() after Button 1
Added records of 1.88 behavior on 2023/06:
(D) With (internal) ImGuiButtonFlags_AllowItemOverlap flag on Button 1 + WIITHOUT SetItemAllowOverlap() call.
Notice issues:
ImGuiButtonFlags_AllowItemOverlapis currently explicit, I've been considering switching to a hover model where it is implicit default, but it's going to be a lots of work. With this model we would only need to callSetItemAllowOverlap().Added records of 1.88 behavior on 2023/06:
SplitterBehavior()andTableUpdateBorders(). Effectively this behavior was analogous to not doing anything, EXCEPT in the case of SplitterBehavior() is allows the caller to follow the call withSetItemAllowOverlap().(This is a a bit of a mess. There are they two aspects: the
ButtonBehavior()logic has theImGuiButtonFlags_AllowItemOverlapflag + there's a `SetItemAllowOverlap() call which can be called afterwards.... hence I know this post is probably only opening the veil to a new world of confusion especially if you are stuck without access to internals..)Thank you for this excellent explanation. I guess I have to think about this.
Some thoughts, though:
SetItemAllowOverlap()...IsItemHovered(wasNotOverlappedInPreviousFrame:true);so I could only react on clicks if this returns true.😄 Especially with node graphs and timeline elements, activating the overlapped element is probably worse than a slight delay.But I'm sure, that you already thought about this problem. If there would be an easy solution, you would have done it already...
Correct.
This was never advertised much because of the subtleties between case B and C and the potential need for both.
However, plot twist discovered via #6512, case B simply doesn't work since 1.89 because of the introduction of the input ownership system.
Update of preceding report following changes in 1.89+. When hovering in the intersection of both button, case A and C are identical, but case B changes:
(B after 1.89) With SetItemAllowOverlap() after Button 1 but not using ImGuiButtonFlags_AllowItemOverlap in Button 1:
This is because Button 1 takes ownership for
ImGuiKey_MouseLefton mouse down, preventing Mouse 2 to access it.The API
SetItemAllowOverlap()cannot be modified to solve this.I am going to work on a solution for this.
I have pushed a bunch of changes related to AllowOverlap mode.
See this comment for details: https://github.com/ocornut/imgui/issues/6512#issuecomment-1611369198
TL;DR;
SetItemAllowOverlap()couldn't work since 1.89 and was obsoleted.SetNextItemAllowOverlap(). It doesn't need an internal button flags and should work across most/all widgets.IsItemHovered()aware of this (previously it wasn't) with opt-out flagImGuiHoveredFlags_AllowWhenOverlappedByItem.xxxAllowItemOverlapflags toxxxAllowOverlap.