swoop_ui/
container.rs

1use bevy_asset::prelude::*;
2use bevy_color::prelude::*;
3use bevy_ecs::prelude::*;
4use bevy_image::prelude::*;
5use bevy_ui::prelude::*;
6
7use crate::UiToBundle;
8
9pub mod h_stack;
10pub mod v_stack;
11
12pub mod prelude {
13    pub use super::h_stack::*;
14    pub use super::v_stack::*;
15    pub use super::{
16        BackgroundContainer, BackgroundStyle, BorderContainer, BorderStyle, StackContainer,
17    };
18}
19
20pub trait StackContainer: Default {
21    fn node_node(&mut self) -> &mut Node;
22
23    fn new(align_items: AlignItems, gap: Val) -> Self
24    where
25        Self: Sized,
26    {
27        let mut stack = Self::default();
28        stack.node_node().align_items = align_items;
29        stack.spacing(gap)
30    }
31
32    fn justify_content(mut self, justify: JustifyContent) -> Self
33    where
34        Self: Sized,
35    {
36        self.node_node().justify_content = justify;
37        self
38    }
39
40    fn align_items(mut self, align_items: AlignItems) -> Self
41    where
42        Self: Sized,
43    {
44        self.node_node().align_items = align_items;
45        self
46    }
47
48    fn spacing(mut self, gap: Val) -> Self
49    where
50        Self: Sized,
51    {
52        let node = self.node_node();
53        match node.flex_direction {
54            FlexDirection::Row => node.column_gap = gap,
55            FlexDirection::Column => node.row_gap = gap,
56            _ => {}
57        }
58        self
59    }
60}
61
62pub trait BackgroundContainer {
63    fn background_node(&mut self) -> &mut BackgroundStyle;
64
65    fn background_color(mut self, color: impl Into<Color>) -> Self
66    where
67        Self: Sized,
68    {
69        *self.background_node() = BackgroundStyle::Color(color.into());
70        self
71    }
72
73    fn background_image(mut self, image: Handle<Image>) -> Self
74    where
75        Self: Sized,
76    {
77        *self.background_node() = BackgroundStyle::Image(image);
78        self
79    }
80}
81
82pub enum BackgroundStyle {
83    Color(Color),
84    Image(Handle<Image>),
85}
86
87impl UiToBundle for BackgroundStyle {
88    fn pack(self) -> impl Bundle {
89        match self {
90            BackgroundStyle::Color(color) => (
91                BackgroundColor(color),
92                ImageNode::solid_color(Srgba::NONE.into()),
93            ),
94            BackgroundStyle::Image(handle) => {
95                (BackgroundColor(Srgba::NONE.into()), ImageNode::new(handle))
96            }
97        }
98    }
99}
100
101impl Default for BackgroundStyle {
102    fn default() -> Self {
103        BackgroundStyle::Color(Srgba::NONE.into())
104    }
105}
106
107pub trait BorderContainer {
108    fn border_node(&mut self) -> &mut BorderStyle;
109
110    fn border_color(mut self, border_color: impl Into<Color>) -> Self
111    where
112        Self: Sized,
113    {
114        self.border_node().border_color.0 = border_color.into();
115        self
116    }
117
118    fn border_radius(mut self, border_radius: BorderRadius) -> Self
119    where
120        Self: Sized,
121    {
122        self.border_node().border_radius = border_radius;
123        self
124    }
125}
126
127pub struct BorderStyle {
128    border_radius: BorderRadius,
129    border_color: BorderColor,
130}
131
132impl UiToBundle for BorderStyle {
133    fn pack(self) -> impl Bundle {
134        (self.border_radius, self.border_color)
135    }
136}
137
138impl Default for BorderStyle {
139    fn default() -> Self {
140        Self {
141            border_radius: BorderRadius::ZERO,
142            border_color: BorderColor(Srgba::NONE.into()),
143        }
144    }
145}