use crate::{AssetLoader, ImageHandle};
use super::{
Button, ButtonBuilder, Checkbox, CheckboxBuilder, Component, Container, ContainerBuilder,
Image, ImageBuilder, Scroll, ScrollBuilder, Text, TextBuilder, TextInput, TextInputBuilder,
};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum NoAction {}
#[derive(Clone, Debug, PartialEq)]
pub enum UiNode<A = NoAction> {
Container(Container<A>),
Text(Text<A>),
Image(Image<A>),
Button(Button<A>),
TextInput(TextInput<A>),
Checkbox(Checkbox<A>),
Scroll(Scroll<A>),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Ui<A = NoAction> {
pub nodes: Vec<UiNode<A>>,
}
impl<A: Clone> Ui<A> {
pub fn new() -> Self {
Self { nodes: Vec::new() }
}
pub fn container(&mut self) -> ContainerBuilder<'_, A> {
ContainerBuilder::new(self)
}
pub fn text(&mut self, value: impl Into<String>) -> TextBuilder<'_, A> {
TextBuilder::new(self, value)
}
pub fn image(&mut self, image: ImageHandle) -> ImageBuilder<'_, A> {
ImageBuilder::new(self, image)
}
pub fn button(&mut self, text: impl Into<String>) -> ButtonBuilder<'_, A> {
ButtonBuilder::new(self, text)
}
pub fn textInput(&mut self, value: impl Into<String>) -> TextInputBuilder<'_, A> {
TextInputBuilder::new(self, value)
}
pub fn checkbox(&mut self, checked: bool) -> CheckboxBuilder<'_, A> {
CheckboxBuilder::new(self, checked)
}
pub fn scroll(&mut self) -> ScrollBuilder<'_, A> {
ScrollBuilder::new(self)
}
pub fn key(&mut self, key: impl Into<String>, build: impl FnOnce(&mut Ui<A>)) {
let mut ui = Ui::new();
build(&mut ui);
let key = key.into();
for mut node in ui.nodes {
node.setKey(key.clone());
self.nodes.push(node);
}
}
pub fn assets(&self) -> AssetLoader {
AssetLoader::default()
}
}
impl<A> UiNode<A> {
pub fn key(&self) -> Option<&str> {
match self {
UiNode::Container(node) => node.key.as_deref(),
UiNode::Text(node) => node.key.as_deref(),
UiNode::Image(node) => node.key.as_deref(),
UiNode::Button(node) => node.key.as_deref(),
UiNode::TextInput(node) => node.key.as_deref(),
UiNode::Checkbox(node) => node.key.as_deref(),
UiNode::Scroll(node) => node.key.as_deref(),
}
}
pub fn component(&self) -> Component {
match self {
UiNode::Container(_) => Component::Container,
UiNode::Text(_) => Component::Text,
UiNode::Image(_) => Component::Image,
UiNode::Button(_) => Component::Button,
UiNode::TextInput(_) => Component::TextInput,
UiNode::Checkbox(_) => Component::Checkbox,
UiNode::Scroll(_) => Component::Scroll,
}
}
pub fn sameIdentity(&self, other: &Self) -> bool {
self.component() == other.component()
&& match (self.key(), other.key()) {
(Some(left), Some(right)) => left == right,
(None, None) => true,
_ => false,
}
}
fn setKey(&mut self, key: String) {
match self {
UiNode::Container(node) => node.key = Some(key),
UiNode::Text(node) => node.key = Some(key),
UiNode::Image(node) => node.key = Some(key),
UiNode::Button(node) => node.key = Some(key),
UiNode::TextInput(node) => node.key = Some(key),
UiNode::Checkbox(node) => node.key = Some(key),
UiNode::Scroll(node) => node.key = Some(key),
}
}
}
impl<A: Clone> Default for Ui<A> {
fn default() -> Self {
Self::new()
}
}