返回 CodeWhale
pet_widget.rs
根目录 / crates / tui / src / tui / ambient_life / pet_widget.rs
1 //! The shared braille renderer, promoted from the portable pet study's TUI.
2 //! It owns no clock, telemetry, or motion. The habitat owns placement and ink.
3
4 use super::pet_sim::{PetSim, PetState, braille};
5 use ratatui::{
6 buffer::Buffer,
7 layout::Rect,
8 style::{Color, Style},
9 widgets::Widget,
10 };
11
12 pub struct PetWidget<'a> {
13 pub sim: &'a PetSim,
14 pub state: &'a PetState,
15 }
16
17 impl Widget for PetWidget<'_> {
18 fn render(self, area: Rect, buf: &mut Buffer) {
19 let frame = self.sim.frame;
20 let label = format!(
21 "{} · {}{}",
22 frame.channel,
23 frame.arch,
24 if frame.hollow { " · resting" } else { "" }
25 );
26 // The creature and its non-colour cue are one unit. A narrow surface
27 // withholds both instead of silently dropping uncertainty or the gait.
28 if area.height < 4 || usize::from(area.width) < label.chars().count() {
29 return;
30 }
31 let tank = Rect {
32 height: area.height - 1,
33 ..area
34 };
35 let grid = braille(
36 self.sim,
37 tank.width as usize,
38 tank.height as usize,
39 self.state,
40 );
41 let fg = Color::Rgb(
42 (frame.r * frame.alpha).clamp(0.0, 255.0) as u8,
43 (frame.g * frame.alpha).clamp(0.0, 255.0) as u8,
44 (frame.b * frame.alpha).clamp(0.0, 255.0) as u8,
45 );
46 render_grid(area, buf, &grid, &label, Style::default().fg(fg));
47 }
48 }
49
50 /// Shared paint path for the Rust cameo and the embedded world's live raster.
51 /// A tiny viewport keeps the complete text cue before spending cells on dots.
52 pub(crate) fn render_grid(area: Rect, buf: &mut Buffer, grid: &[u8], label: &str, style: Style) {
53 codewhale_ratatui::BrailleFrame {
54 cells: grid,
55 caption: label,
56 style,
57 }
58 .render(area, buf);
59 }
60
61 #[cfg(test)]
62 #[path = "pet_widget_legacy.rs"]
63 mod pet_widget_legacy;
64 #[cfg(test)]
65 #[path = "pet_widget_tests.rs"]
66 mod pet_widget_tests;
67
67 lines RUST