bevy_ui_builders/progress/
builder.rs1use bevy::prelude::*;
4use crate::{colors, dimensions};
5use super::types::*;
6
7pub struct ProgressBarBuilder {
9 value: f32,
10 style: ProgressBarStyle,
11 width: Val,
12 height: Option<f32>,
13 margin: UiRect,
14 track_color: Option<Color>,
15 fill_color: Option<Color>,
16 show_label: bool,
17 custom_label: Option<String>,
18 animated: bool,
19}
20
21impl ProgressBarBuilder {
22 pub fn new(value: f32) -> Self {
23 Self {
24 value: value.clamp(0.0, 1.0),
25 style: ProgressBarStyle::Default,
26 width: Val::Percent(100.0),
27 height: None,
28 margin: UiRect::all(Val::Px(0.0)),
29 track_color: None,
30 fill_color: None,
31 show_label: false,
32 custom_label: None,
33 animated: false,
34 }
35 }
36
37 pub fn style(mut self, style: ProgressBarStyle) -> Self {
38 self.style = style;
39 self
40 }
41
42 pub fn width(mut self, width: Val) -> Self {
43 self.width = width;
44 self
45 }
46
47 pub fn height(mut self, height: Val) -> Self {
49 if let Val::Px(px) = height {
50 self.height = Some(px);
51 }
52 self
53 }
54
55 pub fn margin(mut self, margin: UiRect) -> Self {
56 self.margin = margin;
57 self
58 }
59
60 pub fn track_color(mut self, color: Color) -> Self {
62 self.track_color = Some(color);
63 self
64 }
65
66 pub fn fill_color(mut self, color: Color) -> Self {
68 self.fill_color = Some(color);
69 self
70 }
71
72 pub fn with_label(mut self) -> Self {
74 self.show_label = true;
75 self
76 }
77
78 pub fn with_label_text(mut self, text: impl Into<String>) -> Self {
80 self.custom_label = Some(text.into());
81 self.show_label = true;
82 self
83 }
84
85 pub fn animated(mut self) -> Self {
87 self.animated = true;
88 self
89 }
90
91 pub fn build(self, parent: &mut ChildSpawnerCommands) -> Entity {
92 let height = Val::Px(self.height.unwrap_or_else(|| self.style.height()));
93 let track_color = self.track_color.unwrap_or_else(|| self.style.track_color());
94 let fill_color = self.fill_color.unwrap_or_else(|| self.style.fill_color());
95
96 parent
97 .spawn((
98 Node {
99 width: self.width,
100 flex_direction: FlexDirection::Column,
101 margin: self.margin,
102 ..default()
103 },
104 BackgroundColor(Color::NONE),
105 ))
106 .with_children(|container| {
107 container
109 .spawn((
110 Node {
111 width: Val::Percent(100.0),
112 height,
113 position_type: PositionType::Relative,
114 overflow: Overflow::clip(),
115 ..default()
116 },
117 BackgroundColor(track_color),
118 BorderRadius::all(Val::Px(2.0)),
119 ProgressBarTrack,
120 ))
121 .with_children(|track| {
122 track.spawn((
124 Node {
125 width: Val::Percent(self.value * 100.0),
126 height: Val::Percent(100.0),
127 position_type: PositionType::Absolute,
128 left: Val::Px(0.0),
129 top: Val::Px(0.0),
130 ..default()
131 },
132 BackgroundColor(fill_color),
133 BorderRadius::all(Val::Px(2.0)),
134 ProgressBarFill,
135 ));
136 });
137
138 if self.show_label {
140 let label_text = self
141 .custom_label
142 .unwrap_or_else(|| format!("{}%", (self.value * 100.0) as i32));
143
144 container
145 .spawn((
146 Node {
147 margin: UiRect::top(Val::Px(4.0)),
148 justify_content: JustifyContent::Center,
149 ..default()
150 },
151 BackgroundColor(Color::NONE),
152 ))
153 .with_children(|label_container| {
154 label_container.spawn((
155 Text::new(label_text),
156 TextFont {
157 font_size: dimensions::FONT_SIZE_SMALL,
158 ..default()
159 },
160 TextColor(colors::TEXT_MUTED),
161 ProgressBarLabel,
162 ));
163 });
164 }
165 })
166 .insert(ProgressBar {
167 value: self.value,
168 style: self.style,
169 animated: self.animated,
170 })
171 .id()
172 }
173}
174
175pub fn progress(value: f32) -> ProgressBarBuilder {
177 ProgressBarBuilder::new(value)
178}