use crate::RowSource;
pub struct CumulativeHeights {
cumulative: Vec<f32>,
}
impl CumulativeHeights {
pub fn build<S: RowSource + ?Sized>(source: &S) -> Self {
let n = source.row_count();
let mut cumulative = vec![0.0f32; n + 1];
for i in 0..n {
cumulative[i + 1] = cumulative[i] + source.row_height(i);
}
Self { cumulative }
}
pub fn total_height(&self) -> f32 {
self.cumulative.last().copied().unwrap_or(0.0)
}
pub fn row_at_offset(&self, scroll_offset: f32) -> usize {
match self.cumulative.partition_point(|&c| c <= scroll_offset) {
0 => 0,
n => (n - 1).min(self.cumulative.len().saturating_sub(2)),
}
}
pub fn visible_range(
&self,
scroll_offset: f32,
viewport_height: f32,
) -> std::ops::Range<usize> {
let start = self.row_at_offset(scroll_offset);
let end_offset = scroll_offset + viewport_height;
let end = self
.cumulative
.partition_point(|&c| c < end_offset)
.min(self.cumulative.len().saturating_sub(1));
start..end
}
}