zest_widget/widget/
divider.rs1use super::Widget;
8use core::marker::PhantomData;
9use embedded_graphics::{pixelcolor::PixelColor, prelude::*, primitives::Rectangle};
10use zest_core::{Constraints, Length, RenderError, Renderer, TouchPhase};
11use zest_theme::Theme;
12
13pub struct Divider<C: PixelColor, M: Clone> {
17 rect: Rectangle,
18 width: Length,
19 height: Length,
20 color: Option<C>,
21 _phantom: PhantomData<M>,
22}
23
24impl<C: PixelColor, M: Clone> Divider<C, M> {
25 pub fn new(width: impl Into<Length>, height: impl Into<Length>) -> Self {
27 Self {
28 rect: Rectangle::zero(),
29 width: width.into(),
30 height: height.into(),
31 color: None,
32 _phantom: PhantomData,
33 }
34 }
35
36 #[must_use]
38 pub fn width(mut self, width: impl Into<Length>) -> Self {
39 self.width = width.into();
40 self
41 }
42
43 #[must_use]
45 pub fn height(mut self, height: impl Into<Length>) -> Self {
46 self.height = height.into();
47 self
48 }
49
50 #[must_use]
52 pub fn color(mut self, color: C) -> Self {
53 self.color = Some(color);
54 self
55 }
56
57 #[must_use]
61 pub fn thickness(self, thickness: u32) -> Self {
62 let thin_is_height = matches!(
63 (self.width, self.height),
64 (Length::Fill | Length::FillPortion(_), _),
65 );
66 if thin_is_height {
67 self.height(Length::Fixed(thickness))
68 } else {
69 self.width(Length::Fixed(thickness))
70 }
71 }
72}
73
74pub fn horizontal_divider<C: PixelColor, M: Clone>() -> Divider<C, M> {
76 Divider::new(Length::Fill, Length::Fixed(1))
77}
78
79pub fn vertical_divider<C: PixelColor, M: Clone>() -> Divider<C, M> {
81 Divider::new(Length::Fixed(1), Length::Fill)
82}
83
84impl<C: PixelColor, M: Clone> Widget<C, M> for Divider<C, M> {
85 fn measure(&mut self, constraints: Constraints) -> Size {
86 let w = self.width.resolve(1, constraints.max.width);
87 let h = self.height.resolve(1, constraints.max.height);
88 constraints.clamp(Size::new(w, h))
89 }
90
91 fn preferred_size(&self) -> (Length, Length) {
92 (self.width, self.height)
93 }
94
95 fn arrange(&mut self, rect: Rectangle) {
96 self.rect = rect;
97 }
98
99 fn rect(&self) -> Rectangle {
100 self.rect
101 }
102
103 fn handle_touch(&mut self, _point: Point, _phase: TouchPhase) -> Option<M> {
104 None
105 }
106
107 fn draw<'t>(
108 &self,
109 renderer: &mut dyn Renderer<C>,
110 theme: &Theme<'t, C>,
111 ) -> Result<(), RenderError> {
112 let color = self.color.unwrap_or(theme.background.divider);
113 renderer.fill_rect(self.rect, color)?;
114 Ok(())
115 }
116}