use crate::ExtendedUiConfiguration;
use crate::styles::{CssClass, CssSource, TagName};
use crate::widgets::{Divider, DividerAlignment, WidgetId, WidgetKind};
use bevy::camera::visibility::RenderLayers;
use bevy::prelude::*;
#[derive(Component)]
struct DividerBase;
pub struct DividerWidget;
#[derive(Component, Deref, DerefMut)]
struct PrevDividerAlignment(DividerAlignment);
impl Plugin for DividerWidget {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(internal_node_creation_system, update_divider_alignment).chain(),
);
}
}
fn internal_node_creation_system(
mut commands: Commands,
query: Query<
(Entity, &Divider, Option<&CssSource>, Option<&CssClass>),
(With<Divider>, Without<DividerBase>),
>,
config: Res<ExtendedUiConfiguration>,
) {
let layer = config.render_layers.first().unwrap_or(&1);
for (entity, divider, source_opt, class_opt) in query.iter() {
let mut css_source = CssSource::default();
if let Some(source) = source_opt {
css_source = source.clone();
}
let align_class = alignment_class(÷r.alignment);
let mut classes = class_opt.map(|c| c.0.clone()).unwrap_or_default();
if !classes.iter().any(|c| c == align_class) {
classes.push(align_class.to_string());
}
commands.entity(entity).insert((
Name::new(format!("Divider-{}", divider.entry)),
Node::default(),
WidgetId {
id: divider.entry,
kind: WidgetKind::Divider,
},
ZIndex::default(),
Pickable::IGNORE,
BackgroundColor::default(),
BorderColor::default(),
css_source,
TagName("divider".to_string()),
CssClass(classes),
RenderLayers::layer(*layer),
DividerBase,
PrevDividerAlignment(divider.alignment.clone()),
));
}
}
fn update_divider_alignment(
mut divider_query: Query<
(&Divider, &mut CssClass, &mut PrevDividerAlignment),
(With<DividerBase>, Changed<Divider>),
>,
) {
for (divider, mut classes, mut previous_alignment) in divider_query.iter_mut() {
if **previous_alignment == divider.alignment {
continue;
}
set_alignment_class(&mut classes, ÷r.alignment);
**previous_alignment = divider.alignment.clone();
info!("divider alignment -> {:?}", divider.alignment);
}
}
fn alignment_class(alignment: &DividerAlignment) -> &'static str {
match alignment {
DividerAlignment::Vertical => "divider-vert",
DividerAlignment::Horizontal => "divider-hori",
}
}
fn set_alignment_class(classes: &mut CssClass, alignment: &DividerAlignment) {
classes
.0
.retain(|c| c != "divider-vert" && c != "divider-hori");
classes.0.push(alignment_class(alignment).to_string());
}