rework card view to display information on all displays as intended
This commit is contained in:
Generated
+10
@@ -206,6 +206,7 @@ dependencies = [
|
||||
"log",
|
||||
"num_enum",
|
||||
"pn532",
|
||||
"profont",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
@@ -1595,6 +1596,15 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profont"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "016681370a9dd6e7ddb4c1a959922fd59dc45e5ebaa5ff5b13090267898ced34"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.47"
|
||||
|
||||
@@ -58,6 +58,7 @@ esp-backtrace = { version = "0.19.0", features = [
|
||||
"println",
|
||||
] }
|
||||
esp-radio = { version = "0.18.0", features = ["esp32s3", "wifi"] }
|
||||
profont = "0.7.0"
|
||||
|
||||
[build-dependencies]
|
||||
log = "0.4.27"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use alloc::format;
|
||||
use ch1115::{Ch1115, Size128x64};
|
||||
use core::convert::Infallible;
|
||||
use core::error::Error;
|
||||
use core::fmt::Debug;
|
||||
use core::fmt::Display;
|
||||
use display_interface_spi::SPIInterface;
|
||||
use embedded_hal_bus::spi::AtomicDevice;
|
||||
use embedded_hal_bus::util::AtomicCell;
|
||||
@@ -8,6 +12,29 @@ use esp_hal::gpio::Output;
|
||||
|
||||
use crate::drivers::spi_bus::{DisplaySpiBus, SharedOutput, SharedReset};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SecondaryDisplayError(ch1115::Error<Infallible>);
|
||||
|
||||
impl Display for SecondaryDisplayError {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for SecondaryDisplayError {}
|
||||
|
||||
impl From<ch1115::Error<Infallible>> for SecondaryDisplayError {
|
||||
fn from(value: ch1115::Error<Infallible>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Infallible> for SecondaryDisplayError {
|
||||
fn from(value: Infallible) -> Self {
|
||||
Self(ch1115::Error::Pin(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub type GenericSecondaryDisplay<'a, BUS, RST, DC> =
|
||||
Ch1115<SPIInterface<AtomicDevice<'a, BUS, Output<'a>, Delay>, DC>, RST, Size128x64>;
|
||||
pub type SecondaryDisplay<'a> =
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use core::error::Error;
|
||||
use embedded_hal_bus::i2c::AtomicDevice;
|
||||
use esp_hal::delay::Delay;
|
||||
use i2c_character_display::{CharacterDisplayPCF8574T, LcdDisplayType};
|
||||
@@ -48,6 +49,8 @@ pub enum TertiaryDisplayWriteError<'a> {
|
||||
Format(LinesError),
|
||||
}
|
||||
|
||||
impl<'a> Error for TertiaryDisplayWriteError<'a> {}
|
||||
|
||||
impl<'a> From<TertiaryDisplayError<'a>> for TertiaryDisplayWriteError<'a> {
|
||||
fn from(value: TertiaryDisplayError<'a>) -> Self {
|
||||
Self::Display(value)
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use alloc::boxed::Box;
|
||||
use core::error;
|
||||
use embedded_graphics::{
|
||||
draw_target::DrawTarget as _,
|
||||
pixelcolor::{Rgb565, RgbColor as _},
|
||||
};
|
||||
|
||||
use crate::drivers::{
|
||||
primary_lcd::PrimaryDisplay, secondary_oled::SecondaryDisplay, tertiary_lcd::TertiaryDisplay,
|
||||
primary_lcd::{PrimaryDisplay, PrimaryDisplayError},
|
||||
secondary_oled::{SecondaryDisplay, SecondaryDisplayError},
|
||||
tertiary_lcd::TertiaryDisplay,
|
||||
};
|
||||
|
||||
pub struct Outputs {
|
||||
@@ -17,11 +21,20 @@ pub struct Outputs {
|
||||
}
|
||||
|
||||
impl Outputs {
|
||||
pub fn clear_screens(&mut self) {
|
||||
self.primary_display.clear(Rgb565::BLACK).unwrap();
|
||||
self.secondary_display_1.clear().unwrap();
|
||||
// self.secondary_display_2.clear().unwrap();
|
||||
// self.secondary_display_3.clear().unwrap();
|
||||
pub fn clear_screens(&mut self) -> Result<(), Box<dyn error::Error>> {
|
||||
self.primary_display
|
||||
.clear(Rgb565::BLACK)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
self.secondary_display_1
|
||||
.clear()
|
||||
.map_err(SecondaryDisplayError::from)?;
|
||||
self.secondary_display_2
|
||||
.clear()
|
||||
.map_err(SecondaryDisplayError::from)?;
|
||||
self.secondary_display_3
|
||||
.clear()
|
||||
.map_err(SecondaryDisplayError::from)?;
|
||||
self.tertiary_display.clear().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+133
-72
@@ -1,5 +1,7 @@
|
||||
use crate::display::sprite::render_sprite_onto_ili9341;
|
||||
use crate::drivers::primary_lcd::PrimaryDisplayError;
|
||||
use crate::drivers::primary_lcd::{PrimaryDisplay, PrimaryDisplayError};
|
||||
use crate::drivers::secondary_oled::{SecondaryDisplay, SecondaryDisplayError};
|
||||
use crate::drivers::tertiary_lcd::{TertiaryDisplay, TertiaryDisplayWriteError};
|
||||
use crate::navigation::navigation::NewState;
|
||||
use crate::navigation::outputs::Outputs;
|
||||
use crate::peripherals::Peripherals;
|
||||
@@ -8,14 +10,23 @@ use alloc::format;
|
||||
use core::error;
|
||||
use embedded_graphics::mono_font::MonoTextStyle;
|
||||
use embedded_graphics::mono_font::ascii::FONT_6X10;
|
||||
use embedded_graphics::pixelcolor::BinaryColor;
|
||||
use embedded_graphics::pixelcolor::Rgb565;
|
||||
use embedded_graphics::prelude::Point;
|
||||
use embedded_graphics::prelude::RgbColor;
|
||||
use embedded_graphics::text::Text;
|
||||
use embedded_graphics::{Drawable, geometry::Size, primitives::Rectangle};
|
||||
use embedded_graphics_core::draw_target::DrawTarget;
|
||||
use profont::PROFONT_7_POINT;
|
||||
use profont::PROFONT_18_POINT;
|
||||
|
||||
use core::future;
|
||||
use embedded_graphics::geometry::Dimensions;
|
||||
use embedded_text::{
|
||||
TextBox,
|
||||
alignment::{HorizontalAlignment, VerticalAlignment},
|
||||
style::{HeightMode, TextBoxStyleBuilder},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
card::model::{Card, Palette},
|
||||
@@ -27,7 +38,118 @@ use crate::{
|
||||
pub struct CardView {
|
||||
pub card: Card,
|
||||
}
|
||||
impl CardView {
|
||||
fn display_card(
|
||||
&self,
|
||||
primary_display: &mut PrimaryDisplay,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
let background = Rectangle::new(Point::new(0, 0), Size::new(240, 320));
|
||||
let bg_color = self.card.cardtype.clone().into();
|
||||
|
||||
let _ = primary_display.fill_solid(&background, bg_color);
|
||||
// name as header
|
||||
let text_style_name = MonoTextStyle::new(&PROFONT_18_POINT, Rgb565::WHITE);
|
||||
let textbox_style = TextBoxStyleBuilder::new()
|
||||
.height_mode(HeightMode::FitToText)
|
||||
.alignment(HorizontalAlignment::Center)
|
||||
.build();
|
||||
|
||||
let display_area = primary_display.bounding_box();
|
||||
let bounds = Rectangle::new(Point::new(0, 10), Size::new(display_area.size.width, 50));
|
||||
|
||||
TextBox::with_textbox_style(&self.card.name, bounds, text_style_name, textbox_style)
|
||||
.draw(primary_display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
|
||||
// event lower left corner
|
||||
let text_style_event = MonoTextStyle::new(&PROFONT_7_POINT, Rgb565::WHITE);
|
||||
|
||||
let textbox_style = TextBoxStyleBuilder::new()
|
||||
.height_mode(HeightMode::FitToText)
|
||||
.alignment(HorizontalAlignment::Right)
|
||||
.build();
|
||||
|
||||
let display_area = primary_display.bounding_box();
|
||||
let bounds = Rectangle::new(Point::new(0, 310), Size::new(display_area.size.width, 50));
|
||||
|
||||
TextBox::with_textbox_style(
|
||||
&format!("{}", self.card.event),
|
||||
bounds,
|
||||
text_style_event,
|
||||
textbox_style,
|
||||
)
|
||||
.draw(primary_display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
|
||||
// card sprite
|
||||
let palette: Palette = self.card.cardtype.clone().into();
|
||||
|
||||
render_sprite_onto_ili9341(
|
||||
primary_display,
|
||||
self.card.sprite.data.as_slice(),
|
||||
&palette,
|
||||
Point::new(0, 50),
|
||||
240,
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn display_trait(
|
||||
&self,
|
||||
secondary_display: &mut SecondaryDisplay,
|
||||
trait_str: &str,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
let text_style_secondary = MonoTextStyle::new(&PROFONT_18_POINT, BinaryColor::On);
|
||||
|
||||
let textbox_style = TextBoxStyleBuilder::new()
|
||||
.height_mode(HeightMode::FitToText)
|
||||
.vertical_alignment(VerticalAlignment::Middle)
|
||||
.alignment(HorizontalAlignment::Justified)
|
||||
.build();
|
||||
|
||||
let display_area = secondary_display.bounding_box();
|
||||
let bounds = Rectangle::new(Point::new(0, 0), display_area.size);
|
||||
|
||||
TextBox::with_textbox_style(
|
||||
&format!("{}", trait_str),
|
||||
bounds,
|
||||
text_style_secondary,
|
||||
textbox_style,
|
||||
)
|
||||
.draw(secondary_display)
|
||||
.map_err(SecondaryDisplayError::from)?;
|
||||
|
||||
secondary_display
|
||||
.flush()
|
||||
.map_err(SecondaryDisplayError::from)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn display_traits(
|
||||
&self,
|
||||
secondary_display_1: &mut SecondaryDisplay,
|
||||
secondary_display_2: &mut SecondaryDisplay,
|
||||
secondary_display_3: &mut SecondaryDisplay,
|
||||
) -> Result<(), Box<dyn error::Error>> {
|
||||
self.display_trait(secondary_display_1, self.card.trait1.as_str())?;
|
||||
self.display_trait(secondary_display_2, self.card.trait2.as_str())?;
|
||||
self.display_trait(secondary_display_3, self.card.trait3.as_str())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn display_secret<'a>(
|
||||
&self,
|
||||
tertiary_display: &mut TertiaryDisplay<'a>,
|
||||
) -> Result<(), Box<dyn error::Error + 'a>> {
|
||||
tertiary_display
|
||||
.write(&alloc::format!("{}", self.card.secret))
|
||||
.map_err(TertiaryDisplayWriteError::from)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Navigable for CardView {
|
||||
fn display(
|
||||
&self,
|
||||
@@ -35,82 +157,21 @@ impl Navigable for CardView {
|
||||
_: &Peripherals,
|
||||
) -> impl core::future::Future<Output = Result<(), Box<dyn error::Error>>> + Send {
|
||||
async move {
|
||||
let display = &mut outputs.primary_display;
|
||||
display
|
||||
.clear(Rgb565::BLACK)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
|
||||
let background = Rectangle::new(Point::new(0, 0), Size::new(240, 320));
|
||||
let bg_color = self.card.cardtype.clone().into();
|
||||
|
||||
let _ = display.fill_solid(&background, bg_color);
|
||||
|
||||
let style = MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE);
|
||||
Text::new(
|
||||
&format!("Name: {}", self.card.name),
|
||||
Point::new(20, 240),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
&format!("Type: {}", self.card.cardtype),
|
||||
Point::new(20, 250),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
&format!("Event: {}", self.card.event),
|
||||
Point::new(20, 260),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
&format!("UUID: {}", self.card.uuid),
|
||||
Point::new(20, 270),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
&format!("Trait1: {}", self.card.trait1),
|
||||
Point::new(20, 280),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
&format!("Trait2: {}", self.card.trait2),
|
||||
Point::new(20, 290),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
&format!("Trait3: {}", self.card.trait3),
|
||||
Point::new(20, 300),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
Text::new(
|
||||
outputs.clear_screens()?;
|
||||
/*Text::new(
|
||||
&format!("Secret: {}", self.card.secret),
|
||||
Point::new(20, 310),
|
||||
style,
|
||||
)
|
||||
.draw(display)
|
||||
.map_err(PrimaryDisplayError::from)?;
|
||||
|
||||
let palette: Palette = self.card.cardtype.clone().into();
|
||||
render_sprite_onto_ili9341(
|
||||
display,
|
||||
self.card.sprite.data.as_slice(),
|
||||
&palette,
|
||||
Point::new(13, 10),
|
||||
215,
|
||||
);
|
||||
.map_err(PrimaryDisplayError::from)?;*/
|
||||
self.display_traits(
|
||||
&mut outputs.secondary_display_1,
|
||||
&mut outputs.secondary_display_2,
|
||||
&mut outputs.secondary_display_3,
|
||||
)?;
|
||||
self.display_secret(&mut outputs.tertiary_display)?;
|
||||
self.display_card(&mut outputs.primary_display)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user