beuvy_runtime/button/
state.rs1use 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}