-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
UI- Interaction Released state for nodes #8157
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
Conversation
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
This is a breaking change due to the addition of a new variant on a public not non_exhaustive enum. Can you fully flesh out the migration guide section? |
Something like that in updated description would be enough? @james7132 |
This seems to be trying to squash a transient event into persistent state, and it seems like a bit of an impedance mismatch. Is there any reason why UI click events (that target a specific UI node) can't go through the bevy events system like the global mouse events do? |
Events aren't any better as you still need to query for the button if you are going to do anything with it: fn button_system(
mut interaction_event: EventReader<InteractionEvent>,
mut button_query: Query<
(&mut BackgroundColor, &Children),
With<Button>,
>,
mut text_query: Query<&mut Text>,
) {
for event in interaction_event.iter() {
if let Ok((mut color, children)) = button_query.get_mut(event.target_id) {
let mut text = text_query.get_mut(children[0]).unwrap();
match event.interaction {
Interaction::Released => {
text.sections[0].value = "Released".to_string();
*color = PRESSED_BUTTON.into();
}
Interaction::Clicked => {
text.sections[0].value = "Press".to_string();
*color = PRESSED_BUTTON.into();
}
Interaction::Hovered => {
text.sections[0].value = "Hover".to_string();
*color = HOVERED_BUTTON.into();
}
Interaction::None => {
text.sections[0].value = "Button".to_string();
*color = NORMAL_BUTTON.into();
}
}
}
}
} |
That does seem better to me. Yes, you still have to query any components you want to update. But at least your callback will get called at exactly the right time. Otherwise you have to deal with things like transitions from |
Also, I wouldn't expect an enum |
Yeah, I don't think we disagree really. The example was meant more to show how this pattern of creating a new system for every button to model basic responses like text changing on mouse over etc is terrible regardless of whether you use events or change detection or whatever. |
I've noticed quite a bit of strange behavior on I put a few log lines in examples/ui/button.rs and while the Interaction variants do appear to be delivered correctly the button state gets out of sync with the state of the mouse. Notice when I hold down a click, the log says "Clicked" but the button still says "Hover" until the click is released or the mouse moved. If I just stay over the button without moving the mouse and click and hold, release, and then click and hold again, the button starts saying "Released" while held down, and "Press" while released, until the mouse is moved, then it finally says released again. As I mentioned button-states.mov |
I was thinking about that for a while (first part mostly) and decided to take a different approach that doesn't require change in base bevy code and came up with this: https://github.com/Leinnan/bevy_button_released_plugin |
Was surprised that |
Tackling this space over in #15597. Thanks for providing this prior art; it was helpful when looking at designs <3 |
Objective
Fixes #5769
Solution
Instead of changing node state from
Pressed
toNone
on click release, it first checks if pointer is still above element. If not, just go toNone
state. If yes changes it toReleased
state allowing for more familiar user experience (users expect action to happen on release, not click, also if we start pressing on button but release it with cursor outside of it we don't want to make action happened).Changelog
Added
Released
state to nodesInteraction
enumMigration Guide