1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
//! Configuration of a progress bar.
//!
//! This is used to configure the progress bar.
use bevy::prelude::*;
use super::{BarState, ColorScheme, Percentage};
/// Configuration of a progress bar.
#[derive(Component, Debug, Clone)]
#[allow(clippy::module_name_repetitions)]
pub struct ProgressBarConfig<T: Percentage + Component> {
/// The color scheme to use for the progress bar.
pub color_scheme: ColorScheme,
/// The size of the progress bar.
///
/// This is the size to draw the background for the bar, and the foreground bar will be drawn inside of this. At
/// full, the foreground bar will be the same size as the background bar.
pub size: Vec2,
/// The relative position of the progress bar to the entity it will be attached to.
///
/// This is relative to the [`Transform.translation`] of the entity.
pub position_translation: Vec3,
_marker: std::marker::PhantomData<T>,
}
impl<T: Percentage + Component> Default for ProgressBarConfig<T> {
fn default() -> Self {
Self {
color_scheme: ColorScheme::default(),
size: Vec2::new(100.0, 10.0),
position_translation: Vec3::new(0.0, 0.0, 0.0),
_marker: std::marker::PhantomData,
}
}
}
impl<T: Percentage + Component> ProgressBarConfig<T> {
/// The shift of the background bar (in the z-axis) relative to the entity's translation.
pub const BACKGROUND_BAR_SHIFT: f32 = 1.0;
/// The shift of the foreground bar (in the z-axis) relative to the background bar.
pub const FOREGROUND_BAR_SHIFT: f32 = 0.1;
/// Create a new progress bar config with the given color scheme.
#[must_use]
pub fn new(color_scheme: ColorScheme) -> Self {
Self {
color_scheme,
..Default::default()
}
}
/// Update the progress bar config with the given color scheme.
#[must_use]
pub const fn with_color_scheme(mut self, color_scheme: ColorScheme) -> Self {
self.color_scheme = color_scheme;
self
}
/// Update the progress bar's color scheme with the given background color.
#[must_use]
pub const fn with_background_color(mut self, color: Color) -> Self {
self.color_scheme.background = color;
self
}
/// Update the progress bar's color scheme with the given color for the given state.
#[must_use]
pub fn with_color(mut self, state: &BarState, color: Color) -> Self {
self.color_scheme.set_color(state, color);
self
}
/// Update the progress bar's color scheme with the given moderate cutoff.
#[must_use]
pub fn with_moderate_cutoff(mut self, cutoff: f32) -> Self {
self.color_scheme.set_moderate_cutoff(cutoff);
self
}
/// Update the progress bar's color scheme with the given critical cutoff.
#[must_use]
pub fn with_critical_cutoff(mut self, cutoff: f32) -> Self {
self.color_scheme.set_critical_cutoff(cutoff);
self
}
/// Update the progress bar to use a single color for all states.
#[must_use]
pub fn with_single_color(mut self, color: Color) -> Self {
self.color_scheme.set_single_color(color);
self
}
/// Update the progress bar's size.
#[must_use]
pub const fn with_size(mut self, size: Vec2) -> Self {
self.size = size;
self
}
/// Update the progress bar's relative position.
#[must_use]
pub const fn with_position_translation(mut self, position_translation: Vec3) -> Self {
self.position_translation = position_translation;
self
}
/// Set the size of the progress bar.
pub fn set_size(&mut self, size: Vec2) {
self.size = size;
}
/// Set the relative position of the progress bar.
pub fn set_position_translation(&mut self, position_translation: Vec3) {
self.position_translation = position_translation;
}
/// Set the color scheme of the progress bar.
pub fn set_color_scheme(&mut self, color_scheme: ColorScheme) {
self.color_scheme = color_scheme;
}
/// Get the background color.
#[must_use]
pub const fn background_color(&self) -> Color {
self.color_scheme.background
}
/// Get the foreground color for the given T.
#[must_use]
pub fn color(&self, percentage: &T) -> Color {
self.color_scheme.get_color(percentage)
}
/// Get the realized [`Transform`] for the progress bar background.
///
/// This adjusts the translation of the background to be relative to the entity's translation.
#[must_use]
pub fn background_transform(&self, entity_transform: &Transform) -> Transform {
let mut transform = *entity_transform;
transform.translation += self.position_translation;
// Center the bar on the entity's translation
transform.translation.x += self.size.x / 2.0;
// Draw the background bar behind the foreground bar
transform.translation.z += Self::BACKGROUND_BAR_SHIFT;
transform
}
/// Get the realized [`Transform`] for the progress bar foreground.
///
/// This adjusts the translation of the foreground to be relative to the entity's translation. It also adjusts the
/// translation of the foreground to be centered on the entity's translation.
#[must_use]
pub fn foreground_transform(&self, entity_transform: &Transform, percentage: &T) -> Transform {
let mut transform = *entity_transform;
// Adjust position to be relative to the entity's translation
transform.translation += self.position_translation;
// Center the bar on the entity's translation
transform.translation.x += self.size.x * percentage.percentage() / 2.0;
// Draw the foreground bar in front of the background bar
transform.translation.z += Self::FOREGROUND_BAR_SHIFT + Self::BACKGROUND_BAR_SHIFT;
transform
}
/// Get the mesh for the progress bar background.
///
/// This is a [`Quad`] with the size of the progress bar.
#[must_use]
pub fn background_mesh(&self) -> Mesh {
shape::Quad::new(self.size).into()
}
/// Get the mesh for the progress bar foreground.
///
/// This is a [`Quad`] with the size of the progress bar foreground, which is the size of the progress
/// bar background scaled by the percentage.
#[must_use]
pub fn foreground_mesh(&self, percentage: &T) -> Mesh {
shape::Quad::new(Vec2::new(
self.size.x * percentage.percentage(),
self.size.y,
))
.into()
}
/// Get the current [`BarState`] for the given percentage.
#[must_use]
pub fn get_state(&self, percentage: &T) -> BarState {
self.color_scheme
.cutoffs()
.get_state(percentage.percentage())
}
/// Get the color for the given [`BarState`].
#[must_use]
pub const fn color_for_state(&self, state: &BarState) -> Color {
self.color_scheme.bar.get_state(state)
}
}