100 lines
2.7 KiB
Rust
100 lines
2.7 KiB
Rust
use arrayvec::ArrayString;
|
|
|
|
use embedded_graphics::{
|
|
draw_target::DrawTarget,
|
|
mono_font::{ascii::FONT_6X9, MonoTextStyle, MonoTextStyleBuilder},
|
|
pixelcolor::BinaryColor,
|
|
prelude::*,
|
|
primitives::{Circle, PrimitiveStyle},
|
|
text::{Baseline, Text},
|
|
};
|
|
|
|
use core::fmt::Write;
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub enum HelloEvent {
|
|
Tick,
|
|
Knob(i32),
|
|
Button,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct HelloDisplay<const W: i32, const H: i32> {
|
|
circle_pos: (i32, i32),
|
|
counter: i32,
|
|
textbuf: ArrayString<15>,
|
|
text_style: MonoTextStyle<'static, BinaryColor>,
|
|
title: Text<'static, MonoTextStyle<'static, BinaryColor>>,
|
|
}
|
|
|
|
impl<const W: i32, const H: i32> HelloDisplay<W, H> {
|
|
const C_RADIUS: i32 = 8;
|
|
|
|
/// Construct a new HelloDisplay
|
|
pub fn new() -> Self {
|
|
let text_style = MonoTextStyleBuilder::new()
|
|
.font(&FONT_6X9)
|
|
.text_color(BinaryColor::On)
|
|
.build();
|
|
let title =
|
|
Text::with_baseline("Hello Rust!", Point::new(20, 16), text_style, Baseline::Top);
|
|
Self {
|
|
circle_pos: (0, 0),
|
|
counter: 0,
|
|
textbuf: ArrayString::new(),
|
|
text_style,
|
|
title,
|
|
}
|
|
}
|
|
|
|
/// Draw the current state of HelloDisplay onto the DrawTarget
|
|
pub fn draw<D>(&mut self, target: &mut D) -> Result<(), D::Error>
|
|
where
|
|
D: DrawTarget<Color = BinaryColor>,
|
|
{
|
|
let (cx, cy) = self.circle_pos;
|
|
let circle = Circle::new(Point::new(cx, cy), Self::C_RADIUS as u32)
|
|
.into_styled(PrimitiveStyle::with_fill(BinaryColor::On));
|
|
|
|
self.textbuf.clear();
|
|
write!(&mut self.textbuf, "count: {}", self.counter).unwrap();
|
|
let count = Text::with_baseline(
|
|
&self.textbuf,
|
|
Point::new(20, 36),
|
|
self.text_style,
|
|
Baseline::Top,
|
|
);
|
|
|
|
target.clear(BinaryColor::Off)?;
|
|
|
|
self.title.draw(target)?;
|
|
circle.draw(target)?;
|
|
count.draw(target)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Update the current state of HelloDisplay based on an event
|
|
pub fn event(&mut self, event: HelloEvent) {
|
|
match event {
|
|
HelloEvent::Tick => {
|
|
let (_, cy) = self.circle_pos;
|
|
let cx_next = self
|
|
.counter
|
|
.max(Self::C_RADIUS / 2)
|
|
.min(W - Self::C_RADIUS / 2);
|
|
let mut cy_next = cy + 1;
|
|
if cy_next > (H + Self::C_RADIUS) {
|
|
cy_next = -Self::C_RADIUS
|
|
};
|
|
|
|
self.circle_pos = (cx_next, cy_next);
|
|
}
|
|
HelloEvent::Knob(pos_delta) => {
|
|
self.counter = self.counter + pos_delta;
|
|
}
|
|
HelloEvent::Button => {}
|
|
}
|
|
}
|
|
}
|