use std::ops::Range;
use egui::Rect;
pub(super) struct PlotLayout {
pub(super) range: Range<usize>,
pub(super) slot_w: f32,
pub(super) base_x: f32,
}
impl PlotLayout {
pub(super) fn new(
rect: Rect,
present_len: usize,
selection: Option<(usize, usize)>,
history_capacity: usize,
) -> Self {
match selection {
Some((lo, hi)) if lo < present_len => {
let hi = hi.min(present_len - 1);
let vis_n = (hi - lo + 1).max(1);
let slot_w = rect.width() / vis_n as f32;
Self {
range: lo..hi + 1,
slot_w,
base_x: rect.left(),
}
}
_ => {
let slot_w = rect.width() / history_capacity as f32;
Self {
range: 0..present_len,
slot_w,
base_x: rect.right() - present_len as f32 * slot_w,
}
}
}
}
pub(super) fn cursor_x(&self, idx: usize) -> Option<f32> {
if !self.range.contains(&idx) {
return None;
}
Some(self.base_x + (idx - self.range.start) as f32 * self.slot_w + self.slot_w * 0.5)
}
pub(super) fn hover_to_idx(&self, x: f32) -> Option<usize> {
let rel = (x - self.base_x) / self.slot_w;
if rel < 0.0 {
return None;
}
let idx = self.range.start + rel as usize;
(idx < self.range.end).then_some(idx)
}
}