Files
TerminalBasic/crates/tb-ui/examples/spike.rs
Chili Palmer 7e6fa6ea88 Phase 0: Referenzdokumente, Fehlerkatalog, Testkorpus, Ratatui-Spike
Entscheidungen festgehalten: TBVM bestaetigt und eingebettet in die
Executables; durchgaengig UTF-8 statt CP437 (dokumentierte Abweichung).

- docs/: Sprachreferenz, Forms-Referenz, Dateiformate, TBVM-Design
- tb-runtime::errors: klassischer Laufzeitfehler-Katalog (implementiert)
- tb-ui::screen: 80x25-Unicode-Zellenpuffer mit 16-Farben-Abbildung,
  Scrollbereich (VIEW PRINT), Letterboxing; Ratatui-Widget + Tests
- Spike: cargo run -p tb-ui --example spike (Farben, Unicode, Tasten, Maus)
- tests/compat/: erste Referenzprogramme mit byte-genauer Sollausgabe

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 16:36:45 +02:00

91 lines
3.2 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::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());
s.set_color(0, 7);
s.locate(25, 1).unwrap();
s.print(&format!("{text:<80.80}"));
s.set_color(7, 0);
s.locate(r, c).unwrap();
}
fn main() -> anyhow::Result<()> {
let mut terminal = ratatui::init();
execute!(stdout(), EnableMouseCapture)?;
let mut screen = TextScreen::new();
testbild(&mut screen);
status(&mut screen, "Bereit. Tasten/Maus testen, Esc beendet.");
loop {
terminal.draw(|f| f.render_widget(&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) => status(&mut screen, &format!("Resize: {w}x{h}")),
_ => {}
}
}
execute!(stdout(), DisableMouseCapture)?;
ratatui::restore();
Ok(())
}