zest_widget/widget/
image.rs1use super::Widget;
9use core::marker::PhantomData;
10use embedded_graphics::{pixelcolor::PixelColor, prelude::*, primitives::Rectangle};
11use zest_core::{Constraints, Length, RenderError, Renderer, TouchPhase};
12use zest_theme::Theme;
13
14pub struct Image<'a, C: PixelColor, M: Clone> {
16 rect: Rectangle,
17 pixels: &'a [C],
18 image_size: Size,
19 width: Length,
20 height: Length,
21 _phantom: PhantomData<M>,
22}
23
24impl<'a, C: PixelColor, M: Clone> Image<'a, C, M> {
25 pub fn new(pixels: &'a [C], image_size: Size) -> Self {
29 Self {
30 rect: Rectangle::zero(),
31 pixels,
32 image_size,
33 width: Length::Shrink,
34 height: Length::Shrink,
35 _phantom: PhantomData,
36 }
37 }
38
39 #[must_use]
41 pub fn width(mut self, width: impl Into<Length>) -> Self {
42 self.width = width.into();
43 self
44 }
45
46 #[must_use]
48 pub fn height(mut self, height: impl Into<Length>) -> Self {
49 self.height = height.into();
50 self
51 }
52}
53
54impl<'a, C: PixelColor, M: Clone> Widget<C, M> for Image<'a, C, M> {
55 fn measure(&mut self, constraints: Constraints) -> Size {
56 let width = self
57 .width
58 .resolve(self.image_size.width, constraints.max.width);
59 let height = self
60 .height
61 .resolve(self.image_size.height, constraints.max.height);
62 constraints.clamp(Size::new(width, height))
63 }
64
65 fn preferred_size(&self) -> (Length, Length) {
66 (self.width, self.height)
67 }
68
69 fn arrange(&mut self, rect: Rectangle) {
70 self.rect = rect;
71 }
72
73 fn rect(&self) -> Rectangle {
74 self.rect
75 }
76
77 fn handle_touch(&mut self, _point: Point, _phase: TouchPhase) -> Option<M> {
78 None
79 }
80
81 fn draw<'t>(
82 &self,
83 renderer: &mut dyn Renderer<C>,
84 _theme: &Theme<'t, C>,
85 ) -> Result<(), RenderError> {
86 let dx = (self.rect.size.width as i32 - self.image_size.width as i32).max(0) / 2;
87 let dy = (self.rect.size.height as i32 - self.image_size.height as i32).max(0) / 2;
88 let origin = self.rect.top_left + Point::new(dx, dy);
89 renderer.draw_image(origin, self.image_size, self.pixels)
90 }
91}