-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hit test customization #1512
Hit test customization #1512
Conversation
Hello Michal,
I can’t take PR for new features without understanding precisely what you are aiming at and why/how you would like to use them. It seems a like backward to ask “if such construction are needed in imgui” without expliciting your own use case.
If your intent is really to display a circle button, as your example shows it using the FrameRounding isn’t sufficient and you would likely create your own function RoundButton() in which case it becomes strange to use a callback for the hit test. Maybe added a mechanism at the lower level of eg ButtonBehavior() to make those custom constructions more easy would make more sense.
As for the window hit test I have no idea what you’d use that for, interested in hearing about it.
Thanks!
Omar
|
Sorry for lack of motivation section in PR. I had trouble to remember where I had used this feature, more than a year has passed since I needed it. Since I rebased code to latest ImGui I thought I can share it here. I used hit test callbacks to implement editor overlay in our engine. That's it overlay. ImGui window is displayed over entire screen. At the top there is a toolbar and editable shapes are over shapes on a 2D scene. Since this is an overlay I needed to pass input events to underlying editor. To do that I used window callback. Focus for shape editing and gizmos are captured using ImGui::InvisibleButton(), aka. bounding rectangle of a shape. Then hit test callback is used to actually test if a part of shape was hit. I'm utilizing draw lists with arbitrary transformations for rendering (I also added simple ImMatrix consisting of six floats) and InvisibleButton() to handle input. |
82b992c
to
9aa6433
Compare
You can use the
Yes that would be the most useful. |
My setup looks like that. ImGui window cover whole screen so I always receive an input. To interact with 'Exit' button (not part of the scene) is ImGui must pass input events to normal editor, window hit test is used to do that. Individual shapes use hit test inside their bounding rects to determine their active area. Yellow rects are handles (custom buttons) to, in this case, manipulate vertices. Due to release schedule I had, it took a while to get back to the topic. I think widget test hit function can be useful for advanced users. InvisibleButton() + hit test can be used to model any non-rect widget without diving into internal api. |
What I don’t understand is why you have an imgui window covering the screen in the first place. It doesn’t look like you need that at all?
(It’s also not super obvious from your picture what parts are imgui widgets and what parts want input passthrough.)
As part of planned refactor of ButtonBehavior() I think we should be able to pass it the “hovered” state so higher level can compute it based on custom shape, and implementing a full-featured version of InvisibleButton() with arbitrary shape should become easier. I however don’t think a generic callback is desirable and still trying to understand your use case but I don’t know why you have an imgui button covering the screen.
|
I don't have a button covering whole window. I have a window covering whole screen to be able to place buttons in arbitrary positions. Either that or I need to create windows instead buttons, but I read this is not recommended. As far as I know I cannot place widgets without window. |
But where are the imgui buttons in that screenshots? Aren't they only the ones the top rectangular bar? |
Buttons are on top bar, over each green and reddish shape and yellow manipulators. Yes, I'm using buttons for geometry edition since they are the easiest way to capture input (hover, mouse clicks, active state, etc.). Sorry for slow response time. |
@thedmd Do you use the window hit test for something other than creating one rectangular hole? |
On screenschot above every shape was a part of the window so cut out shape is more complex than an rectangle. To keep sanity in check I'm drawing rectangular widgets on window and with custom hit test applied to them. So window hit test callback check only rectangles and if one is hit, widget hit test is perfomed. Since code allow you to set a callback you can implement any test both for window and widget. There is not code which deal specifically with rectangles only in this PR if that's what you're looking for. I'm still keeping code alive and can update PR if you want that. |
I'm asking because your implementation requires the window HitData callback/data to be in scope and usable by the time we reach the next call NewFrame(), which is a very unusual case of opaque user data crossing frame boundaries. As for widgets themselves, I think expanding and promoting the creation of custom widgets would be a more preferable direction. Currently, the signature |
I thought about window hit test callback as its state, like position or size. If callback need additional data to work it is user decision to store such. You're right this is not usual for user data to keep data for next frame. Yet I do not know simpler solution. I didn't thought of using ItemHoverable(). This should be enough to make custom shaped widgets inside opaque rectangle. But this will not support window transparency. As far as I know ItemHoverable() still depends on IsMouseHoveringRect() which test only rectangles. Which brings us back to the widget hit test callback. |
I agree there's lots of interesting to do. Right now I need to solve a specific case, with the additional tricky bit where for docking even though we want to dig a hole through a windows for regular inputs, the docking overlay itself needs to ignore that hole. So if we treat this in a generic fashion, those callback or shape data may need to be carry a little more specific data, needing further design (maybe we have multiple HitTest query or information for multiple "layer" ?). Or in IM always-submit-style maybe the solution is just that in my specific case I can stop submitting the hole when user is holding a window payload. In this case we expect the data to be always resubmitted (in your current PR the WindowHitTest data is not consumed/reset in Begin, but left as-is, that a 1 line change). Don't worry about keeping this PR rebased (unless you need it yourself), the code is self-explanatory and a good reference as-is. |
dca6c71
to
8656f15
Compare
… test function. This allows to add non-rectangular items to window.
…derRectFilledWithHole() helper. (ocornut#1512, ocornut#3368)
…derRectFilledWithHole() helper. (ocornut#1512, ocornut#3368)
This PR does not outlived its expectations. ImGui right now has an ability to add "hole" into the window, which is what I needed. |
Rebased on v1.89 WIP (18808) Out of the blue I updated branch with hit test code. Latest incarnation is more up to ImGui standard. Both item level and window level hit test functions make these possible: 2022-08-20.00-18-36.mp4 |
I agree with you, hope for this issue open again |
Brief
Add ability to customize hit test for widgets and windows. Former allows to create arbitrary shapes inside of a button rectangle, later to create pass-through areas (holes) in windows. This will make #1503 possible.
I'm opening this PR to open a discussion if such functionality is needed in main branch of ImGui. I would like to hear your opinion on that.
Usage
To use this ability user must implement custom hit function with signature:
Call
PushHitTest
/PopHitTest
exactly likePushStyleVar
before drawing widget.Example:
Hit function can be set for windows using these:
Circle button example:
Hole in a window example: