iris_ui/
device.rs

1use crate::geom::{Bounds, Point as GPoint};
2use crate::gfx::{DrawingContext, TextStyle};
3use crate::view::Align;
4use core::ops::Add;
5use embedded_graphics::Drawable;
6use embedded_graphics::draw_target::DrawTargetExt;
7use embedded_graphics::geometry::{Point as EPoint, Size as ESize};
8use embedded_graphics::mono_font::MonoTextStyleBuilder;
9use embedded_graphics::mono_font::ascii::FONT_6X10;
10use embedded_graphics::pixelcolor::Rgb565;
11use embedded_graphics::prelude::DrawTarget;
12use embedded_graphics::primitives::{Line, Primitive, PrimitiveStyle, Rectangle};
13use embedded_graphics::text::{Alignment, Baseline, Text, TextStyleBuilder};
14
15pub struct EmbeddedDrawingContext<'a, T>
16where
17    T: DrawTarget<Color = Rgb565>,
18{
19    pub display: &'a mut T,
20    pub clip: Bounds,
21    offset: EPoint,
22}
23
24impl<'a, T> EmbeddedDrawingContext<'a, T>
25where
26    T: DrawTarget<Color = Rgb565>,
27{
28    pub fn new(display: &'a mut T) -> Self {
29        EmbeddedDrawingContext {
30            display,
31            clip: Bounds::new_empty(),
32            offset: EPoint::new(0, 0),
33        }
34    }
35}
36
37fn bounds_to_rect(bounds: &Bounds) -> Rectangle {
38    Rectangle::new(
39        EPoint::new(bounds.position.x, bounds.position.y),
40        ESize::new(bounds.size.w as u32, bounds.size.h as u32),
41    )
42}
43
44impl<'a, T> DrawingContext for EmbeddedDrawingContext<'a, T>
45where
46    T: DrawTarget<Color = Rgb565>,
47{
48    fn fill_rect(&mut self, bounds: &Bounds, color: &Rgb565) {
49        let mut display = self.display.clipped(&bounds_to_rect(&self.clip));
50        let mut display = display.translated(self.offset);
51        bounds_to_rect(bounds)
52            .into_styled(PrimitiveStyle::with_fill(*color))
53            .draw(&mut display);
54    }
55    fn stroke_rect(&mut self, bounds: &Bounds, color: &Rgb565) {
56        let mut display = self.display.clipped(&bounds_to_rect(&self.clip));
57        let mut display = display.translated(self.offset);
58        bounds_to_rect(bounds)
59            .into_styled(PrimitiveStyle::with_stroke(*color, 1))
60            .draw(&mut display);
61    }
62    fn line(&mut self, start: &GPoint, end: &GPoint, color: &Rgb565) {
63        let mut display = self.display.clipped(&bounds_to_rect(&self.clip));
64        let mut display = display.translated(self.offset);
65        let line = Line::new(EPoint::new(start.x, start.y), EPoint::new(end.x, end.y));
66        line.into_styled(PrimitiveStyle::with_stroke(*color, 1))
67            .draw(&mut display);
68    }
69    fn fill_text(&mut self, bounds: &Bounds, text: &str, text_style: &TextStyle) {
70        let mut display = self.display.clipped(&bounds_to_rect(&self.clip));
71        let mut display = display.translated(self.offset);
72
73        let mut text_builder = MonoTextStyleBuilder::new()
74            .font(text_style.font)
75            .text_color(*text_style.color);
76        if text_style.underline {
77            text_builder = text_builder.underline();
78        }
79        let style = text_builder.build(); // MonoTextStyle::new(&FONT_6X10,  *text_style.color);
80        let mut pt = EPoint::new(bounds.position.x, bounds.position.y);
81        pt.y += bounds.size.h / 2;
82        pt.y += (FONT_6X10.baseline as i32) / 2;
83
84        let w = (FONT_6X10.character_size.width as i32) * (text.len() as i32);
85
86        match text_style.halign {
87            Align::Start => {
88                pt.x += 5;
89            }
90            Align::Center => {
91                pt.x += (bounds.size.w - w) / 2;
92            }
93            Align::End => {}
94        }
95
96        Text::new(text, pt, style).draw(&mut display);
97    }
98    fn text(&mut self, text: &str, position: &GPoint, style: &TextStyle) {
99        let mut display = self.display.clipped(&bounds_to_rect(&self.clip));
100        let mut display = display.translated(self.offset);
101        let mut pt = EPoint::new(position.x, position.y);
102        let mut text_builder = MonoTextStyleBuilder::new()
103            .font(style.font)
104            .text_color(*style.color);
105        if style.underline {
106            text_builder = text_builder.underline();
107        }
108        let estyle = text_builder.build();
109        let etext = Text {
110            position: pt,
111            text,
112            character_style: estyle,
113            text_style: TextStyleBuilder::new()
114                .alignment(Alignment::Center)
115                .baseline(Baseline::Middle)
116                .build(),
117        };
118        etext.draw(&mut display);
119    }
120    fn translate(&mut self, offset: &GPoint) {
121        self.offset = self.offset.add(EPoint::new(offset.x, offset.y));
122    }
123}