firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

fw16-epd-main: testing scratchpad

+168 -34
+38 -2
fw16-epd-gui/src/element/button.rs
··· 2 2 use embedded_graphics::prelude::*; 3 3 use embedded_graphics::mono_font::MonoTextStyle; 4 4 use embedded_graphics::pixelcolor::BinaryColor; 5 - use embedded_graphics::primitives::{PrimitiveStyle, Rectangle, RoundedRectangle}; 5 + use embedded_graphics::primitives::{CornerRadii, PrimitiveStyle, Rectangle, RoundedRectangle}; 6 6 use embedded_graphics::text::{Alignment, Baseline, Text, TextStyle, TextStyleBuilder}; 7 + use embedded_graphics::text::renderer::TextRenderer; 7 8 use fw16_epd_program_interface::{TouchEvent, TouchEventType}; 8 9 use crate::draw_target::EpdDrawTarget; 9 - use crate::element::GuiElement; 10 + use crate::element::{GuiElement, DEFAULT_PRIMITIVE_STYLE, DEFAULT_TEXT_STYLE}; 10 11 11 12 const CENTRE_STYLE: TextStyle = TextStyleBuilder::new() 12 13 .alignment(Alignment::Center) ··· 43 44 } 44 45 } 45 46 47 + pub fn auto_sized(top_left: Point, corner_radii: CornerRadii, label: &'a str, rect_style: PrimitiveStyle<BinaryColor>, char_style: MonoTextStyle<'a, BinaryColor>) -> Self { 48 + let size = Size::new((char_style.font.character_size.width + char_style.font.character_spacing) * (label.len() as u32 + 1), char_style.line_height()); 49 + Self { 50 + rect: RoundedRectangle::new(Rectangle::new(top_left, size), corner_radii), 51 + label, 52 + rect_style, 53 + char_style, 54 + click_state: ClickState::None, 55 + } 56 + } 57 + 58 + pub fn with_default_style(rect: Rectangle, label: &'a str) -> Self { 59 + Self { 60 + rect: RoundedRectangle::new(rect, CornerRadii::new(Size::new(3, 3))), 61 + label, 62 + rect_style: DEFAULT_PRIMITIVE_STYLE, 63 + char_style: DEFAULT_TEXT_STYLE, 64 + click_state: ClickState::None, 65 + } 66 + } 67 + 68 + pub fn with_default_style_auto_sized(top_left: Point, label: &'a str) -> Self { 69 + Self::auto_sized( 70 + top_left, 71 + CornerRadii::new(Size::new(3, 3)), 72 + label, 73 + DEFAULT_PRIMITIVE_STYLE, 74 + DEFAULT_TEXT_STYLE 75 + ) 76 + } 77 + 46 78 pub fn clicked(&mut self, clear: bool) -> bool { 47 79 if self.click_state == ClickState::Clicked { 48 80 if clear { ··· 53 85 } else { 54 86 false 55 87 } 88 + } 89 + 90 + pub fn rect(&self) -> Rectangle { 91 + self.rect.bounding_box() 56 92 } 57 93 } 58 94
+10
fw16-epd-gui/src/element/mod.rs
··· 1 1 pub mod button; 2 2 3 + use embedded_graphics::mono_font::ascii::FONT_10X20; 4 + use embedded_graphics::mono_font::MonoTextStyle; 3 5 use embedded_graphics::pixelcolor::BinaryColor; 4 6 use embedded_graphics::prelude::*; 7 + use embedded_graphics::primitives::{PrimitiveStyle, PrimitiveStyleBuilder}; 5 8 use fw16_epd_program_interface::TouchEvent; 6 9 use crate::draw_target::EpdDrawTarget; 10 + 11 + pub const DEFAULT_PRIMITIVE_STYLE: PrimitiveStyle<BinaryColor> = PrimitiveStyleBuilder::new() 12 + .stroke_width(2) 13 + .stroke_color(BinaryColor::On) 14 + .fill_color(BinaryColor::Off) 15 + .build(); 16 + pub const DEFAULT_TEXT_STYLE: MonoTextStyle<BinaryColor> = MonoTextStyle::new(&FONT_10X20, BinaryColor::On); 7 17 8 18 pub trait GuiElement { 9 19 fn draw_element(&self, target: &mut EpdDrawTarget);
+120 -32
fw16-epd-main/src/gui.rs
··· 1 - use core::fmt::Write; 2 1 use defmt::debug; 3 - use embedded_graphics::mono_font::ascii::FONT_10X20; 4 - use embedded_graphics::mono_font::MonoTextStyle; 2 + use embedded_graphics::geometry::AnchorPoint; 5 3 use embedded_graphics::pixelcolor::BinaryColor; 6 4 use embedded_graphics::prelude::*; 7 - use embedded_graphics::primitives::{PrimitiveStyle, Rectangle, RoundedRectangle}; 8 - use embedded_graphics::text::Text; 9 - use heapless::String; 5 + use embedded_graphics::primitives::Line; 10 6 use fw16_epd_gui::draw_target::EpdDrawTarget; 11 7 use fw16_epd_gui::element::button::Button; 12 - use fw16_epd_gui::element::GuiElement; 8 + use fw16_epd_gui::element::{GuiElement, DEFAULT_PRIMITIVE_STYLE}; 9 + use fw16_epd_program_interface::{SafeOption, TouchEvent, TouchEventType}; 13 10 use crate::{next_touch_event, set_touch_enabled}; 14 11 15 - pub(crate) fn gui_main(mut draw_target: EpdDrawTarget) -> ! { 16 - debug!("gui_main"); 12 + struct MainPage { 13 + scratchpad_button: Button<'static>, 14 + } 17 15 18 - draw_target.refresh(false, true); 16 + impl MainPage { 17 + fn new() -> Self { 18 + Self { 19 + scratchpad_button: Button::with_default_style_auto_sized(Point::new(10, 10), "Scratchpad"), 20 + } 21 + } 22 + } 19 23 20 - unsafe { set_touch_enabled(true) }; 24 + impl GuiElement for MainPage { 25 + fn draw_element(&self, target: &mut EpdDrawTarget) { 26 + self.scratchpad_button.draw_element(target); 27 + } 21 28 22 - let mut button = Button::new( 23 - RoundedRectangle::with_equal_corners(Rectangle::new(Point::new(10, 40), Size::new(100, 20)), Size::new(3, 3)), 24 - "Click me", 25 - PrimitiveStyle::with_stroke(BinaryColor::On, 2), 26 - MonoTextStyle::new(&FONT_10X20, BinaryColor::On) 27 - ); 28 - button.draw_element(&mut draw_target); 29 - draw_target.refresh(true, false); 29 + fn handle_touch(&mut self, ev: TouchEvent) { 30 + self.scratchpad_button.handle_touch(ev); 31 + } 32 + } 30 33 31 - let mut counter = 0; 34 + struct ScratchpadPage { 35 + exit_button: Button<'static>, 36 + clear_button: Button<'static>, 37 + prev_pos: Option<Point>, 38 + } 32 39 33 - loop { 34 - while let Some(ev) = next_touch_event().into() { 35 - button.handle_touch(ev); 40 + impl ScratchpadPage { 41 + fn new() -> Self { 42 + let exit_button = Button::with_default_style_auto_sized(Point::new(10, 416 - 10 - 20), "Exit"); 43 + let next_pos = exit_button 44 + .rect() 45 + .translate(Point::new(10, 0)) 46 + .anchor_point(AnchorPoint::TopRight); 47 + let clear_button = Button::with_default_style_auto_sized(next_pos, "Clear"); 48 + 49 + Self { 50 + exit_button, 51 + clear_button, 52 + prev_pos: None, 36 53 } 54 + } 55 + } 37 56 38 - if button.clicked(true) { 39 - counter += 1; 57 + impl GuiElement for ScratchpadPage { 58 + fn draw_element(&self, target: &mut EpdDrawTarget) { 59 + self.exit_button.draw_element(target); 60 + self.clear_button.draw_element(target); 61 + } 40 62 41 - let mut s = String::<10>::new(); 42 - write!(s, "{counter}").unwrap(); 63 + fn handle_touch(&mut self, ev: TouchEvent) { 64 + self.exit_button.handle_touch(ev); 65 + self.clear_button.handle_touch(ev); 66 + if matches!(ev.ev_type, TouchEventType::Down | TouchEventType::Move) { 67 + self.prev_pos = Some(ev.eg_point()); 68 + } 69 + } 70 + } 43 71 44 - draw_target.clear(BinaryColor::Off).unwrap(); 45 - button.draw_element(&mut draw_target); 72 + enum Gui { 73 + MainPage(MainPage), 74 + ScratchpadPage(ScratchpadPage), 75 + } 46 76 47 - Text::new(&s, Point::new(10, 80), MonoTextStyle::new(&FONT_10X20, BinaryColor::On)) 48 - .draw_element(&mut draw_target); 49 - draw_target.refresh(true, false); 77 + impl Gui { 78 + fn tick(&mut self, target: &mut EpdDrawTarget, ev: TouchEvent) { 79 + match self { 80 + Gui::MainPage(page) => { 81 + page.handle_touch(ev); 82 + 83 + if page.scratchpad_button.clicked(true) { 84 + let scratchpad = ScratchpadPage::new(); 85 + target.clear(BinaryColor::Off).unwrap(); 86 + scratchpad.draw_element(target); 87 + target.refresh(false, true); 88 + *self = Gui::ScratchpadPage(scratchpad); 89 + return; 90 + } 91 + } 92 + 93 + Gui::ScratchpadPage(page) => { 94 + if matches!(ev.ev_type, TouchEventType::Move | TouchEventType::Up) { 95 + if let Some(prev) = page.prev_pos { 96 + Line::new(prev, ev.eg_point()) 97 + .into_styled(DEFAULT_PRIMITIVE_STYLE) 98 + .draw(target) 99 + .unwrap(); 100 + page.draw_element(target); 101 + target.refresh(true, false); 102 + } 103 + } 104 + 105 + page.handle_touch(ev); 106 + 107 + if page.exit_button.clicked(true) { 108 + let main = MainPage::new(); 109 + target.clear(BinaryColor::Off).unwrap(); 110 + main.draw_element(target); 111 + target.refresh(false, true); 112 + *self = Gui::MainPage(main); 113 + return; 114 + } 115 + 116 + if page.clear_button.clicked(true) { 117 + target.clear(BinaryColor::Off).unwrap(); 118 + page.draw_element(target); 119 + target.refresh(false, false); 120 + } 121 + } 122 + } 123 + } 124 + } 125 + 126 + pub(crate) fn gui_main(mut draw_target: EpdDrawTarget) -> ! { 127 + debug!("gui_main"); 128 + 129 + unsafe { set_touch_enabled(true) }; 130 + let main = MainPage::new(); 131 + main.draw_element(&mut draw_target); 132 + draw_target.refresh(false, true); 133 + let mut gui = Gui::MainPage(main); 134 + 135 + loop { 136 + while let SafeOption::Some(ev) = next_touch_event() { 137 + gui.tick(&mut draw_target, ev); 50 138 } 51 139 } 52 140 }