use crate::element::{ElementProps, ElementWidget};
use crate::parser::color::parse_color;
use crate::parser::values::{parse_attribute, parse_matches};
use crate::widgets::Widget;
use bevy::asset::AssetServer;
use bevy::color::Color;
use bevy::prelude::*;
use roxmltree::Node as XmlNode;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
pub enum DividerOrientation {
#[default]
Horizontal,
Vertical,
}
impl DividerOrientation {
pub fn parse(s: &str) -> Result<Self, String> {
parse_matches(
s,
&[
("horizontal", || Ok(Self::Horizontal)),
("vertical", || Ok(Self::Vertical)),
],
)
}
}
#[derive(Component, Clone, Debug, PartialEq, Default)]
pub struct DividerWidget {
pub orientation: DividerOrientation,
pub color: Option<Color>,
}
impl Widget for DividerWidget {
fn spawn(&self, commands: &mut EntityCommands, _: &AssetServer) -> Entity {
commands.id()
}
fn parse(
node: &XmlNode,
prefix: Option<&str>,
base: Option<&ElementWidget>,
) -> Result<Self, String>
where
Self: Sized,
{
let base_div = match base {
Some(ElementWidget::Divider(div)) => Some(div),
_ => None,
};
let orientation = parse_attribute(node, "orientation", prefix, DividerOrientation::parse)?
.or_else(|| base_div.map(|b| b.orientation))
.unwrap_or_default();
let color = parse_attribute(node, "color", prefix, parse_color)?
.or_else(|| base_div.and_then(|b| b.color));
Ok(Self { orientation, color })
}
fn apply_defaults(
node: &XmlNode,
default: &mut ElementProps,
hover: &mut ElementProps,
click: &mut ElementProps,
) {
let is_vertical = node
.attribute("orientation")
.map(|s| s.trim() == "vertical")
.unwrap_or(false);
let default_color = Color::srgb(0.25, 0.25, 0.28);
if is_vertical {
if !node.has_attribute("width") {
default.node.width = Val::Px(1.0);
}
if !node.has_attribute("height") {
default.node.height = Val::Percent(100.0);
}
if !node.has_attribute("margin") {
default.node.margin = UiRect::axes(Val::Px(8.0), Val::Px(0.0));
}
} else {
if !node.has_attribute("width") {
default.node.width = Val::Percent(100.0);
}
if !node.has_attribute("height") {
default.node.height = Val::Px(1.0);
}
if !node.has_attribute("margin") {
default.node.margin = UiRect::axes(Val::Px(0.0), Val::Px(8.0));
hover.node.margin = default.node.margin;
click.node.margin = default.node.margin;
}
}
if default.bg_color.is_none() {
default.bg_color = Some(default_color);
}
}
}