bevy_ui_builders/dialog/
systems.rs

1//! Dialog interaction systems
2
3use bevy::prelude::*;
4use super::types::{DialogOverlay, CancelButton};
5
6/// System to handle ESC key for dismissible dialogs
7pub fn handle_dialog_escape(
8    keyboard: Res<ButtonInput<KeyCode>>,
9    mut commands: Commands,
10    overlay_query: Query<(Entity, &DialogOverlay)>,
11) {
12    if keyboard.just_pressed(KeyCode::Escape) {
13        for (entity, overlay) in &overlay_query {
14            if overlay.dismissible {
15                commands.entity(entity).despawn();
16            }
17        }
18    }
19}
20
21/// System to handle clicking outside dismissible dialogs
22pub fn handle_dialog_overlay_click(
23    mut commands: Commands,
24    overlay_query: Query<(Entity, &DialogOverlay, &Interaction), Changed<Interaction>>,
25) {
26    for (entity, overlay, interaction) in &overlay_query {
27        if *interaction == Interaction::Pressed && overlay.dismissible {
28            commands.entity(entity).despawn();
29        }
30    }
31}
32
33/// System to handle cancel button clicks
34pub fn handle_cancel_button(
35    mut commands: Commands,
36    button_query: Query<&Interaction, (Changed<Interaction>, With<CancelButton>)>,
37    overlay_query: Query<Entity, With<DialogOverlay>>,
38) {
39    for interaction in &button_query {
40        if *interaction == Interaction::Pressed {
41            // Despawn all dialog overlays when cancel is pressed
42            for entity in &overlay_query {
43                commands.entity(entity).despawn();
44            }
45        }
46    }
47}
48
49/// Event fired when a dialog button is clicked
50#[derive(Event)]
51pub struct DialogButtonEvent {
52    pub dialog_type: super::types::DialogType,
53    pub button_marker: String,
54}
55
56/// System to emit events for dialog button clicks
57pub fn emit_dialog_button_events(
58    mut events: EventWriter<DialogButtonEvent>,
59    confirm_query: Query<&Interaction, (Changed<Interaction>, With<super::types::ConfirmButton>)>,
60    save_query: Query<&Interaction, (Changed<Interaction>, With<super::types::SaveButton>)>,
61    discard_query: Query<&Interaction, (Changed<Interaction>, With<super::types::DiscardButton>)>,
62    ok_query: Query<&Interaction, (Changed<Interaction>, With<super::types::OkButton>)>,
63    yes_query: Query<&Interaction, (Changed<Interaction>, With<super::types::YesButton>)>,
64    no_query: Query<&Interaction, (Changed<Interaction>, With<super::types::NoButton>)>,
65    overlay_query: Query<&DialogOverlay>,
66) {
67    // Check each button type
68    for interaction in &confirm_query {
69        if *interaction == Interaction::Pressed {
70            if let Ok(overlay) = overlay_query.single() {
71                events.write(DialogButtonEvent {
72                    dialog_type: overlay.dialog_type,
73                    button_marker: "confirm".to_string(),
74                });
75            }
76        }
77    }
78
79    for interaction in &save_query {
80        if *interaction == Interaction::Pressed {
81            if let Ok(overlay) = overlay_query.single() {
82                events.write(DialogButtonEvent {
83                    dialog_type: overlay.dialog_type,
84                    button_marker: "save".to_string(),
85                });
86            }
87        }
88    }
89
90    for interaction in &discard_query {
91        if *interaction == Interaction::Pressed {
92            if let Ok(overlay) = overlay_query.single() {
93                events.write(DialogButtonEvent {
94                    dialog_type: overlay.dialog_type,
95                    button_marker: "discard".to_string(),
96                });
97            }
98        }
99    }
100
101    for interaction in &ok_query {
102        if *interaction == Interaction::Pressed {
103            if let Ok(overlay) = overlay_query.single() {
104                events.write(DialogButtonEvent {
105                    dialog_type: overlay.dialog_type,
106                    button_marker: "ok".to_string(),
107                });
108            }
109        }
110    }
111
112    for interaction in &yes_query {
113        if *interaction == Interaction::Pressed {
114            if let Ok(overlay) = overlay_query.single() {
115                events.write(DialogButtonEvent {
116                    dialog_type: overlay.dialog_type,
117                    button_marker: "yes".to_string(),
118                });
119            }
120        }
121    }
122
123    for interaction in &no_query {
124        if *interaction == Interaction::Pressed {
125            if let Ok(overlay) = overlay_query.single() {
126                events.write(DialogButtonEvent {
127                    dialog_type: overlay.dialog_type,
128                    button_marker: "no".to_string(),
129                });
130            }
131        }
132    }
133}