embedded_menu/selection_indicator/style/
mod.rs

1use embedded_graphics::{
2    prelude::DrawTarget,
3    primitives::{ContainsPoint, Rectangle},
4    transform::Transform,
5};
6
7use crate::{interaction::InputState, selection_indicator::Insets, theme::Theme};
8
9pub mod animated_triangle;
10pub mod border;
11pub mod line;
12pub mod rectangle;
13pub mod triangle;
14
15// Re-export the styles themselves to make them easier to use.
16pub use animated_triangle::AnimatedTriangle;
17pub use border::Border;
18pub use line::Line;
19pub use triangle::Triangle;
20
21pub fn interpolate(value: u32, x_min: u32, x_max: u32, y_min: u32, y_max: u32) -> u32 {
22    let x_range = x_max - x_min;
23    let y_range = y_max - y_min;
24
25    if x_range == 0 {
26        y_min
27    } else {
28        let x = value - x_min;
29        let y = x * y_range / x_range;
30
31        y + y_min
32    }
33}
34
35pub trait IndicatorStyle: Copy {
36    type Shape: ContainsPoint + Transform + Clone;
37    type State: Default + Copy;
38
39    fn on_target_changed(&self, _state: &mut Self::State) {}
40    fn update(&self, _state: &mut Self::State, _input_state: InputState) {}
41    fn padding(&self, state: &Self::State, height: i32) -> Insets;
42    fn shape(&self, state: &Self::State, bounds: Rectangle, fill_width: u32) -> Self::Shape;
43    fn draw<T, D>(
44        &self,
45        state: &Self::State,
46        input_state: InputState,
47        theme: &T,
48        display: &mut D,
49    ) -> Result<Self::Shape, D::Error>
50    where
51        T: Theme,
52        D: DrawTarget<Color = T::Color>;
53}
54
55#[test]
56fn interpolate_basic() {
57    assert_eq!(interpolate(0, 0, 100, 0, 100), 0);
58    assert_eq!(interpolate(50, 0, 100, 0, 100), 50);
59    assert_eq!(interpolate(100, 0, 100, 0, 100), 100);
60    assert_eq!(interpolate(100, 0, 10, 0, 100), 1000);
61}