feat(display): windows: full-screen, F1 cycles, OS bar (names, front, user); canvas-only (display-owned buffers, 4 max, reused); launchers OPEN (pm per app, terminal own), window caps minted by display; FORGET on launcher death via init courier; raster crate (font, chunked text); F-keys in input; terminal+snake on canvas; REDRAW gone
This commit is contained in:
@@ -74,3 +74,67 @@ impl Framebuffer for MockFramebuffer {
|
||||
self.scrolls += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// A screen of `W` by `H` pixels that keeps what is drawn, for tests that
|
||||
/// look at the picture rather than the calls.
|
||||
pub struct GridFramebuffer<const W: usize, const H: usize> {
|
||||
pixels: [[Color; W]; H],
|
||||
pub flushes: usize,
|
||||
}
|
||||
|
||||
impl<const W: usize, const H: usize> GridFramebuffer<W, H> {
|
||||
pub fn new() -> Self {
|
||||
Self { pixels: [[Color::from_raw(0); W]; H], flushes: 0 }
|
||||
}
|
||||
|
||||
/// The pixel at (x, y), `None` off the screen.
|
||||
pub fn pixel(&self, x: usize, y: usize) -> Option<Color> {
|
||||
self.pixels.get(y).and_then(|row| row.get(x)).copied()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const W: usize, const H: usize> Default for GridFramebuffer<W, H> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const W: usize, const H: usize> Framebuffer for GridFramebuffer<W, H> {
|
||||
fn width(&self) -> Dimension {
|
||||
Dimension::new(W as u16)
|
||||
}
|
||||
|
||||
fn height(&self) -> Dimension {
|
||||
Dimension::new(H as u16)
|
||||
}
|
||||
|
||||
fn write_pixel(&mut self, x: ScreenCoord, y: ScreenCoord, color: Color) {
|
||||
if let Some(px) = self.pixels.get_mut(y.raw() as usize).and_then(|r| r.get_mut(x.raw() as usize)) {
|
||||
*px = color;
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_rect(&mut self, x: ScreenCoord, y: ScreenCoord, w: Dimension, h: Dimension, color: Color) {
|
||||
for row in y.raw()..y.raw().saturating_add(h.raw()) {
|
||||
for col in x.raw()..x.raw().saturating_add(w.raw()) {
|
||||
self.write_pixel(ScreenCoord::new(col), ScreenCoord::new(row), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clear(&mut self, color: Color) {
|
||||
self.pixels = [[color; W]; H];
|
||||
}
|
||||
|
||||
fn flush(&mut self) {
|
||||
self.flushes += 1;
|
||||
}
|
||||
|
||||
fn scroll_up(&mut self, top: ScreenCoord, height: Dimension, by: Dimension, fill: Color) {
|
||||
let (top, height, by) = (top.raw() as usize, height.raw() as usize, by.raw() as usize);
|
||||
let end = (top + height).min(H);
|
||||
for y in top..end {
|
||||
self.pixels[y] = if y + by < end { self.pixels[y + by] } else { [fill; W] };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user