use ratatui::macros::ratatui_core;
use crate::CellFlags;
impl crate::Frame {
pub fn from_rect(rect: ratatui::prelude::Rect) -> Self {
Self::with_capacity(rect.width as usize, rect.height as usize)
}
}
pub struct AnimationWidget<'a> {
frame: &'a crate::Frame,
}
impl<'a> AnimationWidget<'a> {
pub fn new(frame: &'a crate::Frame) -> Self {
Self { frame }
}
}
fn crossterm_color_to_ratatui_color(color: crossterm::style::Color) -> ratatui::prelude::Color {
match color {
crossterm::style::Color::Reset => ratatui_core::style::Color::Reset,
crossterm::style::Color::Black => ratatui_core::style::Color::Black,
crossterm::style::Color::DarkGrey => ratatui_core::style::Color::DarkGray,
crossterm::style::Color::Red => ratatui_core::style::Color::LightRed,
crossterm::style::Color::DarkRed => ratatui_core::style::Color::Red,
crossterm::style::Color::Green => ratatui_core::style::Color::LightGreen,
crossterm::style::Color::DarkGreen => ratatui_core::style::Color::Green,
crossterm::style::Color::Yellow => ratatui_core::style::Color::LightYellow,
crossterm::style::Color::DarkYellow => ratatui_core::style::Color::Yellow,
crossterm::style::Color::Blue => ratatui_core::style::Color::LightBlue,
crossterm::style::Color::DarkBlue => ratatui_core::style::Color::Blue,
crossterm::style::Color::Magenta => ratatui_core::style::Color::LightMagenta,
crossterm::style::Color::DarkMagenta => ratatui_core::style::Color::Magenta,
crossterm::style::Color::Cyan => ratatui_core::style::Color::LightCyan,
crossterm::style::Color::DarkCyan => ratatui_core::style::Color::Cyan,
crossterm::style::Color::White => ratatui_core::style::Color::White,
crossterm::style::Color::Grey => ratatui_core::style::Color::Gray,
crossterm::style::Color::Rgb { r, g, b } => ratatui_core::style::Color::Rgb(r, g, b),
crossterm::style::Color::AnsiValue(n) => ratatui_core::style::Color::Indexed(n),
}
}
impl From<CellFlags> for ratatui::style::Style {
fn from(value: CellFlags) -> Self {
let mut style = ratatui::style::Style::default();
if value.contains(CellFlags::BOLD) {
style = style.add_modifier(ratatui::style::Modifier::BOLD);
}
if value.contains(CellFlags::ITALIC) {
style = style.add_modifier(ratatui::style::Modifier::ITALIC);
}
if value.contains(CellFlags::UNDERLINE) {
style = style.add_modifier(ratatui::style::Modifier::UNDERLINED);
}
if value.contains(CellFlags::INVERSE) {
style = style.add_modifier(ratatui::style::Modifier::REVERSED);
}
if value.contains(CellFlags::HIDDEN) {
style = style.add_modifier(ratatui::style::Modifier::HIDDEN);
}
if value.contains(CellFlags::STRIKETHROUGH) {
style = style.add_modifier(ratatui::style::Modifier::CROSSED_OUT);
}
if value.contains(CellFlags::DIM) {
style = style.add_modifier(ratatui::style::Modifier::DIM);
}
if value.contains(CellFlags::BLINK) {
style = style.add_modifier(ratatui::style::Modifier::SLOW_BLINK);
}
style
}
}
impl From<crate::Cell> for ratatui::buffer::Cell {
fn from(value: crate::Cell) -> Self {
From::from(&value)
}
}
impl From<&crate::Cell> for ratatui::buffer::Cell {
fn from(value: &crate::Cell) -> Self {
let mut rat_cell = Self::default();
let symbol = value.ch().to_string();
let fg = crossterm_color_to_ratatui_color(value.fg());
let bg = crossterm_color_to_ratatui_color(value.bg());
let flags = value.flags();
rat_cell.set_symbol(&symbol);
rat_cell.set_fg(fg);
rat_cell.set_bg(bg);
rat_cell.set_style(flags);
rat_cell
}
}
impl<'a> ratatui::widgets::Widget for AnimationWidget<'a> {
fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer)
where
Self: Sized,
{
let frame = self.frame;
let height = frame.height().min(area.height as usize);
let width = frame.width().min(area.width as usize);
for row in 0..height {
for col in 0..width {
let Some(cell) = frame.get_cell(row, col) else {
continue;
};
let cell: ratatui::buffer::Cell = cell.into();
let x = area.x + col as u16;
let y = area.y + row as u16;
let Some(buf_cell) = buf.cell_mut((x, y)) else {
continue;
};
*buf_cell = cell;
}
}
}
}