R8.3: sheet tab strip scrolls the chosen sheet in (Gitea #8)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude committed 2026-10-18 22:41:28 -04:00
1 parent 2ca53ef585
commit 1e6147ae77
9 files changed
+136 -23

No files matched your search

+15 -8
View File
@@ -109,18 +109,12 @@ impl Book {
let Some(tab) = self.active_tab() else {
return div().into_any_element();
};
let Some(choices) = visible(&tab.extra.sheets) else {
let Some(tabs) = strip(tab.id, &tab.extra.sheets) else {
return div().into_any_element();
};
let this = cx.entity();
let picked = this.clone();
let tabs = SheetTabs::new(
"table-sheets",
choices,
tab.extra.sheets.current.to_string(),
)
.placement(TabPlacement::Bottom)
.on_change(move |value, _, cx| {
let tabs = tabs.on_change(move |value, _, cx| {
let index: usize = value.parse().expect("sheet tabs are indexes");
picked.update(cx, |book, cx| book.show_sheet(index, cx));
})
@@ -310,6 +304,15 @@ impl Book {
}
}
/// Workbook `id`'s sheet tabs; each workbook keeps its own scroll.
fn strip(id: u64, sheets: &ely_lok::Sheets) -> Option<SheetTabs> {
let choices = visible(sheets)?;
Some(
SheetTabs::new(("table-sheets", id), choices, sheets.current.to_string())
.placement(TabPlacement::Bottom),
)
}
/// Visible sheets as tabs, once the shown one is known.
fn visible(sheets: &ely_lok::Sheets) -> Option<Vec<Choice>> {
let shown = sheets.list.get(sheets.current)?;
@@ -327,6 +330,10 @@ fn visible(sheets: &ely_lok::Sheets) -> Option<Vec<Choice>> {
)
}
#[cfg(test)]
#[path = "tests/strip.rs"]
mod strip_tests;
#[cfg(test)]
mod tests {
use super::*;
+96
View File
@@ -0,0 +1,96 @@
//! Each workbook's strip shows its own chosen sheet.
use ely_lok::{Sheet, Sheets};
use gpui::{
Bounds, Context, IntoElement, Modifiers, ParentElement as _, Pixels, Render, RenderOnce as _,
ScrollDelta, ScrollHandle, ScrollWheelEvent, Styled as _, TestAppContext, TouchPhase,
VisualTestContext, Window, div, point, px,
};
use super::strip;
struct Books {
book: u64,
sheets: Sheets,
scroll: Option<ScrollHandle>,
}
impl Render for Books {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let tabs = strip(self.book, &self.sheets)
.expect("tabs")
.render(window, cx)
.into_any_element();
let id = gpui::ElementId::from(("table-sheets", self.book));
let handle = window.use_keyed_state((id, "scroll"), cx, |_, _| ScrollHandle::new());
self.scroll = Some(handle.read(cx).clone());
div()
.w(px(640.))
.child(div().flex().items_center().px_2().child(tabs))
}
}
fn settle(cx: &mut VisualTestContext) {
for _ in 0..5 {
cx.run_until_parked();
cx.update(|window, _| window.refresh());
}
cx.run_until_parked();
}
/// The strip's viewport and the chosen tab in it.
fn place(
view: &gpui::Entity<Books>,
cx: &mut VisualTestContext,
) -> (Bounds<Pixels>, Bounds<Pixels>) {
view.read_with(cx, |view, _| {
let scroll = view.scroll.as_ref().expect("drawn");
let mut chosen = scroll
.bounds_for_item(view.sheets.current)
.expect("chosen tab");
chosen.origin += scroll.offset();
(scroll.bounds(), chosen)
})
}
fn shown(view: &gpui::Entity<Books>, cx: &mut VisualTestContext) -> bool {
let (viewport, chosen) = place(view, cx);
chosen.left() >= viewport.left() && chosen.right() <= viewport.right()
}
#[gpui::test]
fn a_switched_workbook_shows_its_chosen_sheet(cx: &mut TestAppContext) {
cx.update(ely_gpui_component::init_for_tests);
let sheets = Sheets {
current: 29,
list: (0..30)
.map(|n| Sheet {
name: format!("Sheet {n}"),
visible: true,
})
.collect(),
};
let (view, cx) = cx.add_window_view(|_, _| Books {
book: 1,
sheets,
scroll: None,
});
settle(cx);
assert!(shown(&view, cx), "the first draw shows the chosen sheet");
for book in [2, 1, 2] {
cx.simulate_event(ScrollWheelEvent {
position: point(px(60.), px(16.)),
delta: ScrollDelta::Pixels(point(px(0.), px(50_000.))),
modifiers: Modifiers::none(),
touch_phase: TouchPhase::Moved,
});
settle(cx);
assert!(!shown(&view, cx), "the wheel moves the chosen sheet away");
view.update(cx, |view, cx| {
view.book = book;
cx.notify();
});
settle(cx);
assert!(shown(&view, cx), "workbook {book} shows its chosen sheet");
}
}