-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Merged by Bors] - Disable UI node Interaction
when ComputedVisibility
is false
#5361
[Merged by Bors] - Disable UI node Interaction
when ComputedVisibility
is false
#5361
Conversation
@undersquire, I'd love to have your review (and ideally hands-on-testing) for this PR :) |
crates/bevy_ui/src/focus.rs
Outdated
if let Some(mut interaction) = interaction { | ||
if *interaction != Interaction::None { | ||
*interaction = Interaction::None; | ||
} | ||
} | ||
|
||
return None; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be simpler and skipping the nested branching to just assign Interaction::None
, as it is small data-wise, should likely be faster:
if let Some(mut interaction) = interaction { | |
if *interaction != Interaction::None { | |
*interaction = Interaction::None; | |
} | |
} | |
return None; | |
interaction.as_mut().map(|interaction| *interaction = Interaction::None); | |
return None; |
EDIT: Oh, it's an Option
, OK. Modified suggestion above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this has the right change detection behavior: that's why this code is so convoluted. I don't want this triggering Interaction
change detection every update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I consider @undersquire's experience proof that this PR works.
Adding to the milestone now that we have approvals; I'd like to enable more serious experiments with bevy_ui during 0.8 and this is an important building block. |
As this just change the focus, setting an entity as not visible doesn't remove it from the layout computation. The proper way to hide a UI node without despawning the entity is to set it's |
Does that propagate downwards correctly? I really dislike that this is the way to control whether or not to hide UI nodes (monolithic components are bad and the discoverability is terrible), but that's a debate for another issue. |
I'm mostly in agreement with Alice here. I think the core problem is that there are multiple ways to remove elements, when there really should be only one. I think the right path forward is to close this PR, then open a new PR that unifies all of these things under the same API/field (disabling visible display, removing from the layout, and disabling interaction). |
Yes, I think this should be considered as a bug in Bevy, as the visibility will not act as expected. |
Strongly feel that we should only have one (and that it should be visibility). Let me make an issue. |
For what it’s worth, I feel like the consistency of using Visibility for UI as well is the better choice. |
from discussion in #5368 and looking how it works on the web, it actually makes sense to keep visibility and display separated. making an item invisible but keeping it in layout is actually useful to ensure layout doesn't change when showing/hiding elements |
Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻
I really would like to see an example that shows the difference between EDIT: Done: #5380 |
I can try to test my menus using the |
Use this PR branch :) Ideally we'll turn that into a proper UI example down the line. |
I can confirm that I get the same effect by modifying the |
bors r+ |
# Objective UI nodes can be hidden by setting their `Visibility` property. Since #5310 was merged, this is now ergonomic to use, as visibility is now inherited. However, UI nodes still receive (and store) interactions when hidden, resulting in surprising hidden state (and an inability to otherwise disable UI nodes. ## Solution Fixes #5360. I've updated the `ui_focus_system` to accomplish this in a minimally intrusive way, and updated the docs to match. **NOTE:** I have not added automated tests to verify this behavior, as we do not currently have a good testing paradigm for `bevy_ui`. I'm not thrilled with that by any means, but I'm not sure fixing it is within scope. ## Paths not taken ### Separate `Disabled` component This is a much larger and more controversial change, and not well-scoped to UI. Furthermore, it is extremely rare that you want hidden UI elements to function: the most common cases are for things like changing tabs, collapsing elements or so on. Splitting this behavior would be more complex, and substantially violate user expectations. ### A separate limbo world Mentioned in the linked issue. Super cool, but all of the problems of the `Disabled` component solution with a whole new RFC-worth of complexity. ### Using change detection to reduce the amount of redundant work Adds a lot of complexity for questionable performance gains. Likely involves a complete refactor of the entire system. We simply don't have the tests or benchmarks here to justify this. ## Changelog - UI nodes are now always in an `Interaction::None` state while they are hidden (via the `ComputedVisibility` component).
Pull request successfully merged into main. Build succeeded: |
Interaction
when ComputedVisibility
is falseInteraction
when ComputedVisibility
is false
…yengine#5361) # Objective UI nodes can be hidden by setting their `Visibility` property. Since bevyengine#5310 was merged, this is now ergonomic to use, as visibility is now inherited. However, UI nodes still receive (and store) interactions when hidden, resulting in surprising hidden state (and an inability to otherwise disable UI nodes. ## Solution Fixes bevyengine#5360. I've updated the `ui_focus_system` to accomplish this in a minimally intrusive way, and updated the docs to match. **NOTE:** I have not added automated tests to verify this behavior, as we do not currently have a good testing paradigm for `bevy_ui`. I'm not thrilled with that by any means, but I'm not sure fixing it is within scope. ## Paths not taken ### Separate `Disabled` component This is a much larger and more controversial change, and not well-scoped to UI. Furthermore, it is extremely rare that you want hidden UI elements to function: the most common cases are for things like changing tabs, collapsing elements or so on. Splitting this behavior would be more complex, and substantially violate user expectations. ### A separate limbo world Mentioned in the linked issue. Super cool, but all of the problems of the `Disabled` component solution with a whole new RFC-worth of complexity. ### Using change detection to reduce the amount of redundant work Adds a lot of complexity for questionable performance gains. Likely involves a complete refactor of the entire system. We simply don't have the tests or benchmarks here to justify this. ## Changelog - UI nodes are now always in an `Interaction::None` state while they are hidden (via the `ComputedVisibility` component).
…yengine#5361) # Objective UI nodes can be hidden by setting their `Visibility` property. Since bevyengine#5310 was merged, this is now ergonomic to use, as visibility is now inherited. However, UI nodes still receive (and store) interactions when hidden, resulting in surprising hidden state (and an inability to otherwise disable UI nodes. ## Solution Fixes bevyengine#5360. I've updated the `ui_focus_system` to accomplish this in a minimally intrusive way, and updated the docs to match. **NOTE:** I have not added automated tests to verify this behavior, as we do not currently have a good testing paradigm for `bevy_ui`. I'm not thrilled with that by any means, but I'm not sure fixing it is within scope. ## Paths not taken ### Separate `Disabled` component This is a much larger and more controversial change, and not well-scoped to UI. Furthermore, it is extremely rare that you want hidden UI elements to function: the most common cases are for things like changing tabs, collapsing elements or so on. Splitting this behavior would be more complex, and substantially violate user expectations. ### A separate limbo world Mentioned in the linked issue. Super cool, but all of the problems of the `Disabled` component solution with a whole new RFC-worth of complexity. ### Using change detection to reduce the amount of redundant work Adds a lot of complexity for questionable performance gains. Likely involves a complete refactor of the entire system. We simply don't have the tests or benchmarks here to justify this. ## Changelog - UI nodes are now always in an `Interaction::None` state while they are hidden (via the `ComputedVisibility` component).
…yengine#5361) # Objective UI nodes can be hidden by setting their `Visibility` property. Since bevyengine#5310 was merged, this is now ergonomic to use, as visibility is now inherited. However, UI nodes still receive (and store) interactions when hidden, resulting in surprising hidden state (and an inability to otherwise disable UI nodes. ## Solution Fixes bevyengine#5360. I've updated the `ui_focus_system` to accomplish this in a minimally intrusive way, and updated the docs to match. **NOTE:** I have not added automated tests to verify this behavior, as we do not currently have a good testing paradigm for `bevy_ui`. I'm not thrilled with that by any means, but I'm not sure fixing it is within scope. ## Paths not taken ### Separate `Disabled` component This is a much larger and more controversial change, and not well-scoped to UI. Furthermore, it is extremely rare that you want hidden UI elements to function: the most common cases are for things like changing tabs, collapsing elements or so on. Splitting this behavior would be more complex, and substantially violate user expectations. ### A separate limbo world Mentioned in the linked issue. Super cool, but all of the problems of the `Disabled` component solution with a whole new RFC-worth of complexity. ### Using change detection to reduce the amount of redundant work Adds a lot of complexity for questionable performance gains. Likely involves a complete refactor of the entire system. We simply don't have the tests or benchmarks here to justify this. ## Changelog - UI nodes are now always in an `Interaction::None` state while they are hidden (via the `ComputedVisibility` component).
Objective
UI nodes can be hidden by setting their
Visibility
property. Since #5310 was merged, this is now ergonomic to use, as visibility is now inherited.However, UI nodes still receive (and store) interactions when hidden, resulting in surprising hidden state (and an inability to otherwise disable UI nodes.
Solution
Fixes #5360.
I've updated the
ui_focus_system
to accomplish this in a minimally intrusive way, and updated the docs to match.NOTE: I have not added automated tests to verify this behavior, as we do not currently have a good testing paradigm for
bevy_ui
. I'm not thrilled with that by any means, but I'm not sure fixing it is within scope.Paths not taken
Separate
Disabled
componentThis is a much larger and more controversial change, and not well-scoped to UI.
Furthermore, it is extremely rare that you want hidden UI elements to function: the most common cases are for things like changing tabs, collapsing elements or so on.
Splitting this behavior would be more complex, and substantially violate user expectations.
A separate limbo world
Mentioned in the linked issue. Super cool, but all of the problems of the
Disabled
component solution with a whole new RFC-worth of complexity.Using change detection to reduce the amount of redundant work
Adds a lot of complexity for questionable performance gains. Likely involves a complete refactor of the entire system.
We simply don't have the tests or benchmarks here to justify this.
Changelog
Interaction::None
state while they are hidden (via theComputedVisibility
component).