eg_seven_segment/
digit.rs

1use embedded_graphics::{
2    geometry::AnchorPoint,
3    prelude::*,
4    primitives::{Rectangle, Styled, StyledDrawable},
5};
6
7use crate::{segment::Segment, Segments, SevenSegmentStyle};
8
9/// Single digit drawable.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub struct Digit {
12    segments: Segments,
13    position: Point,
14}
15
16impl Digit {
17    /// Creates a new digit.
18    pub fn new(segments: Segments, position: Point) -> Self {
19        Self { segments, position }
20    }
21
22    /// Applies a style to this digit.
23    pub fn into_styled<C: PixelColor>(
24        self,
25        style: SevenSegmentStyle<C>,
26    ) -> Styled<Self, SevenSegmentStyle<C>> {
27        Styled {
28            primitive: self,
29            style,
30        }
31    }
32}
33
34impl<C: PixelColor> StyledDrawable<SevenSegmentStyle<C>> for Digit {
35    type Color = C;
36    type Output = Point;
37
38    fn draw_styled<D>(
39        &self,
40        style: &SevenSegmentStyle<C>,
41        target: &mut D,
42    ) -> Result<Self::Output, D::Error>
43    where
44        D: DrawTarget<Color = Self::Color>,
45    {
46        let rect = Rectangle::new(self.position, style.digit_size);
47
48        let vertical_size = Size::new(style.digit_size.width, style.segment_width);
49        let horizontal_size_top = Size::new(
50            style.segment_width,
51            (style.digit_size.height + style.segment_width) / 2,
52        );
53        let horizontal_size_bottom = Size::new(
54            style.segment_width,
55            (style.digit_size.height + style.segment_width + 1) / 2,
56        );
57
58        if let Some(color) = style.state_color(self.segments.contains(Segments::A)) {
59            Segment::with_reduced_size(rect.resized(vertical_size, AnchorPoint::TopLeft), color)
60                .draw(target)?;
61        }
62
63        if let Some(color) = style.state_color(self.segments.contains(Segments::B)) {
64            Segment::with_reduced_size(
65                rect.resized(horizontal_size_top, AnchorPoint::TopRight),
66                color,
67            )
68            .draw(target)?;
69        }
70
71        if let Some(color) = style.state_color(self.segments.contains(Segments::C)) {
72            Segment::with_reduced_size(
73                rect.resized(horizontal_size_bottom, AnchorPoint::BottomRight),
74                color,
75            )
76            .draw(target)?;
77        }
78
79        if let Some(color) = style.state_color(self.segments.contains(Segments::D)) {
80            Segment::with_reduced_size(rect.resized(vertical_size, AnchorPoint::BottomLeft), color)
81                .draw(target)?;
82        }
83
84        if let Some(color) = style.state_color(self.segments.contains(Segments::E)) {
85            Segment::with_reduced_size(
86                rect.resized(horizontal_size_bottom, AnchorPoint::BottomLeft),
87                color,
88            )
89            .draw(target)?;
90        }
91
92        if let Some(color) = style.state_color(self.segments.contains(Segments::F)) {
93            Segment::with_reduced_size(
94                rect.resized(horizontal_size_top, AnchorPoint::TopLeft),
95                color,
96            )
97            .draw(target)?;
98        }
99
100        if let Some(color) = style.state_color(self.segments.contains(Segments::G)) {
101            Segment::with_reduced_size(rect.resized(vertical_size, AnchorPoint::CenterLeft), color)
102                .draw(target)?;
103        }
104
105        Ok(self.position + style.digit_size.x_axis() + Size::new(style.digit_spacing, 0))
106    }
107}