use std::{cell::RefCell, io, rc::Rc};
use crossterm::event::{Event, KeyModifiers, MouseEvent, MouseEventKind};
use crate::{
AnyElement, ComponentDrawer, ElementRepr, render::tree::Tree, terminal::UpdaterTerminal,
};
use ratatui::{backend::TestBackend, buffer::Buffer};
pub(crate) type TestLog = Rc<RefCell<Vec<String>>>;
pub(crate) fn log_of(entries: &[&str]) -> Vec<String> {
entries.iter().map(|s| (*s).to_string()).collect()
}
struct NoopUpdater;
impl UpdaterTerminal for NoopUpdater {
fn insert_before(
&mut self,
_height: u16,
_draw_fn: Box<dyn FnOnce(&mut Buffer)>,
) -> io::Result<()> {
Ok(())
}
}
pub(crate) struct Mounted {
tree: Tree<'static>,
terminal: ratatui::Terminal<TestBackend>,
noop: NoopUpdater,
}
impl Mounted {
pub(crate) fn mount(el: impl Into<AnyElement<'static>>, mouse: bool) -> Self {
let el: &'static mut AnyElement<'static> = Box::leak(Box::new(el.into()));
let helper = el.helper();
let props = el.props_mut();
let mut this = Self {
tree: Tree::new_with_mouse(props, helper, mouse),
terminal: ratatui::Terminal::new(TestBackend::new(40, 10)).unwrap(),
noop: NoopUpdater,
};
this.frame();
this
}
fn frame(&mut self) {
self.tree.update_once(&mut self.noop);
self.terminal
.draw(|frame| {
let area = frame.area();
let mut drawer = ComponentDrawer::new(frame, area);
self.tree.draw_root(&mut drawer);
})
.unwrap();
}
pub(crate) fn dispatch(&mut self, kind: MouseEventKind, col: u16, row: u16) {
self.tree
.system_context_mut()
.input
.dispatch(Event::Mouse(MouseEvent {
kind,
column: col,
row,
modifiers: KeyModifiers::NONE,
}));
self.frame();
}
pub(crate) fn buffer(&mut self) -> Buffer {
self.terminal.backend().buffer().clone()
}
}