use ratatui::prelude::*;
use crate::app::App;
pub fn render(frame: &mut Frame, area: Rect, app: &App) {
let Some(buf) = app.state.active_buffer() else {
return;
};
let Some(shell_id) = app.shell_mgr.session_id_for_buffer(&buf.id) else {
return;
};
let Some(screen) = app.shell_mgr.screen(shell_id) else {
return;
};
let (screen_rows, screen_cols) = screen.size();
let rows = area.height.min(screen_rows);
let cols = area.width.min(screen_cols);
let ratatui_buf = frame.buffer_mut();
for row in 0..rows {
for col in 0..cols {
let x = area.x + col;
let y = area.y + row;
let Some(ratatui_cell) = ratatui_buf.cell_mut(Position::new(x, y)) else {
continue;
};
let Some(cell) = screen.cell(row, col) else {
ratatui_cell.set_char(' ');
ratatui_cell.set_style(Style::reset());
continue;
};
let ch = cell.contents();
let fg = vt100_color_to_ratatui(cell.fgcolor());
let bg = vt100_color_to_ratatui(cell.bgcolor());
let mut modifier = Modifier::empty();
if cell.bold() {
modifier |= Modifier::BOLD;
}
if cell.italic() {
modifier |= Modifier::ITALIC;
}
if cell.underline() {
modifier |= Modifier::UNDERLINED;
}
if cell.inverse() {
modifier |= Modifier::REVERSED;
}
let style = Style::new().fg(fg).bg(bg).add_modifier(modifier);
let display_char = if ch.is_empty() {
' ' } else {
ch.chars().next().unwrap_or(' ')
};
ratatui_cell.set_char(display_char);
ratatui_cell.set_style(style);
}
}
if !screen.hide_cursor() {
let (crow, ccol) = screen.cursor_position();
let cx = area.x + ccol;
let cy = area.y + crow;
if cx < area.x + area.width && cy < area.y + area.height {
frame.set_cursor_position(Position::new(cx, cy));
}
}
}
const fn vt100_color_to_ratatui(color: vt100::Color) -> Color {
match color {
vt100::Color::Default => Color::Reset,
vt100::Color::Idx(n) => Color::Indexed(n),
vt100::Color::Rgb(r, g, b) => Color::Rgb(r, g, b),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vt100_color_default_maps_to_reset() {
assert_eq!(vt100_color_to_ratatui(vt100::Color::Default), Color::Reset);
}
#[test]
fn vt100_color_indexed_maps_correctly() {
assert_eq!(
vt100_color_to_ratatui(vt100::Color::Idx(196)),
Color::Indexed(196)
);
}
#[test]
fn vt100_color_rgb_maps_correctly() {
assert_eq!(
vt100_color_to_ratatui(vt100::Color::Rgb(255, 128, 0)),
Color::Rgb(255, 128, 0)
);
}
}