use bevy::{
ecs::{relationship::RelatedSpawnerCommands, system::EntityCommands},
prelude::*,
};
#[derive(Debug, Clone, Resource)]
pub struct Palette {
pub border: Color,
pub background: Color,
pub text: Color,
}
impl Default for Palette {
fn default() -> Self {
Self {
border: Color::BLACK,
background: Color::WHITE.mix(&Color::BLACK, 0.8),
text: Color::WHITE,
}
}
}
pub trait Widgets {
fn button(&mut self, text: impl Into<String>, palette: &Palette) -> EntityCommands<'_>;
fn column(&mut self) -> EntityCommands<'_>;
fn column_wrap(&mut self) -> EntityCommands<'_>;
}
impl<T: Spawn> Widgets for T {
fn button(&mut self, text: impl Into<String>, palette: &Palette) -> EntityCommands<'_> {
let mut entity = self.spawn((
Name::new("Button"),
Button,
Node {
margin: UiRect {
left: Val::Px(10.0),
..default()
},
border: UiRect::all(Val::Px(2.0)),
justify_content: JustifyContent::Center,
align_items: AlignItems::Center,
..default()
},
BorderColor::all(palette.border),
BackgroundColor(palette.background),
));
entity.with_children(|children| {
children.spawn((
Name::new("Button Text"),
Text::new(text),
TextColor(palette.text),
));
});
entity
}
fn column(&mut self) -> EntityCommands<'_> {
self.spawn(Node {
flex_direction: FlexDirection::Column,
..default()
})
}
fn column_wrap(&mut self) -> EntityCommands<'_> {
self.spawn(Node {
flex_direction: FlexDirection::Column,
flex_wrap: FlexWrap::Wrap,
..default()
})
}
}
trait Spawn {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands<'_>;
}
impl Spawn for Commands<'_, '_> {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands<'_> {
self.spawn(bundle)
}
}
impl<R: bevy::ecs::relationship::Relationship> Spawn for RelatedSpawnerCommands<'_, R> {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands<'_> {
self.spawn(bundle)
}
}
impl Spawn for EntityCommands<'_> {
fn spawn<B: Bundle>(&mut self, bundle: B) -> EntityCommands<'_> {
self.insert(bundle);
self.reborrow()
}
}