1use bevy_asset::AssetServer;
2use bevy_ecs::prelude::Bundle;
3use bevy_text::{TextStyle, TextSection};
4use bevy_ecs::entity::Entity;
5use bevy_ecs::system::Commands;
6use bevy_ui::{Val, FlexWrap, Style, JustifyContent, AlignItems};
7use bevy_ui::node_bundles::{NodeBundle, TextBundle, ButtonBundle, ImageBundle};
8use bevy_hierarchy::BuildChildren;
9use super::{Class, AssetClass, UiChildBuilder};
10
11
12pub fn root(
14 class: impl Class<NodeBundle>,
15 assets: &AssetServer,
16 commands: &mut Commands,
17 children: impl FnOnce(&mut UiChildBuilder)
18) -> Entity {
19 rooti(class, assets, commands, (), children)
20}
21
22pub fn rooti(
24 class: impl Class<NodeBundle>,
25 assets: &AssetServer,
26 commands: &mut Commands,
27 extras: impl Bundle,
28 children: impl FnOnce(&mut UiChildBuilder)
29) -> Entity {
30 let mut bundle = NodeBundle::default();
31 class.apply(&mut bundle);
32 commands
33 .spawn((bundle, extras))
34 .with_children(|builder| {
35 children(&mut UiChildBuilder {
36 builder,
37 assets
38 });
39 })
40 .id()
41}
42
43
44pub fn blank(
47 parent: Entity,
48 class: impl Class<NodeBundle>,
49 assets: &AssetServer,
50 commands: &mut Commands,
51 children: impl FnOnce(&mut UiChildBuilder)
52) -> Entity {
53 blanki(parent, class, assets, commands, (), children)
54}
55
56pub fn blanki(
59 parent: Entity,
60 class: impl Class<NodeBundle>,
61 assets: &AssetServer,
62 commands: &mut Commands,
63 extras: impl Bundle,
64 children: impl FnOnce(&mut UiChildBuilder)
65) -> Entity {
66 commands
67 .entity(parent)
68 .with_children(|builder| {
69 let mut bundle = NodeBundle::default();
70 class.apply(&mut bundle);
71 let mut builder = UiChildBuilder { builder, assets };
72 builder.spawn((bundle, extras)).with_children(children);
73 })
74 .id()
75}
76
77pub fn node(
79 class: impl Class<NodeBundle>,
80 parent: &mut UiChildBuilder,
81 children: impl FnOnce(&mut UiChildBuilder)
82) -> Entity {
83 nodei(class, (), parent, children)
84}
85
86
87pub fn nodei(
89 class: impl Class<NodeBundle>,
90 extras: impl Bundle,
91 parent: &mut UiChildBuilder,
92 children: impl FnOnce(&mut UiChildBuilder)
93) -> Entity {
94 let mut bundle = NodeBundle::default();
95 class.apply(&mut bundle);
96
97 let mut commands = parent.spawn(bundle);
98 commands.insert(extras);
99 commands.with_children(children).id()
100}
101
102pub fn text(
104 text: impl Into<String>,
105 class: impl AssetClass<TextBundle>,
106 text_class: impl AssetClass<TextStyle>,
107 parent: &mut UiChildBuilder
108) -> Entity {
109 texti(text, class, text_class, (), parent)
110}
111
112pub fn texti(
114 text: impl Into<String>,
115 class: impl AssetClass<TextBundle>,
116 text_class: impl AssetClass<TextStyle>,
117 extras: impl Bundle,
118 parent: &mut UiChildBuilder
119) -> Entity {
120 let mut bundle = TextBundle::default();
121 class.apply(parent.assets, &mut bundle);
122 let sections = &mut bundle.text.sections;
123 let mut style = TextStyle::default();
124 text_class.apply(parent.assets, &mut style);
125 sections.push(TextSection {
126 value: text.into(),
127 style,
128 });
129 parent.spawn((bundle, extras)).id()
130}
131
132pub fn button(
134 class: impl AssetClass<ButtonBundle>,
135 parent: &mut UiChildBuilder,
136 children: impl FnOnce(&mut UiChildBuilder)
137) -> Entity {
138 buttoni(class, (), parent, children)
139}
140
141pub fn buttoni(
143 class: impl AssetClass<ButtonBundle>,
144 extras: impl Bundle,
145 parent: &mut UiChildBuilder,
146 children: impl FnOnce(&mut UiChildBuilder)
147) -> Entity {
148 let mut bundle = ButtonBundle::default();
149 class.apply(parent.assets, &mut bundle);
150 parent
151 .spawn((bundle, extras))
152 .with_children(children).id()
153}
154
155pub fn simple_button(
157 class: impl AssetClass<ButtonBundle>,
158 parent: &mut UiChildBuilder
159) -> Entity {
160 simple_buttoni(class, (), parent)
161}
162
163pub fn simple_buttoni(
165 class: impl AssetClass<ButtonBundle>,
166 extras: impl Bundle,
167 parent: &mut UiChildBuilder
168) -> Entity {
169 let mut bundle = ButtonBundle::default();
170 class.apply(parent.assets, &mut bundle);
171 parent.spawn((bundle, extras)).id()
172}
173
174pub fn text_button(
176 txt: impl Into<String>,
177 class: impl AssetClass<ButtonBundle>,
178 text_style: impl AssetClass<TextStyle>,
179 parent: &mut UiChildBuilder
180) -> Entity {
181 text_buttoni(txt, class, text_style, (), parent)
182}
183
184pub fn text_buttoni(
186 txt: impl Into<String>,
187 class: impl AssetClass<ButtonBundle>,
188 text_style: impl AssetClass<TextStyle>,
189 extras: impl Bundle,
190 parent: &mut UiChildBuilder
191) -> Entity {
192 buttoni(class, extras, parent, |p| {
193 text(txt, (), text_style, p);
194 })
195}
196
197pub fn image(
199 class: impl AssetClass<ImageBundle>,
200 parent: &mut UiChildBuilder
201) -> Entity {
202 imagei(class, (), parent)
203}
204
205pub fn imagei(
207 class: impl AssetClass<ImageBundle>,
208 extras: impl Bundle,
209 parent: &mut UiChildBuilder
210) -> Entity {
211 let mut bundle = ImageBundle::default();
212 class.apply(parent.assets, &mut bundle);
213 parent.spawn((bundle, extras)).id()
214}
215
216pub fn image_pane(
218 class: impl AssetClass<ImageBundle>,
219 parent: &mut UiChildBuilder,
220 children: impl FnOnce(&mut UiChildBuilder)
221) -> Entity {
222 image_panei(class, parent, (), children)
223}
224
225pub fn image_panei(
227 class: impl AssetClass<ImageBundle>,
228 parent: &mut UiChildBuilder,
229 extras: impl Bundle,
230 children: impl FnOnce(&mut UiChildBuilder)
231) -> Entity {
232 let mut bundle = ImageBundle::default();
233 class.apply(parent.assets, &mut bundle);
234 parent
235 .spawn((bundle, extras))
236 .with_children(children).id()
237}
238
239pub fn grid(
242 rows: usize,
243 columns: usize,
244 class: impl Class<NodeBundle>,
245 parent: &mut UiChildBuilder,
246 children: impl FnMut(&mut UiChildBuilder, usize, usize)
247) -> Entity {
248 gridi(rows, columns, class, (), parent, children)
249}
250
251pub fn gridi(
254 rows: usize,
255 columns: usize,
256 class: impl Class<NodeBundle>,
257 extras: impl Bundle,
258 parent: &mut UiChildBuilder,
259 mut children: impl FnMut(&mut UiChildBuilder, usize, usize)
260) -> Entity {
261 let mut container_bundle = NodeBundle::default();
263 class.apply(&mut container_bundle);
264 container_bundle.style.flex_wrap = FlexWrap::Wrap;
265 let mut container = parent.spawn((container_bundle, extras));
266
267 let cell_bundle = NodeBundle {
269 style: Style {
270 width: Val::Percent(100.0 / columns as f32),
271 height: Val::Percent(100.0 / rows as f32),
272 justify_content: JustifyContent::Center,
273 align_items: AlignItems::Center,
274 ..Default::default()
275 },
276 ..Default::default()
277 };
278 for row in 0..rows {
279 for col in 0..columns {
280 container = container.with_children(|container| {
281 container
282 .spawn(cell_bundle.clone())
283 .with_children(|cell| children(cell, row, col));
284 });
285 }
286 }
287 container.id()
288}