1#[cfg(feature = "class_helpers")]
4pub mod class_helpers;
5mod widgets;
6
7pub use widgets::*;
8use bevy_asset::AssetServer;
9use bevy_ecs::bundle::Bundle;
10use bevy_ecs::entity::Entity;
11use bevy_ecs::system::EntityCommands;
12use bevy_hierarchy::{BuildChildren, ChildBuilder};
13use bevy_text::TextStyle;
14use bevy_ui::node_bundles::{ButtonBundle, ImageBundle, NodeBundle, TextBundle};
15
16
17pub struct UiChildBuilder<'a, 'b> {
19 builder: &'a mut ChildBuilder<'b>,
20 assets: &'a AssetServer,
21}
22
23impl<'a, 'b> UiChildBuilder<'a, 'b> {
24
25 pub fn new(builder: &'a mut ChildBuilder<'b>, assets: &'a AssetServer) -> Self {
27 Self { builder, assets }
28 }
29
30 pub fn spawn<'c>(&'c mut self, bundle: impl Bundle) -> UiEntityCommands<'a, 'c> {
31 let commands: EntityCommands<'c> = self.builder.spawn(bundle);
32 UiEntityCommands {
33 assets: self.assets,
34 commands,
35 }
36 }
37 pub fn assets(&self) -> &AssetServer {
38 self.assets
39 }
40}
41
42pub struct UiEntityCommands<'a, 'b> {
44 commands: EntityCommands<'b>,
45 assets: &'a AssetServer
46}
47
48impl<'a, 'b> UiEntityCommands<'a, 'b> {
49 pub fn id(&self) -> Entity {
50 self.commands.id()
51 }
52 pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
53 self.commands.insert(bundle);
54 self
55 }
56 pub fn with_children(mut self, spawn_children: impl FnOnce(&mut UiChildBuilder)) -> Self {
57 self.commands.with_children(move |builder| {
58 let mut ui_builder = UiChildBuilder {
59 assets: self.assets,
60 builder,
61 };
62 spawn_children(&mut ui_builder);
63 });
64 self
65 }
66}
67
68pub trait Class<B> {
70 fn apply(self, b: &mut B);
71}
72
73impl<T> Class<T> for () {
74 fn apply(self, _b: &mut T) {}
75}
76
77impl<F, B> Class<B> for F
78where
79 F: FnOnce(&mut B),
80{
81 fn apply(self, b: &mut B) {
82 self(b);
83 }
84}
85
86impl<F1, F2, B> Class<B> for (F1, F2)
87where
88 F1: Class<B>,
89 F2: Class<B>,
90{
91 fn apply(self, b: &mut B) {
92 self.0.apply(b);
93 self.1.apply(b);
94 }
95}
96
97impl<F1, F2, F3, B> Class<B> for (F1, F2, F3)
98where
99 F1: Class<B>,
100 F2: Class<B>,
101 F3: Class<B>,
102{
103 fn apply(self, b: &mut B) {
104 self.0.apply(b);
105 self.1.apply(b);
106 self.2.apply(b);
107 }
108}
109
110impl<F1, F2, F3, F4, B> Class<B> for (F1, F2, F3, F4)
111where
112 F1: Class<B>,
113 F2: Class<B>,
114 F3: Class<B>,
115 F4: Class<B>,
116{
117 fn apply(self, b: &mut B) {
118 self.0.apply(b);
119 self.1.apply(b);
120 self.2.apply(b);
121 self.3.apply(b);
122 }
123}
124
125impl Class<NodeBundle> for NodeBundle {
126 fn apply(self, b: &mut NodeBundle) {
127 *b = self;
128 }
129}
130
131impl Class<ImageBundle> for ImageBundle {
132 fn apply(self, b: &mut ImageBundle) {
133 *b = self;
134 }
135}
136
137pub trait AssetClass<B> {
140 fn apply(self, assets: &AssetServer, b: &mut B);
141}
142
143impl<T> AssetClass<T> for () {
144 fn apply(self, _a: &AssetServer, _b: &mut T) {}
145}
146
147impl<F, B> AssetClass<B> for F
148where
149 F: FnOnce(&AssetServer, &mut B),
150{
151 fn apply(self, a: &AssetServer, b: &mut B) {
152 self(a, b);
153 }
154}
155
156impl<F1, F2, B> AssetClass<B> for (F1, F2)
157where
158 F1: AssetClass<B>,
159 F2: AssetClass<B>,
160{
161 fn apply(self, a: &AssetServer, b: &mut B) {
162 self.0.apply(a, b);
163 self.1.apply(a, b);
164 }
165}
166
167impl<F1, F2, F3, B> AssetClass<B> for (F1, F2, F3)
168where
169 F1: AssetClass<B>,
170 F2: AssetClass<B>,
171 F3: AssetClass<B>,
172{
173 fn apply(self, a: &AssetServer, b: &mut B) {
174 self.0.apply(a, b);
175 self.1.apply(a, b);
176 self.2.apply(a, b);
177 }
178}
179
180impl<F1, F2, F3, F4, B> AssetClass<B> for (F1, F2, F3, F4)
181where
182 F1: AssetClass<B>,
183 F2: AssetClass<B>,
184 F3: AssetClass<B>,
185 F4: AssetClass<B>,
186{
187 fn apply(self, a: &AssetServer, b: &mut B) {
188 self.0.apply(a, b);
189 self.1.apply(a, b);
190 self.2.apply(a, b);
191 self.3.apply(a, b);
192 }
193}
194
195impl AssetClass<ButtonBundle> for ButtonBundle {
196 fn apply(self, _a: &AssetServer, b: &mut ButtonBundle) {
197 *b = self;
198 }
199}
200
201impl AssetClass<TextBundle> for TextBundle {
202 fn apply(self, _a: &AssetServer, b: &mut TextBundle) {
203 *b = self;
204 }
205}
206
207impl AssetClass<TextStyle> for TextStyle {
208 fn apply(self, _a: &AssetServer, b: &mut TextStyle) {
209 *b = self;
210 }
211}
212
213pub trait EntityWriter {
216 fn set(self, entity: &mut Option<Entity>);
217 fn push(self, destination: &mut Vec<Entity>);
218}
219
220impl EntityWriter for Entity {
221 fn set(self, entity: &mut Option<Entity>) {
223 *entity = Some(self);
224 }
225 fn push(self, entities: &mut Vec<Entity>) {
227 entities.push(self);
228 }
229}