#![allow(clippy::module_name_repetitions)]
use bevy::prelude::*;
use crate::prelude::FormButtonBundle;
pub struct FormPlugin;
impl Plugin for FormPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<FormInputTextStyle>()
.add_event::<GenericFormEvent>()
.add_systems(Update, form_keyboard);
}
}
#[derive(Component, Reflect)]
pub struct Form;
#[derive(Component, Reflect)]
pub struct FormValid;
#[derive(Component, Reflect)]
pub struct FormInvalid(pub Vec<FormValidationError>);
#[derive(Resource, Debug)]
pub struct FormInputTextStyle(pub TextStyle);
impl Default for FormInputTextStyle {
fn default() -> Self {
FormInputTextStyle(TextStyle {
font_size: 20.0,
color: Color::BLACK,
..default()
})
}
}
#[derive(Event, Debug)]
pub struct GenericFormEvent {
pub form: FormEvent<Entity>,
}
#[derive(Debug)]
pub enum FormEvent<T> {
Submit(T),
Apply(T),
Cancel(Entity),
Custom(Entity, String, Option<T>),
}
#[derive(Event, Debug)]
pub struct FormValidationEvent {
pub valid: bool,
pub dirty: bool,
pub fields: Vec<FormValidationError>,
}
#[derive(Debug, Clone, Reflect)]
pub enum FormValidationError {
Required(Entity),
Invalid(Entity),
Custom(Entity, String),
}
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub enum FormEventAction {
Submit,
Apply,
Cancel,
Custom(String),
}
#[derive(Component)]
pub struct FormActionId(pub usize);
pub trait FormActions: Sized {
type FormEntity;
fn get_button_bundles(form: Entity) -> Vec<FormButtonBundle>;
fn from_id_and_data(id: usize, entity: Option<Self::FormEntity>) -> Result<Self, String>;
}
#[allow(clippy::needless_pass_by_value)]
fn form_keyboard(
keyboard_input: Res<ButtonInput<KeyCode>>,
q_form: Query<(Entity, Option<&FormInvalid>), With<Form>>,
mut form_events: EventWriter<GenericFormEvent>,
) {
if let Ok((entity, invalid)) = q_form.get_single() {
if keyboard_input.just_released(KeyCode::Enter) && invalid.is_none() {
form_events.send(GenericFormEvent {
form: FormEvent::Submit(entity),
});
} else if keyboard_input.just_released(KeyCode::Escape) {
form_events.send(GenericFormEvent {
form: FormEvent::Cancel(entity),
});
}
}
}