use bevy_ecs::prelude::*;
use bevy_render::view::Visibility;
use bevy_text::Text;
use bevy_ui::{prelude::*, FocusPolicy};
use crate::{
class::{ApplyClass, BsmlClass},
Bsml,
};
#[derive(Debug, Clone, Component, Default)]
pub struct BsmlClasses(pub Vec<(Interaction, BsmlClass)>);
impl BsmlClasses {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn insert(&mut self, interaction: Interaction, class: impl Into<BsmlClass>) {
let class = class.into();
for (i, c) in &mut self.0 {
if *i == interaction && c.eq_class_type(&class) {
*c = class;
return;
}
}
self.0.push((interaction, class));
}
pub fn remove(&mut self, interaction: Interaction, class: impl Into<BsmlClass>) {
let class = class.into();
self.0
.retain(|(i, c)| *i != interaction || !c.eq_class_type(&class));
}
pub fn iter(&self) -> impl Iterator<Item = &(Interaction, BsmlClass)> {
self.0.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut (Interaction, BsmlClass)> {
self.0.iter_mut()
}
}
pub(super) fn apply_class_system(
mut query: Query<
(
&Interaction,
Ref<BsmlClasses>,
Option<&mut Style>,
Option<&mut Text>,
Option<&mut ZIndex>,
Option<&mut BorderColor>,
Option<&mut BackgroundColor>,
Option<&mut Visibility>,
Option<&mut FocusPolicy>,
),
(Or<(Changed<Interaction>, Changed<BsmlClasses>)>, With<Bsml>),
>,
) {
for (
interaction,
classes,
mut style,
mut text,
mut z_index,
mut border_color,
mut bg_color,
mut visibility,
mut focus_policy,
) in &mut query
{
let mut update_styles = |(_, class): &(Interaction, BsmlClass)| {
if let Some(style) = &mut style {
style.apply_class(class);
}
if let Some(text) = &mut text {
text.apply_class(class);
}
if let Some(z_index) = &mut z_index {
z_index.apply_class(class);
}
if let Some(border_color) = &mut border_color {
border_color.apply_class(class);
}
if let Some(bg_color) = &mut bg_color {
bg_color.apply_class(class);
}
if let Some(visibility) = &mut visibility {
visibility.apply_class(class);
}
if let Some(focus_policy) = &mut focus_policy {
focus_policy.apply_class(class);
}
};
if classes.is_changed() && *interaction != Interaction::None {
classes
.0
.iter()
.filter(|(i, _)| *i == Interaction::None)
.for_each(&mut update_styles);
}
classes
.0
.iter()
.filter(|(i, _)| i == interaction)
.for_each(update_styles);
}
}