bevy_ui_builders/slider/
types.rs

1//! Slider types and components
2
3use bevy::prelude::*;
4use crate::styles::colors;
5
6/// Main slider component with configuration and state
7#[derive(Component, Clone, Debug)]
8pub struct Slider {
9    pub value: f32,
10    pub min: f32,
11    pub max: f32,
12    pub step: Option<f32>,
13    /// Entity ID of the associated value text display (if any)
14    pub value_text_entity: Option<Entity>,
15}
16
17impl Slider {
18    pub fn new(min: f32, max: f32, value: f32) -> Self {
19        Self {
20            value: value.clamp(min, max),
21            min,
22            max,
23            step: None,
24            value_text_entity: None,
25        }
26    }
27
28    /// Get normalized value (0.0 to 1.0)
29    pub fn normalized(&self) -> f32 {
30        if self.max == self.min {
31            return 0.0;
32        }
33        ((self.value - self.min) / (self.max - self.min)).clamp(0.0, 1.0)
34    }
35
36    /// Set value from normalized (0.0 to 1.0)
37    pub fn set_normalized(&mut self, normalized: f32) {
38        let normalized = normalized.clamp(0.0, 1.0);
39        self.value = self.min + (self.max - self.min) * normalized;
40
41        // Apply step if configured
42        if let Some(step) = self.step {
43            let steps = ((self.value - self.min) / step).round();
44            self.value = self.min + steps * step;
45        }
46
47        self.value = self.value.clamp(self.min, self.max);
48    }
49}
50
51/// Marker for the draggable handle
52#[derive(Component)]
53pub struct SliderHandle;
54
55/// Component for increment/decrement buttons
56#[derive(Component)]
57pub struct SliderButtonAction {
58    pub slider_entity: Entity,
59    pub delta: f32,
60}
61
62/// Component for the slider track (clickable area)
63#[derive(Component)]
64pub struct SliderTrack;
65
66/// Component for the filled portion of the slider
67#[derive(Component)]
68pub struct SliderFill;
69
70/// Component for the value text display
71#[derive(Component)]
72pub struct SliderValueText;
73
74/// Component for the label text
75#[derive(Component)]
76pub struct SliderLabel;
77
78/// Configuration for how the value is displayed
79#[derive(Clone, Debug)]
80pub enum ValueFormat {
81    /// Display as integer
82    Integer,
83    /// Display with fixed decimal places
84    Decimal(usize),
85    /// Display as percentage
86    Percentage,
87    /// Custom formatter function
88    Custom(fn(f32) -> String),
89}
90
91impl ValueFormat {
92    /// Format a value according to this format
93    pub fn format(&self, value: f32) -> String {
94        match self {
95            ValueFormat::Integer => format!("{}", value as i32),
96            ValueFormat::Decimal(places) => format!("{:.precision$}", value, precision = places),
97            ValueFormat::Percentage => format!("{}%", (value * 100.0) as i32),
98            ValueFormat::Custom(formatter) => formatter(value),
99        }
100    }
101}
102
103/// Configuration for slider appearance
104#[derive(Component, Clone, Debug)]
105pub struct SliderConfig {
106    pub show_value: bool,
107    pub value_format: ValueFormat,
108    pub track_height: f32,
109    pub handle_size: f32,
110    pub track_color: Color,
111    pub fill_color: Color,
112    pub handle_color: Color,
113}
114
115impl Default for SliderConfig {
116    fn default() -> Self {
117        Self {
118            show_value: true,
119            value_format: ValueFormat::Decimal(1),
120            track_height: 6.0,
121            handle_size: 16.0,
122            track_color: colors::BACKGROUND_TERTIARY,
123            fill_color: colors::PRIMARY.with_alpha(0.3),
124            handle_color: colors::PRIMARY,
125        }
126    }
127}