mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-28 12:46:48 -06:00
Merge pull request #2497 from marcoarnulfo:fix/full-column-extend-scroll
This commit is contained in:
@@ -731,9 +731,16 @@ pub fn show(app: &mut SheetApp, ui: &mut egui::Ui) {
|
||||
// Keep the active cell (or the moving end of an extension) visible after keyboard moves.
|
||||
if app.grid.ensure_visible {
|
||||
app.grid.ensure_visible = false;
|
||||
let cell = if std::mem::take(&mut app.grid.reveal_moving_end) { sel.moving_end() } else { sel.active };
|
||||
let moving = std::mem::take(&mut app.grid.reveal_moving_end);
|
||||
let cell = if moving { sel.moving_end() } else { sel.active };
|
||||
let from = app.grid.reveal_from.take();
|
||||
let target = app.editor.as_ref().and_then(|e| e.point_cell).unwrap_or(cell);
|
||||
// A whole column's moving end sits on the sheet's last row (a whole row's on its last
|
||||
// column): when an extension moves it only across, the view keeps its place the other way.
|
||||
// An extension that reaches the last row itself (Ctrl+Shift+Down past the data) still
|
||||
// follows it.
|
||||
let extended = (moving && target == cell).then(|| sel.current());
|
||||
let before = view.scroll;
|
||||
if paper {
|
||||
crate::paper_view::ensure_covers(app, &wb, si, target);
|
||||
geo = make_geo(app, view.scroll);
|
||||
@@ -761,6 +768,12 @@ pub fn show(app: &mut SheetApp, ui: &mut egui::Ui) {
|
||||
} else if from.is_some_and(|f| f.col >= geo.fc) {
|
||||
view.scroll.x = 0.0;
|
||||
}
|
||||
if extended.is_some_and(|r| r.is_full_cols()) && from.is_some_and(|f| f.row == cell.row) {
|
||||
view.scroll.y = before.y;
|
||||
}
|
||||
if extended.is_some_and(|r| r.is_full_rows()) && from.is_some_and(|f| f.col == cell.col) {
|
||||
view.scroll.x = before.x;
|
||||
}
|
||||
view.scroll = view.scroll.max(egui::Vec2::ZERO);
|
||||
geo = make_geo(app, view.scroll);
|
||||
}
|
||||
|
||||
@@ -290,3 +290,77 @@ fn down_from_a_frozen_header_row_goes_to_row_2_at_the_top_from_far_down() {
|
||||
assert_eq!(scroll(&h).y, 0.0);
|
||||
assert!(visible(&h, "A2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shift_arrows_on_a_whole_column_leave_the_rows_where_they_are() {
|
||||
// A whole column's moving end is on the sheet's last row: Shift+Right from Ctrl+Space must
|
||||
// widen it to the next columns without scrolling down to the bottom of the sheet.
|
||||
let mut h = harness();
|
||||
h.state_mut().session.execute("selection.set", json!({"cell": "A100"})).unwrap();
|
||||
h.state_mut().grid.ensure_visible = true;
|
||||
h.run_steps(2);
|
||||
let down = scroll(&h).y;
|
||||
assert!(down > 0.0 && visible(&h, "A100"));
|
||||
h.state_mut().session.execute("selection.column", json!({})).unwrap();
|
||||
h.run_steps(2);
|
||||
key(&mut h, Key::ArrowRight, Modifiers::SHIFT);
|
||||
assert_eq!(h.state().session.active().unwrap().selection.current(), RangeRef::parse("A:B").unwrap());
|
||||
assert_eq!(scroll(&h).y, down, "the view stays on the rows it showed");
|
||||
// The columns still scroll to follow the extension.
|
||||
for _ in 0..30 {
|
||||
key(&mut h, Key::ArrowRight, Modifiers::SHIFT);
|
||||
}
|
||||
assert!(visible(&h, "AF100") && !visible(&h, "A100"));
|
||||
assert_eq!(scroll(&h).y, down);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shift_arrows_on_a_whole_row_leave_the_columns_where_they_are() {
|
||||
let mut h = harness();
|
||||
h.state_mut().session.execute("selection.set", json!({"cell": "CA1"})).unwrap();
|
||||
h.state_mut().grid.ensure_visible = true;
|
||||
h.run_steps(2);
|
||||
let right = scroll(&h).x;
|
||||
assert!(right > 0.0 && visible(&h, "CA1"));
|
||||
h.state_mut().session.execute("selection.row", json!({})).unwrap();
|
||||
h.run_steps(2);
|
||||
key(&mut h, Key::ArrowDown, Modifiers::SHIFT);
|
||||
assert_eq!(h.state().session.active().unwrap().selection.current(), RangeRef::parse("1:2").unwrap());
|
||||
assert_eq!(scroll(&h).x, right, "the view stays on the columns it showed");
|
||||
// The rows still scroll to follow the extension.
|
||||
for _ in 0..60 {
|
||||
key(&mut h, Key::ArrowDown, Modifiers::SHIFT);
|
||||
}
|
||||
assert!(visible(&h, "CA62") && !visible(&h, "CA1"));
|
||||
assert_eq!(scroll(&h).x, right);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_shift_down_past_the_data_to_the_whole_column_still_follows_the_moving_end() {
|
||||
// The second Ctrl+Shift+Down from A1 runs past A200 to the last row: the selection becomes the
|
||||
// whole column, and the view still follows its moving end down the sheet.
|
||||
let mut h = harness();
|
||||
key(&mut h, Key::ArrowDown, CTRL_SHIFT);
|
||||
assert_extended(&h, "A1", "A200");
|
||||
let at_200 = scroll(&h).y;
|
||||
key(&mut h, Key::ArrowDown, CTRL_SHIFT);
|
||||
assert_eq!(h.state().session.active().unwrap().selection.current(), RangeRef::parse("A:A").unwrap());
|
||||
assert!(scroll(&h).y > at_200, "the view follows the extension to the last row");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ctrl_shift_right_on_a_whole_column_follows_across_and_keeps_the_rows() {
|
||||
// Ctrl+Space then Ctrl+Shift+Right selects every column: the view follows the moving end to
|
||||
// the last column and stays on the rows it showed.
|
||||
let mut h = harness();
|
||||
h.state_mut().session.execute("selection.set", json!({"cell": "A100"})).unwrap();
|
||||
h.state_mut().grid.ensure_visible = true;
|
||||
h.run_steps(2);
|
||||
let down = scroll(&h).y;
|
||||
h.state_mut().session.execute("selection.column", json!({})).unwrap();
|
||||
h.run_steps(2);
|
||||
key(&mut h, Key::ArrowRight, CTRL_SHIFT);
|
||||
assert_eq!(h.state().session.active().unwrap().selection.current(), RangeRef::parse("A:XFD").unwrap());
|
||||
assert!(scroll(&h).x > 0.0, "the view follows the extension across");
|
||||
assert_eq!(scroll(&h).y, down, "the view stays on the rows it showed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user