embedded_menu/selection_indicator/style/
line.rs

1use embedded_graphics::{
2    prelude::{DrawTarget, Size},
3    primitives::{Primitive, PrimitiveStyle, Rectangle},
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 Line;
18
19impl IndicatorStyle for Line {
20    type Shape = Rectangle;
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: Rectangle, fill_width: u32) -> Self::Shape {
33        Rectangle::new(
34            bounds.top_left,
35            Size::new(fill_width.max(1), bounds.size.height),
36        )
37    }
38
39    fn draw<T, D>(
40        &self,
41        state: &Self::State,
42        input_state: InputState,
43        theme: &T,
44        display: &mut D,
45    ) -> Result<Self::Shape, D::Error>
46    where
47        T: Theme,
48        D: DrawTarget<Color = T::Color>,
49    {
50        let display_area = display.bounding_box();
51
52        let fill_width = if let InputState::InProgress(progress) = input_state {
53            interpolate(progress as u32, 0, 255, 0, display_area.size.width)
54        } else {
55            0
56        };
57
58        let shape = self.shape(state, display_area, fill_width);
59
60        shape
61            .into_styled(PrimitiveStyle::with_fill(theme.selection_color()))
62            .draw(display)?;
63
64        Ok(shape)
65    }
66}