Files
TerminalBasic/crates/tb-ui/examples/spike.rs

112 lines
3.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Phase-0-Spike: 80×25-Bildschirmpuffer, 16-Farben-Palette, Unicode,
//! Tastatur- und Mausereignisse.
//!
//! Start: `cargo run -p tb-ui --example spike` — Beenden mit Esc.
//! Getippte Zeichen erscheinen im Eingabebereich; Sondertasten und
//! Mausereignisse werden in der Statuszeile angezeigt.
use crossterm::event::{
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind,
};
use crossterm::execute;
use std::io::stdout;
use std::time::Duration;
use tb_ui::screen::{ScreenWidget, TextScreen};
fn testbild(s: &mut TextScreen) {
s.set_color(15, 1);
s.print(&format!(
"{:^80}",
"Terminal Basic — Phase-0-Spike (Esc beendet)"
));
// Farbraster: alle Vordergrundfarben auf allen Hintergründen
for bg in 0u8..8 {
s.set_color(15, 0);
s.locate(3 + bg as usize, 3).unwrap();
s.print(&format!("HG {bg} "));
for fg in 0u8..16 {
s.set_color(fg, bg);
s.print(&format!(" {fg:2}"));
}
}
// Unicode statt CP437: Rahmen, Umlaute, Symbole
s.set_color(14, 0);
s.locate(12, 3).unwrap();
s.print("┌─ Unicode ────────────────────────────┐");
s.locate(13, 3).unwrap();
s.print("│ Äpfel, Öl, Übermaß, ß — ☃ ♥ ♦ ♣ ♠ π λ │");
s.locate(14, 3).unwrap();
s.print("└──────────────────────────────────────┘");
s.set_color(7, 0);
s.locate(16, 3).unwrap();
s.print("Eingabe (Zeichen erscheinen hier):");
s.locate(17, 3).unwrap();
}
fn status(s: &mut TextScreen, text: &str) {
let (r, c) = (s.csrlin(), s.pos());
let (row, width) = (s.rows(), s.cols());
s.set_color(0, 7);
s.locate(row, 1).unwrap();
s.print(&format!("{text:<width$.width$}"));
s.set_color(7, 0);
s.locate(r, c).unwrap();
}
fn main() -> anyhow::Result<()> {
let mut terminal = ratatui::init();
execute!(stdout(), EnableMouseCapture)?;
let (tw, th) = crossterm::terminal::size()?;
let mut screen = TextScreen::with_size(tw as usize, th as usize);
testbild(&mut screen);
status(&mut screen, "Bereit. Tasten/Maus testen, Esc beendet.");
loop {
terminal.draw(|f| f.render_widget(ScreenWidget(&screen), f.area()))?;
if !event::poll(Duration::from_millis(100))? {
continue;
}
match event::read()? {
Event::Key(k) if k.kind != KeyEventKind::Release => match k.code {
KeyCode::Esc => break,
KeyCode::Char(c) => {
screen.print(&c.to_string());
status(
&mut screen,
&format!("Taste: {:?} Modifier: {:?}", k.code, k.modifiers),
);
}
KeyCode::Enter => screen.print("\n"),
other => status(
&mut screen,
&format!("Sondertaste: {other:?} Modifier: {:?}", k.modifiers),
),
},
Event::Mouse(m) => {
status(
&mut screen,
&format!(
"Maus: {:?} bei Spalte {}, Zeile {}",
m.kind,
m.column + 1,
m.row + 1
),
);
}
Event::Resize(w, h) => {
screen.resize(w as usize, h as usize);
status(&mut screen, &format!("Resize: {w}x{h}"));
}
_ => {}
}
}
execute!(stdout(), DisableMouseCapture)?;
ratatui::restore();
Ok(())
}