firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
1use embedded_graphics::prelude::*;
2use embedded_graphics::geometry::Point;
3use embedded_graphics::pixelcolor::BinaryColor;
4use embedded_graphics::primitives::{Circle, Line, PrimitiveStyle, Rectangle};
5use eepy_sys::input_common::{Event, TouchEventType};
6use crate::draw_target::EpdDrawTarget;
7use crate::element::{Gui, DEFAULT_PRIMITIVE_STYLE};
8
9pub struct Slider {
10 pub start_point: Point,
11 pub length: i32,
12 pub min: i32,
13 pub max: i32,
14 pub value: i32,
15
16 pub line_style: PrimitiveStyle<BinaryColor>,
17 pub marker_style: PrimitiveStyle<BinaryColor>,
18 pub marker_radius: i32,
19
20 sliding: bool,
21}
22
23impl Slider {
24 pub fn new(start_point: Point, length: i32, min: i32, max: i32, starting_value: i32, line_style: PrimitiveStyle<BinaryColor>, marker_style: PrimitiveStyle<BinaryColor>, marker_radius: i32) -> Self {
25 Self {
26 start_point,
27 length,
28 min,
29 max,
30 value: starting_value,
31
32 line_style,
33 marker_style,
34 marker_radius,
35
36 sliding: false,
37 }
38 }
39
40 pub fn with_default_style(start_point: Point, length: i32, min: i32, max: i32, starting_value: i32) -> Self {
41 Self {
42 start_point,
43 length,
44 min,
45 max,
46 value: starting_value,
47
48 line_style: DEFAULT_PRIMITIVE_STYLE,
49 marker_style: DEFAULT_PRIMITIVE_STYLE,
50 marker_radius: 9,
51
52 sliding: false,
53 }
54 }
55}
56
57impl Gui for Slider {
58 type Output = bool;
59
60 fn draw_init(&self, target: &mut EpdDrawTarget) {
61 target.fill_solid(&self.bounding_box(), BinaryColor::Off).unwrap();
62
63 Line::new(self.start_point, self.start_point + Point::new(self.length, 0))
64 .into_styled(self.line_style)
65 .draw(target)
66 .unwrap();
67
68 let x = self.start_point.x + (self.length * (self.value - self.min)) / (self.max - self.min);
69 let marker_point = Point::new(x, self.start_point.y);
70 Circle::with_center(marker_point, self.marker_radius as u32 * 2)
71 .into_styled(self.marker_style)
72 .draw(target)
73 .unwrap();
74 }
75
76 fn tick(&mut self, target: &mut EpdDrawTarget, ev: Event) -> bool {
77 if let Event::Touch(ev) = ev {
78 let p = ev.eg_point();
79
80 if self.bounding_box().contains(p) && ev.ev_type == TouchEventType::Down {
81 self.sliding = true;
82 } else if ev.ev_type == TouchEventType::Up {
83 self.sliding = false;
84 }
85
86 if self.sliding {
87 if p.x >= self.start_point.x && p.x <= (self.start_point.x + self.length) {
88 let xmin = self.start_point.x;
89 let xmax = xmin + self.length;
90
91 self.value = self.min + ((self.max - self.min) * (ev.eg_point().x - xmin)) / (xmax - xmin);
92 self.draw_init(target);
93 } else if p.x < self.start_point.x {
94 self.value = self.min;
95 self.draw_init(target);
96 } else {
97 self.value = self.max;
98 self.draw_init(target);
99 }
100
101 return true;
102 }
103 }
104
105 false
106 }
107
108 fn bounding_box(&self) -> Rectangle {
109 let real_radius = self.marker_radius + self.marker_style.stroke_width as i32;
110 let top_left = self.start_point + Point::new(-real_radius, -real_radius);
111 Rectangle::new(top_left, Size::new((self.length + 2 * real_radius) as u32, 2 * real_radius as u32))
112 }
113
114}