use ratatui::Frame;
use ratatui::layout::Position;
use ratatui::layout::Rect;
use tui_pane::CpuMonitor;
use tui_pane::CpuUsage;
use tui_pane::Hittable;
use tui_pane::RenderFocus;
use tui_pane::Renderable;
use tui_pane::Viewport;
use crate::channel::Receiver;
use crate::config::CpuConfig;
use crate::tui::hit_test::HoverTarget;
use crate::tui::panes::PaneId;
use crate::tui::panes::RenderStyles;
use crate::tui::panes::cpu;
use crate::tui::render_context::PaneRenderCtx;
pub struct CpuPane {
pub viewport: Viewport,
pub focus: RenderFocus,
content: Option<CpuUsage>,
monitor: CpuMonitor,
row_rects: Vec<(Rect, usize)>,
}
impl CpuPane {
pub fn new(cpu_config: &CpuConfig) -> Self {
let mut pane = Self {
viewport: Viewport::new(),
focus: RenderFocus::inactive(),
content: None,
monitor: CpuMonitor::new(cpu_config.poll_ms),
row_rects: Vec::new(),
};
pane.install_placeholder();
pane
}
pub fn tick(&mut self) {
if let Some(usage) = self.monitor.latest() {
self.content = Some(usage);
}
}
pub const fn sample_rx(&self) -> &Receiver<CpuUsage> { self.monitor.receiver() }
pub const fn is_sampling(&self) -> bool { self.monitor.is_sampling() }
pub fn reset(&mut self, cpu_config: &CpuConfig) {
self.monitor = CpuMonitor::new(cpu_config.poll_ms);
self.install_placeholder();
}
pub fn install_placeholder(&mut self) {
self.content = Some(self.monitor.placeholder_cpu_usage());
}
pub const fn content(&self) -> Option<&CpuUsage> { self.content.as_ref() }
pub fn set_row_rects(&mut self, rects: Vec<(Rect, usize)>) { self.row_rects = rects; }
pub fn clear_row_rects(&mut self) { self.row_rects.clear(); }
}
impl Renderable<PaneRenderCtx<'_>> for CpuPane {
fn render(&mut self, frame: &mut Frame<'_>, area: Rect, ctx: &PaneRenderCtx<'_>) {
let styles = RenderStyles {
readonly_label: ratatui::style::Style::default().fg(tui_pane::label_color()),
chrome: tui_pane::default_pane_chrome(),
};
cpu::render_cpu_pane_body(frame, area, self, &styles, ctx);
}
}
impl Hittable<HoverTarget> for CpuPane {
fn hit_test_at(&self, pos: Position) -> Option<HoverTarget> {
let (_rect, row) = self
.row_rects
.iter()
.find(|(rect, _)| rect.contains(pos))
.copied()?;
Some(HoverTarget::PaneRow {
pane: PaneId::Cpu,
row,
})
}
}