Skip to content
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

Closed

Conversation

alice-i-cecile
Copy link
Member

@alice-i-cecile alice-i-cecile commented Jul 18, 2022

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).

@alice-i-cecile
Copy link
Member Author

@undersquire, I'd love to have your review (and ideally hands-on-testing) for this PR :)

@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-UI Graphical user interfaces, styles, layouts, and widgets C-Usability A targeted quality-of-life change that makes Bevy easier to use labels Jul 18, 2022
@undersquire
Copy link

Working perfectly on my end, especially now that Visibility affects children too. Not sure if there are any other tests that can be done.

image

image

Open! is sent when I click my Inventory button, and shows the Close button. Close! is sent when I click the Close button, and hides itself.

crates/bevy_ui/src/focus.rs Outdated Show resolved Hide resolved
Comment on lines 131 to 137
if let Some(mut interaction) = interaction {
if *interaction != Interaction::None {
*interaction = Interaction::None;
}
}

return None;
Copy link
Contributor

@superdump superdump Jul 18, 2022

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:

Suggested change
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.

Copy link
Member Author

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.

Co-authored-by: Robert Swain <robert.swain@gmail.com>
crates/bevy_ui/src/focus.rs Outdated Show resolved Hide resolved
crates/bevy_ui/src/focus.rs Show resolved Hide resolved
alice-i-cecile and others added 2 commits July 18, 2022 08:54
Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
Copy link
Contributor

@Nilirad Nilirad left a 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.

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Jul 18, 2022
@alice-i-cecile
Copy link
Member Author

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.

@alice-i-cecile alice-i-cecile added this to the Bevy 0.8 milestone Jul 18, 2022
@mockersf
Copy link
Member

mockersf commented Jul 18, 2022

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 Style component display field to Display::None. https://docs.rs/bevy/latest/bevy/ui/struct.Style.html#structfield.display

@mockersf mockersf removed the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Jul 18, 2022
@alice-i-cecile
Copy link
Member Author

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.

@alice-i-cecile alice-i-cecile removed this from the Bevy 0.8 milestone Jul 18, 2022
@sixfold-origami
Copy link
Contributor

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).

@mockersf
Copy link
Member

mockersf commented Jul 18, 2022

Yes, I think this should be considered as a bug in Bevy, as the visibility will not act as expected.
We should align visibility and display to only one value. display is closer to html/css and the rest of the ui properties, visibility to everything else in Bevy. Do we want to keep both and sync them, or only one?

@alice-i-cecile
Copy link
Member Author

Strongly feel that we should only have one (and that it should be visibility). Let me make an issue.

@superdump
Copy link
Contributor

For what it’s worth, I feel like the consistency of using Visibility for UI as well is the better choice.

@mockersf
Copy link
Member

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

@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Jul 18, 2022
@alice-i-cecile alice-i-cecile marked this pull request as ready for review July 18, 2022 18:35
@alice-i-cecile
Copy link
Member Author

@mockersf @Nilirad I've added some additional docs in my last commit to help make this distinction a little more clear :)

@alice-i-cecile alice-i-cecile added this to the Bevy 0.8 milestone Jul 18, 2022
crates/bevy_ui/src/focus.rs Outdated Show resolved Hide resolved
crates/bevy_ui/src/ui_node.rs Outdated Show resolved Hide resolved
crates/bevy_ui/src/ui_node.rs Outdated Show resolved Hide resolved
crates/bevy_ui/src/ui_node.rs Outdated Show resolved Hide resolved
Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
Copy link
Contributor

@Nilirad Nilirad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻

@Nilirad
Copy link
Contributor

Nilirad commented Jul 19, 2022

I really would like to see an example that shows the difference between ComputedVisibility::is_visible and Display::None. I'll write an issue for that ASAP.

EDIT: Done: #5380

@undersquire
Copy link

undersquire commented Jul 19, 2022

I can try to test my menus using the Display::None and show the results here (comparing to the Visibility implementation). Should I use this PR branch or Bevy 0.7?

@alice-i-cecile
Copy link
Member Author

Use this PR branch :) Ideally we'll turn that into a proper UI example down the line.

@undersquire
Copy link

undersquire commented Jul 19, 2022

I can confirm that I get the same effect by modifying the Style component's Display field. I am unsure what else changes compared to using the Visibility component.

@alice-i-cecile
Copy link
Member Author

[5:25 PM] cart: Feels like an easy win worth squezing in

bors r+

bors bot pushed a commit that referenced this pull request Jul 20, 2022
# 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).
@bors
Copy link
Contributor

bors bot commented Jul 20, 2022

@bors bors bot changed the title Disable UI node Interaction when ComputedVisibility is false [Merged by Bors] - Disable UI node Interaction when ComputedVisibility is false Jul 20, 2022
@bors bors bot closed this Jul 20, 2022
inodentry pushed a commit to IyesGames/bevy that referenced this pull request Aug 8, 2022
…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).
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
…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).
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
…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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Bug An unexpected or incorrect behavior C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Activate/Deactivate UI Elements
7 participants