Setzt den OpenSpec-Change phase-3-runtime-bildschirm um (77/77 Aufgaben). Abdeckung laut Inventar: 195 implementiert, 37 offen, 53 Non-Feature. Vollstaendigkeits-Inventar - docs/inventar.md mit 285 Eintraegen aus den Themenlisten von bas7advr.hlp und qb45advr.hlp, je mit Status und Fundstelle - crates/tb-frontend/tests/inventar.rs haelt die Tabelle in beide Richtungen gegen den Code; der Abdeckungsstand kann nicht veralten Bruchschritt (Puffer, Host, Korpus) - Cell/TextScreen ziehen ratatui-frei nach tb-runtime::screen; tb-ui behaelt Farbabbildung, Widget und den neuen Terminal-Host - Host wechselt vom Zeichenstrom auf Anzeige des Zellenpuffers plus Ereignisse (Taste, Groessenaenderung, Abbruch) - Korpusvergleich auf getrimmten Bildschirm-Snapshot; die acht bestehenden Sollausgaben blieben dabei unveraendert Groessenunabhaengigkeit - 80x25 ist nirgends mehr eine feste Grenze; Groessenaenderungen waehrend der Ausfuehrung werden zugestellt (Inhalt oben links erhalten, Cursor und VIEW PRINT geklemmt) - Korpusnachweis: dasselbe Programm bei 80x25 und 120x40 mit je eigener Sollausgabe, plus ein Programm mit Groessenwechsel mitten im Lauf Bibliothek - Breite Unicode-Zeichen belegen zwei Zellen (Cursor, POS, Randumbruch) - Bildschirm: CLS, COLOR, LOCATE, WIDTH, VIEW PRINT, SCREEN, CSRLIN, POS - Tastatur: INKEY$, INPUT$, Funktionstasten-Makros (KEY n / LIST / ON) - PRINT USING, LPRINT USING, FORMAT$, SetFormatCC - Mathematik mit kompatiblem PRNG (gleiche Saat, gleiche Folge) - Datum und Zeit mit Serienwerten ab 1899 - Finanzmathematik: FV#, PV#, Pmt#, IPmt#, PPmt#, NPer#, Rate#, NPV#, IRR#, MIRR#, SLN#, SYD#, DDB# - Datei-E/A: sequenziell, RANDOM (Recordpuffer und UDT-Variablen), BINARY, FIELD/LSET/RSET, Statusfunktionen, Dateisystem, MK$/CV - System: ENVIRON, FRE, CLEAR, TRON/TROFF, STACK, ERDEV, ERR-Anweisung Altlasten aus Phase 2 - ON ERROR GOTO auf Modulebene ist aus Prozeduren ansprechbar (prozeduruebergreifender Fixup im Codegenerator) - DATA behaelt seinen Rohtext (Gross-/Kleinschreibung, innerer Leerraum) - Die vier TODO-verify-Zellen der Konvertierungsmatrix sind aufgeloest Vom Inventar aufgedeckte Fehler - Zwoelf Non-Features wies der Compiler entgegen der Phase-1-Spec nicht ab (CALLS, SSEG, POINT, VIEW, COM, PEN, STRIG, STICK, die String*-Routinen, LINE und OPEN "COMn:") -- geschlossen - Drei Gruppen fehlten im urspruenglichen Umfang: Finanzmathematik, Record-Konvertierung, Rest der Dateisystemfunktionen - bas7advr.hlp allein ist keine vollstaendige Quelle; das Inventar bildet die Vereinigung mit qb45advr.hlp Neue Changes - phase-3-isam: schliesst Phase 3 ab (Speicherschicht redb) - phase-3-ortszeit: zieht die UTC-Abweichung zurueck Neue Abhaengigkeit: unicode-width. Dokumentiert: sprachreferenz.md und tbvm-design.md sind TODO-frei, docs/bibliothek.md neu, PLAN.md fortgeschrieben. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
96 lines
3.4 KiB
Rust
96 lines
3.4 KiB
Rust
//! 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(())
|
||
}
|