extern crate alloc;
use alloc::string::String;
use crate::{
resource::font::Font,
sys,
ui::{
Layer, Layout, StaticWindow, TextAlignment, TextBuf, TextLayer, UiGuard, Window, WindowCtx,
},
};
pub type StatusBoard<const SLOTS: usize> = StaticWindow<BoardLayout<SLOTS>, BoardLines<SLOTS>>;
pub struct BoardLines<const SLOTS: usize> {
lines: [Option<String>; SLOTS],
}
pub struct BoardLayout<const SLOTS: usize> {
text: TextLayer<TextBuf>,
}
impl<const SLOTS: usize> BoardLayout<SLOTS> {
fn render(&mut self, lines: &BoardLines<SLOTS>) {
let render = |text: &mut TextBuf| {
text.clear();
for line in lines.lines.iter().flatten() {
text.push_str(line);
text.push_str("\n");
}
};
self.text.text_mut(render);
}
}
impl<const SLOTS: usize> Layout<BoardLines<SLOTS>> for BoardLayout<SLOTS> {
fn load(ctx: &mut WindowCtx<'_, Self, BoardLines<SLOTS>>) -> Self {
let mut root = ctx.root();
let mut text = TextLayer::new(root.bounds()).expect("board text layer");
text.set_alignment(TextAlignment::Center)
.set_font(Font::system(sys::FONT_KEY_GOTHIC_18));
root.add_child(&mut text);
let mut board = Self { text };
if let Some(lines) = ctx.data() {
board.render(lines);
}
board
}
}
impl<const SLOTS: usize> StatusBoard<SLOTS> {
pub fn init(&self) {
let lines = BoardLines {
lines: [const { None }; SLOTS],
};
self.set(Window::new(Some(lines)).expect("board window"));
}
pub fn set_line(&self, ui: &mut UiGuard, slot: usize, line: impl Into<String>) {
self.with(ui, |board, ctx| {
let Some(lines) = ctx.data() else { return };
lines.lines[slot] = Some(line.into());
if let Some(board) = board {
board.render(lines);
}
});
}
}