Skip to content

Commit

Permalink
implement theme abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
BrendanBall committed Oct 30, 2023
1 parent 22300ac commit 15ad22a
Show file tree
Hide file tree
Showing 11 changed files with 497 additions and 55 deletions.
355 changes: 354 additions & 1 deletion Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[workspace]
members = [
"esp32c3_nostd"
"esp32c3_nostd",
"display_themes",
"airquamon_domain"
]

resolver = "2"
Expand Down
8 changes: 8 additions & 0 deletions airquamon_domain/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "airquamon_domain"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
7 changes: 7 additions & 0 deletions airquamon_domain/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![no_std]

pub struct Data {
pub co2: u16,
pub temperature: f32,
pub humidity: f32,
}
16 changes: 16 additions & 0 deletions display_themes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "display_themes"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
embedded-graphics = "0.8"
heapless = "0.7.16"
airquamon_domain = { path = "../airquamon_domain" }
epd-waveshare = { path = "/home/brendan/dev/projects/epd-waveshare" }

[dev-dependencies]
embedded-graphics-simulator = "0.5.0"
epd-waveshare = { path = "/home/brendan/dev/projects/epd-waveshare", features = ["graphics"] }
26 changes: 26 additions & 0 deletions display_themes/examples/simulate_theme_1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use embedded_graphics::prelude::*;
use embedded_graphics_simulator::{SimulatorDisplay, Window, OutputSettingsBuilder};
use epd_waveshare::color::TriColor;
use display_themes::{Theme, Theme1};
use airquamon_domain::Data;


fn main() -> Result<(), core::convert::Infallible> {
let mut display = SimulatorDisplay::<TriColor>::new(Size::new(296, 128));

let data = Data{
co2: 459,
temperature: 20.59,
humidity: 57.42,
};

let mut theme1 = Theme1::new();
theme1.draw(&data, &mut display).unwrap();

let output_settings = OutputSettingsBuilder::new()
.scale(2)
.build();
Window::new("Airquamon Simulator", &output_settings).show_static(&display);

Ok(())
}
14 changes: 14 additions & 0 deletions display_themes/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![no_std]

use airquamon_domain::Data;
use embedded_graphics::prelude::*;

mod theme_1;
pub use theme_1::Theme1;

pub trait Theme<COLOR>
where
COLOR: PixelColor,
{
fn draw<DRAWTARGET: DrawTarget<Color = COLOR>>(&mut self, data: &Data, display: &mut DRAWTARGET) -> Result<(), DRAWTARGET::Error>;
}
51 changes: 51 additions & 0 deletions display_themes/src/theme_1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::Theme;
use airquamon_domain::Data;
use embedded_graphics::{
mono_font::MonoTextStyleBuilder,
prelude::*,
primitives::{Line, PrimitiveStyle},
text::{Baseline, Text, TextStyleBuilder},
};
use epd_waveshare::color::TriColor;
use heapless::String;
use core::fmt::Write;

pub struct Theme1 {
display_text: String<60>,
}

impl Theme1 {
pub fn new() -> Self {
Theme1 {
display_text: String::new(),
}
}
}

impl Theme<TriColor> for Theme1
{
fn draw<DRAWTARGET: DrawTarget<Color = TriColor>>(&mut self, data: &Data, display: &mut DRAWTARGET) -> Result<(), DRAWTARGET::Error> {
self.display_text.clear();
write!(self.display_text, "CO2: {0} ppm | {1:#.2} °C | {2:#.2} %", data.co2, data.temperature, data.humidity).expect("Error occurred while trying to write in String");
let _ = Line::new(Point::new(5, 50), Point::new(291, 50))
.into_styled(PrimitiveStyle::with_stroke(TriColor::Chromatic, 4))
.draw(display);
draw_text(display, &self.display_text, 5, 10)?;
Ok(())
}
}

