diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 9006ef20d5c9b..b0b9a3ff8b9af 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -11,6 +11,7 @@ use bevy_window::CursorMoved; pub enum Interaction { Clicked, Hovered, + Pressed, None, } @@ -37,6 +38,7 @@ pub struct State { cursor_moved_event_reader: EventReader, cursor_position: Vec2, hovered_entity: Option, + just_clicked: bool, } pub fn ui_focus_system( @@ -55,7 +57,7 @@ pub fn ui_focus_system( state.cursor_position = cursor_moved.position; } - if mouse_button_input.just_released(MouseButton::Left) { + if state.just_clicked { for (_entity, _node, _transform, interaction, _focus_policy) in &mut node_query.iter() { if let Some(mut interaction) = interaction { if *interaction == Interaction::Clicked { @@ -63,9 +65,11 @@ pub fn ui_focus_system( } } } + state.just_clicked = false; } - let mouse_clicked = mouse_button_input.just_pressed(MouseButton::Left); + let mouse_pressed = mouse_button_input.just_pressed(MouseButton::Left); + let mouse_released = mouse_button_input.just_released(MouseButton::Left); let mut hovered_entity = None; { @@ -85,9 +89,7 @@ pub fn ui_focus_system( Some((entity, focus_policy, interaction, FloatOrd(position.z()))) } else { if let Some(mut interaction) = interaction { - if *interaction == Interaction::Hovered { - *interaction = Interaction::None; - } + *interaction = Interaction::None; } None } @@ -97,10 +99,15 @@ pub fn ui_focus_system( moused_over_z_sorted_nodes.sort_by_key(|(_, _, _, z)| -*z); for (entity, focus_policy, interaction, _) in moused_over_z_sorted_nodes { if let Some(mut interaction) = interaction { - if mouse_clicked { + if mouse_pressed { // only consider nodes with ClickState "clickable" - if *interaction != Interaction::Clicked { + if *interaction != Interaction::Pressed { + *interaction = Interaction::Pressed; + } + } else if mouse_released { + if *interaction == Interaction::Pressed { *interaction = Interaction::Clicked; + state.just_clicked = true; } } else if *interaction == Interaction::None { *interaction = Interaction::Hovered; @@ -113,7 +120,7 @@ pub fn ui_focus_system( FocusPolicy::Block => { break; } - FocusPolicy::Pass => { /* allow the next node to be hovered/clicked */ } + FocusPolicy::Pass => { /* allow the next node to be hovered/pressed/clicked */ } } } } diff --git a/examples/ui/button.rs b/examples/ui/button.rs index 6e371de7804bc..bc7f752ceb405 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -14,6 +14,7 @@ struct ButtonMaterials { normal: Handle, hovered: Handle, pressed: Handle, + clicked: Handle, } impl FromResources for ButtonMaterials { @@ -23,6 +24,7 @@ impl FromResources for ButtonMaterials { normal: materials.add(Color::rgb(0.02, 0.02, 0.02).into()), hovered: materials.add(Color::rgb(0.05, 0.05, 0.05).into()), pressed: materials.add(Color::rgb(0.1, 0.5, 0.1).into()), + clicked: materials.add(Color::rgb(1.0, 0.0, 0.0).into()), } } } @@ -41,13 +43,17 @@ fn button_system( let mut text = text_query.get_mut::(children[0]).unwrap(); match *interaction { Interaction::Clicked => { - text.value = "Press".to_string(); - *material = button_materials.pressed; + text.value = "Click".to_string(); + *material = button_materials.clicked; } Interaction::Hovered => { text.value = "Hover".to_string(); *material = button_materials.hovered; } + Interaction::Pressed => { + text.value = "Press".to_string(); + *material = button_materials.pressed; + } Interaction::None => { text.value = "Button".to_string(); *material = button_materials.normal;