embedded_menu/selection_indicator/style/
rectangle.rs

1use embedded_graphics::{
2    prelude::DrawTarget,
3    primitives::{Primitive, PrimitiveStyle, Rectangle as RectangleShape},
4    Drawable,
5};
6
7use crate::{
8    interaction::InputState,
9    selection_indicator::{
10        style::{interpolate, IndicatorStyle},
11        Insets,
12    },
13    theme::Theme,
14};
15
16#[derive(Clone, Copy)]
17pub struct Rectangle;
18
19impl IndicatorStyle for Rectangle {
20    type Shape = RectangleShape;
21    type State = ();
22
23    fn padding(&self, _state: &Self::State, _height: i32) -> Insets {
24        Insets {
25            left: 2,
26            top: 0,
27            right: 0,
28            bottom: 0,
29        }
30    }
31
32    fn shape(&self, _state: &Self::State, bounds: RectangleShape, _fill_width: u32) -> Self::Shape {
33        bounds
34    }
35
36    fn draw<T, D>(
37        &self,
38        state: &Self::State,
39        input_state: InputState,
40        theme: &T,
41        display: &mut D,
42    ) -> Result<Self::Shape, D::Error>
43    where
44        T: Theme,
45        D: DrawTarget<Color = T::Color>,
46    {
47        let display_area = display.bounding_box();
48
49        let fill_width = if let InputState::InProgress(progress) = input_state {
50            interpolate(progress as u32, 0, 255, 0, display_area.size.width)
51        } else {
52            0
53        };
54
55        let shape = self.shape(state, display_area, fill_width);
56
57        shape
58            .into_styled(PrimitiveStyle::with_fill(theme.selection_color()))
59            .draw(display)?;
60
61        Ok(shape)
62    }
63}