Skip to main content

beuvy_runtime/button/
state.rs

1use super::{ActiveButton, Button, ButtonClickMessage, DisabledButton};
2use crate::focus::{UiHovered, UiPressed};
3use bevy::prelude::*;
4
5pub(super) fn button_hover_over(
6    event: On<Pointer<Over>>,
7    mut commands: Commands,
8    buttons: Query<Has<DisabledButton>, With<Button>>,
9) {
10    let Ok(disabled) = buttons.get(event.entity) else {
11        return;
12    };
13    if disabled {
14        return;
15    }
16    if let Ok(mut entity_commands) = commands.get_entity(event.entity) {
17        entity_commands.try_insert(UiHovered);
18    }
19}
20
21pub(super) fn button_hover_out(
22    event: On<Pointer<Out>>,
23    mut commands: Commands,
24    buttons: Query<Has<DisabledButton>, With<Button>>,
25) {
26    let Ok(disabled) = buttons.get(event.entity) else {
27        return;
28    };
29    if disabled {
30        return;
31    }
32    if let Ok(mut entity_commands) = commands.get_entity(event.entity) {
33        entity_commands.try_remove::<UiHovered>();
34    }
35}
36
37pub(super) fn button_click(
38    event: On<Pointer<Click>>,
39    mut button_click_message: MessageWriter<ButtonClickMessage>,
40    buttons: Query<(&Button, Has<DisabledButton>)>,
41) {
42    let Ok((button, disabled)) = buttons.get(event.entity) else {
43        return;
44    };
45    if disabled {
46        return;
47    }
48    button_click_message.write(ButtonClickMessage {
49        button: button.clone(),
50        entity: event.entity,
51    });
52}
53
54pub(super) fn button_press(
55    event: On<Pointer<Press>>,
56    mut commands: Commands,
57    buttons: Query<Has<DisabledButton>, With<Button>>,
58) {
59    let Ok(disabled) = buttons.get(event.entity) else {
60        return;
61    };
62    if disabled {
63        return;
64    }
65    if let Ok(mut entity_commands) = commands.get_entity(event.entity) {
66        entity_commands.try_insert(UiPressed);
67    }
68}
69
70pub fn sync_button_active_state(commands: &mut Commands, entity: Entity, active: bool) {
71    let Ok(mut entity_commands) = commands.get_entity(entity) else {
72        return;
73    };
74
75    if active {
76        entity_commands.try_insert(ActiveButton);
77    } else {
78        entity_commands.try_remove::<ActiveButton>();
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn ui_pressed_does_not_create_active_button() {
88        let mut world = World::new();
89        let entity = world.spawn((Button::default(), UiPressed)).id();
90
91        assert!(world.entity(entity).contains::<UiPressed>());
92        assert!(!world.entity(entity).contains::<ActiveButton>());
93    }
94}