use std::cell::Cell;
use std::rc::Rc;
use ratatui_core::layout::Rect;
use crate::geometry::Size;
use crate::surface::Surface;
use crate::view::{Element, RenderCtx, View, element};
#[derive(Clone, Debug, Default)]
pub struct RectProbe(Rc<Cell<Rect>>);
impl RectProbe {
pub fn new() -> Self {
Self::default()
}
pub fn rect(&self) -> Rect {
self.0.get()
}
pub fn wrap(&self, view: Element) -> Element {
element(Probe::new(view, self))
}
fn set(&self, rect: Rect) {
self.0.set(rect);
}
}
pub struct Probe {
inner: Element,
probe: RectProbe,
}
impl Probe {
pub fn new(inner: Element, probe: &RectProbe) -> Self {
Self {
inner,
probe: probe.clone(),
}
}
}
impl View for Probe {
fn measure(&self, available: Size) -> Size {
self.inner.measure(available)
}
fn render(&self, area: Rect, surface: &mut Surface, ctx: &RenderCtx) {
self.probe.set(area);
self.inner.render(area, surface, ctx);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::components::{Flex, Text};
use crate::style::Theme;
use crate::view::element;
use ratatui_core::layout::Rect;
#[test]
fn probe_reports_the_rect_a_view_was_painted_into() {
let probe = RectProbe::new();
assert_eq!(probe.rect(), Rect::ZERO, "an unpainted probe reads ZERO");
let root = Flex::column()
.fixed(1, element(Text::raw("header")))
.grow(1, probe.wrap(element(Text::raw("body"))));
let theme = Theme::default();
let _ = crate::testing::render(&root, 10, 5, &theme);
assert_eq!(probe.rect(), Rect::new(0, 1, 10, 4));
}
}