add status bar
This commit is contained in:
31
Cargo.lock
generated
31
Cargo.lock
generated
@@ -39,6 +39,12 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrform"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7cf566ecc5c9d82b973e81d30babf6583c9b497f86295c952d538c3254ef4e6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ascii-canvas"
|
name = "ascii-canvas"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
@@ -805,6 +811,27 @@ dependencies = [
|
|||||||
"embedded-io",
|
"embedded-io",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-layout"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a90553247f2b05c59ac7894ea13d830636c2b1203fa03bff400eddbd1fa9f52"
|
||||||
|
dependencies = [
|
||||||
|
"embedded-graphics",
|
||||||
|
"embedded-layout-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-layout-macros"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f6e621fe4c7e05b695274b722dc0a60bacd1c8696b58191baa0154713d52400"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-sdmmc"
|
name = "embedded-sdmmc"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -1871,7 +1898,10 @@ dependencies = [
|
|||||||
name = "shared"
|
name = "shared"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arrform",
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
|
"embedded-graphics-core",
|
||||||
|
"embedded-layout",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1886,6 +1916,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
"embedded-graphics-simulator",
|
"embedded-graphics-simulator",
|
||||||
|
"embedded-layout",
|
||||||
"shared",
|
"shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,7 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
arrform = "0.1.1"
|
||||||
embedded-graphics = "0.8.1"
|
embedded-graphics = "0.8.1"
|
||||||
|
embedded-graphics-core = "0.4.0"
|
||||||
|
embedded-layout = "0.4.2"
|
||||||
|
|||||||
@@ -1,106 +1,74 @@
|
|||||||
#![feature(ascii_char)]
|
pub mod screen {
|
||||||
|
use arrform::{ArrForm, arrform};
|
||||||
|
use embedded_graphics::{
|
||||||
|
Drawable,
|
||||||
|
draw_target::DrawTarget,
|
||||||
|
mono_font::{MonoTextStyle, ascii::FONT_10X20},
|
||||||
|
pixelcolor::Rgb565,
|
||||||
|
prelude::{Point, RgbColor, Size},
|
||||||
|
primitives::Rectangle,
|
||||||
|
text::Text,
|
||||||
|
};
|
||||||
|
use embedded_layout::{
|
||||||
|
align::{horizontal, vertical},
|
||||||
|
layout::linear::LinearLayout,
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
use embedded_graphics::{
|
pub const SCREEN_WIDTH: usize = 320;
|
||||||
mono_font::{
|
pub const SCREEN_HEIGHT: usize = 320;
|
||||||
MonoFont, MonoTextStyle,
|
|
||||||
ascii::{FONT_6X9, FONT_10X20},
|
|
||||||
},
|
|
||||||
pixelcolor::{BinaryColor, Rgb565},
|
|
||||||
prelude::{Point, WebColors, *},
|
|
||||||
primitives::{Circle, Line, PrimitiveStyle, Rectangle},
|
|
||||||
text::{Alignment, Baseline, Text, TextStyle},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const SCREEN_WIDTH: usize = 320;
|
pub const STATUS_BAR_WIDTH: usize = 320;
|
||||||
pub const SCREEN_HEIGHT: usize = 320;
|
pub const STATUS_BAR_HEIGHT: usize = 40;
|
||||||
const SCREEN_ROWS: usize = 15;
|
|
||||||
const SCREEN_COLS: usize = 31;
|
|
||||||
const FONT: MonoFont = FONT_10X20;
|
|
||||||
const COLOR: Rgb565 = Rgb565::CSS_LAWN_GREEN;
|
|
||||||
|
|
||||||
pub struct Cursor {
|
pub struct UI {
|
||||||
x: u16,
|
pub status_bar: StatusBar,
|
||||||
y: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Cursor {
|
|
||||||
fn new(x: u16, y: u16) -> Self {
|
|
||||||
Self { x, y }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TextBuffer {
|
|
||||||
grid: [[Option<char>; SCREEN_COLS]; SCREEN_ROWS],
|
|
||||||
cursor: Cursor,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextBuffer {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
grid: [[None; SCREEN_COLS]; SCREEN_ROWS],
|
|
||||||
cursor: Cursor { x: 0, y: 0 },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// writes char at cursor
|
impl UI {
|
||||||
pub fn write_char(&mut self, ch: char) {
|
pub fn new() -> Self {
|
||||||
for (i, row) in self.grid.iter_mut().enumerate() {
|
Self {
|
||||||
for (j, col) in row.iter_mut().enumerate() {
|
status_bar: StatusBar {
|
||||||
if i as u16 == self.cursor.x && j as u16 == self.cursor.y {
|
battery: 100,
|
||||||
*col = Some(ch)
|
backlight: 100,
|
||||||
}
|
volume: 100,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// fills text buffer with char
|
pub fn draw_status_bar<D: DrawTarget<Color = Rgb565>>(&mut self, target: &mut D) {
|
||||||
pub fn fill(&mut self, ch: char) {
|
let text_style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
|
||||||
for i in 0..SCREEN_ROWS {
|
|
||||||
for j in 0..SCREEN_COLS {
|
let status_bar = Rectangle::new(
|
||||||
self.cursor = Cursor::new(i as u16, j as u16);
|
Point::new(0, 0),
|
||||||
self.write_char(ch);
|
Size::new(STATUS_BAR_WIDTH as u32, STATUS_BAR_HEIGHT as u32),
|
||||||
}
|
);
|
||||||
|
let _ = LinearLayout::horizontal(
|
||||||
|
Chain::new(Text::new(
|
||||||
|
arrform!(20, "Bat: {}", self.status_bar.battery).as_str(),
|
||||||
|
Point::zero(),
|
||||||
|
text_style,
|
||||||
|
))
|
||||||
|
.append(Text::new(
|
||||||
|
arrform!(20, "Lght: {}", self.status_bar.backlight).as_str(),
|
||||||
|
Point::zero(),
|
||||||
|
text_style,
|
||||||
|
))
|
||||||
|
.append(Text::new(
|
||||||
|
arrform!(20, "Vol: {}", self.status_bar.volume).as_str(),
|
||||||
|
Point::zero(),
|
||||||
|
text_style,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.arrange()
|
||||||
|
.align_to(&status_bar, horizontal::Center, vertical::Center)
|
||||||
|
.draw(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_up(&mut self) {
|
pub struct StatusBar {
|
||||||
let (top, bottom) = self.grid.split_at_mut(SCREEN_ROWS - 1);
|
pub battery: u8,
|
||||||
for (dest, src) in top.iter_mut().zip(&bottom[1..]) {
|
pub backlight: u8,
|
||||||
dest.copy_from_slice(src);
|
pub volume: u8,
|
||||||
}
|
|
||||||
|
|
||||||
self.grid[SCREEN_ROWS - 1].fill(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw<D: DrawTarget<Color = Rgb565>>(&mut self, target: &mut D) {
|
|
||||||
let style = MonoTextStyle::new(&FONT, COLOR);
|
|
||||||
|
|
||||||
let char_width = FONT.character_size.width as i32;
|
|
||||||
let char_height = FONT.character_size.height as i32;
|
|
||||||
|
|
||||||
let matrix_width = SCREEN_COLS as i32 * char_width;
|
|
||||||
let matrix_height = SCREEN_ROWS as i32 * char_height;
|
|
||||||
|
|
||||||
let offset_x = (SCREEN_WIDTH as i32 - matrix_width) / 2;
|
|
||||||
let offset_y = (SCREEN_HEIGHT as i32 - matrix_height) / 2;
|
|
||||||
|
|
||||||
for (i, row) in self.grid.iter().enumerate() {
|
|
||||||
for (j, col) in row[1..].iter().enumerate() {
|
|
||||||
if let Some(ch) = col {
|
|
||||||
let pos = Point::new(
|
|
||||||
offset_x + (j as i32) * char_width,
|
|
||||||
offset_y + (i as i32) * char_height,
|
|
||||||
);
|
|
||||||
|
|
||||||
let _ = Text::with_baseline(
|
|
||||||
ch.as_ascii().unwrap().as_str(),
|
|
||||||
pos,
|
|
||||||
style,
|
|
||||||
Baseline::Top,
|
|
||||||
)
|
|
||||||
.draw(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
embedded-graphics = "0.8.1"
|
embedded-graphics = "0.8.1"
|
||||||
embedded-graphics-simulator = "0.7.0"
|
embedded-graphics-simulator = "0.7.0"
|
||||||
|
embedded-layout = "0.4.2"
|
||||||
shared = { path = "../shared" }
|
shared = { path = "../shared" }
|
||||||
|
|||||||
@@ -1,29 +1,17 @@
|
|||||||
#![feature(ascii_char)]
|
use embedded_graphics::{pixelcolor::Rgb565, prelude::Size};
|
||||||
|
|
||||||
use embedded_graphics::{
|
|
||||||
geometry::Size,
|
|
||||||
mono_font::{
|
|
||||||
MonoFont, MonoTextStyle,
|
|
||||||
ascii::{FONT_6X9, FONT_10X20},
|
|
||||||
},
|
|
||||||
pixelcolor::{BinaryColor, Rgb565},
|
|
||||||
prelude::{Point, WebColors, *},
|
|
||||||
primitives::{Circle, Line, PrimitiveStyle, Rectangle},
|
|
||||||
text::{Alignment, Baseline, Text, TextStyle},
|
|
||||||
};
|
|
||||||
use embedded_graphics_simulator::{
|
use embedded_graphics_simulator::{
|
||||||
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, Window,
|
BinaryColorTheme, OutputSettingsBuilder, SimulatorDisplay, Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
use shared::{SCREEN_HEIGHT, SCREEN_WIDTH, TextBuffer};
|
use shared::screen::{SCREEN_HEIGHT, SCREEN_WIDTH, UI};
|
||||||
|
|
||||||
fn main() -> Result<(), core::convert::Infallible> {
|
fn main() -> Result<(), core::convert::Infallible> {
|
||||||
let mut display =
|
let mut display =
|
||||||
SimulatorDisplay::<Rgb565>::new(Size::new(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32));
|
SimulatorDisplay::<Rgb565>::new(Size::new(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32));
|
||||||
|
|
||||||
let mut textbuffer = TextBuffer::new();
|
let mut ui = UI::new();
|
||||||
textbuffer.fill('A');
|
|
||||||
textbuffer.draw(&mut display);
|
ui.draw_status_bar(&mut display);
|
||||||
|
|
||||||
let output_settings = OutputSettingsBuilder::new().build();
|
let output_settings = OutputSettingsBuilder::new().build();
|
||||||
Window::new("Hello World", &output_settings).show_static(&display);
|
Window::new("Hello World", &output_settings).show_static(&display);
|
||||||
|
|||||||
Reference in New Issue
Block a user