fn draw_text<DRAWTARGET>(display: &mut DRAWTARGET, text: &str, x: i32, y: i32) -> Result<(), DRAWTARGET::Error>
where
DRAWTARGET: DrawTarget<Color = TriColor> {
let style = MonoTextStyleBuilder::new()
.font(&embedded_graphics::mono_font::ascii::FONT_8X13_BOLD)
.text_color(TriColor::Black)
.background_color(TriColor::White)
.build();

let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();

Text::with_text_style(text, Point::new(x, y), style, text_style).draw(display)?;
Ok(())
}
File renamed without changes.
2 changes: 2 additions & 0 deletions esp32c3_nostd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
airquamon_domain = { path = "../airquamon_domain" }
display_themes = { path = "../display_themes" }
esp32c3-hal = { git = "https://github.com/esp-rs/esp-hal.git", rev = "33bfe80d958911f4d0b43adb89cca34b5dce1676", features = ["eh1"] }
esp-hal-common = { git = "https://github.com/esp-rs/esp-hal.git", rev = "33bfe80d958911f4d0b43adb89cca34b5dce1676", features = ["esp32c3", "eh1"] }
esp-backtrace = { version = "0.8.0", features = ["esp32c3", "panic-handler", "exception-handler", "print-uart"] }
Expand Down
69 changes: 16 additions & 53 deletions esp32c3_nostd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@ use esp32c3_hal::{
use embedded_hal::spi::SpiDevice;
use embedded_hal::delay::DelayUs;
use scd4x::scd4x::Scd4x;
use embedded_graphics::{
mono_font::MonoTextStyleBuilder,
prelude::*,
primitives::{Line, PrimitiveStyle},
text::{Baseline, Text, TextStyleBuilder},
};
use embedded_graphics::prelude::*;
use epd_waveshare::{epd2in9b_v3::*, prelude::*, color::{TriColor, ColorType}, graphics};
use heapless::String;
use core::fmt::{Write as FmtWrite};
use log::{info, error};
use log::info;
use airquamon_domain::Data;
use display_themes::{Theme, Theme1};

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -94,7 +89,7 @@ fn main() -> ! {
draw_target: display,
epd: epd,
delay: delay,
display_text: String::new(),
theme: Theme1::new(),
};

sensor.wake_up();
Expand Down Expand Up @@ -141,7 +136,7 @@ fn main() -> ! {


info!("updating display");
display.draw(Data {
display.draw(&Data {
co2: data.co2,
temperature: data.temperature,
humidity: data.humidity,
Expand All @@ -152,12 +147,6 @@ fn main() -> ! {
}
}

struct Data {
pub co2: u16,
pub temperature: f32,
pub humidity: f32,
}

trait Buffer {
fn buffer(&self) -> &[u8];
}
Expand Down Expand Up @@ -197,52 +186,42 @@ impl<
}
}

struct Display<SPI, EPD, DRAWTARGET, DELAY>
struct Display<SPI, EPD, DRAWTARGET, DELAY, THEME>
where
SPI: SpiDevice,
EPD: WaveshareThreeColorDisplayV2<SPI, DELAY>,
DRAWTARGET: DrawTarget<Color = TriColor> + ChromaticBuffer,
DELAY: DelayUs
DELAY: DelayUs,
THEME: Theme<TriColor>

{
spi: SPI,
epd: EPD,
draw_target: DRAWTARGET,
delay: DELAY,
display_text: String<60>,
theme: THEME,
}

trait DisplayTheme {

type Error;

fn draw(&mut self, data: Data) -> Result<(), Self::Error>;
fn draw_text(&mut self, text: &str) -> Result<(), Self::Error>;
fn draw(&mut self, data: &Data) -> Result<(), Self::Error>;
}

impl<SPI, EPD, DRAWTARGET, DELAY> DisplayTheme for Display<SPI, EPD, DRAWTARGET, DELAY>
impl<SPI, EPD, DRAWTARGET, DELAY, THEME> DisplayTheme for Display<SPI, EPD, DRAWTARGET, DELAY, THEME>
where
SPI: SpiDevice,
EPD: WaveshareThreeColorDisplayV2<SPI, DELAY>,
SPI: SpiDevice,
DRAWTARGET: DrawTarget<Color = TriColor> + ChromaticBuffer,
DELAY: DelayUs
DELAY: DelayUs,
THEME: Theme<TriColor>
{
type Error = SPI::Error;

fn draw(&mut self, data: Data) -> Result<(), Self::Error> {
self.display_text.clear();
write!(self.display_text, "CO2: {0} ppm | {1:#.2} °C | {2:#.2} %", data.co2, data.temperature, data.humidity).expect("Error occurred while trying to write in String");
let _ = Line::new(Point::new(5, 50), Point::new(291, 50))
.into_styled(PrimitiveStyle::with_stroke(TriColor::Chromatic, 4))
.draw(&mut self.draw_target);
draw_text(&mut self.draw_target, &self.display_text, 5, 10);
draw_to_epd(&mut self.spi, &mut self.epd, &mut self.draw_target, &mut self.delay)?;
Ok(())
}

fn draw_text(&mut self, text: &str) -> Result<(), Self::Error> {
draw_text(&mut self.draw_target, text, 5, 10);
fn draw(&mut self, data: &Data) -> Result<(), Self::Error> {
let _ = self.theme.draw(data, &mut self.draw_target);
draw_to_epd(&mut self.spi, &mut self.epd, &mut self.draw_target, &mut self.delay)?;
Ok(())
}
Expand All @@ -268,19 +247,3 @@ where
epd.sleep(spi, delay)?;
Ok(())
}



fn draw_text<DRAWTARGET>(display: &mut DRAWTARGET, text: &str, x: i32, y: i32)
where
DRAWTARGET: DrawTarget<Color = TriColor> {
let style = MonoTextStyleBuilder::new()
.font(&embedded_graphics::mono_font::ascii::FONT_8X13_BOLD)
.text_color(TriColor::Black)
.background_color(TriColor::White)
.build();

let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();

let _ = Text::with_text_style(text, Point::new(x, y), style, text_style).draw(display);
}

0 comments on commit 15ad22a

Please sign in to comment.