Calculate scroll position based on middle item

This commit is contained in:
Anthony
2025-10-07 16:58:03 -04:00
parent 98f26b2b43
commit 0bcb4bd400
2 changed files with 39 additions and 1 deletions

View File

@@ -3097,6 +3097,25 @@ impl ScrollHandle {
}
}
/// Get the bottom child that's scrolled into view.
pub fn bottom_item(&self) -> usize {
let state = self.0.borrow();
let bottom = state.bounds.bottom() - state.offset.borrow().y;
match state.child_bounds.binary_search_by(|bounds| {
if bottom < bounds.top() {
Ordering::Greater
} else if bottom > bounds.bottom() {
Ordering::Less
} else {
Ordering::Equal
}
}) {
Ok(ix) => ix,
Err(ix) => ix.min(state.child_bounds.len().saturating_sub(1)),
}
}
/// Return the bounds into which this child is painted
pub fn bounds(&self) -> Bounds<Pixels> {
self.0.borrow().bounds
@@ -3198,6 +3217,21 @@ impl ScrollHandle {
}
}
/// Get the logical scroll bottom, based on a child index and a pixel offset.
pub fn logical_scroll_bottom(&self) -> (usize, Pixels) {
let ix = self.bottom_item();
let state = self.0.borrow();
if let Some(child_bounds) = state.child_bounds.get(ix) {
(
ix,
child_bounds.bottom() + state.offset.borrow().y - state.bounds.bottom(),
)
} else {
(ix, px(0.))
}
}
/// Get the count of children for scrollable item.
pub fn children_count(&self) -> usize {
self.0.borrow().child_bounds.len()

View File

@@ -944,7 +944,11 @@ impl SettingsWindow {
}
fn calculate_navbar_entry_from_scroll_position(&mut self) {
let scroll_index = self.scroll_handle.logical_scroll_top().0;
let top = self.scroll_handle.top_item();
let bottom = self.scroll_handle.bottom_item();
let scroll_index = (top + bottom) / 2;
let scroll_index = scroll_index.clamp(top, bottom);
let mut page_index = self.navbar_entry;
while !self.navbar_entries[page_index].is_root {