mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-24 02:16:56 -06:00
ui: scroll active page into view when selection changes
This commit is contained in:
@@ -24,6 +24,10 @@ display_name = "VanTan"
|
||||
real_name = "Tyler Jennings"
|
||||
display_name = "tylerjenningsw"
|
||||
|
||||
[people.SiadeLucas]
|
||||
real_name = "Siade Lucas"
|
||||
sync_github_name = true
|
||||
|
||||
[people.Silvertree2010]
|
||||
display_name = "Netter"
|
||||
sync_github_name = false
|
||||
|
||||
@@ -229,6 +229,8 @@ fn pages(app: &mut FigApp, ui: &mut Ui) {
|
||||
let mut move_to: Option<(NodeId, String)> = None;
|
||||
// Pages are dragged up and down the list to reorder them.
|
||||
let mut reorder = crate::list_drag::ListDrag::in_order(ui, "pages");
|
||||
let scroll_to_cur = app.ui.pages_seen_page != Some(cur);
|
||||
app.ui.pages_seen_page = Some(cur);
|
||||
// A long list scrolls in its own area, so the layers keep their room below it.
|
||||
let max_h = pages_list_height(app.ui.pages_height, ui.available_height());
|
||||
let mut moved = egui::ScrollArea::vertical().id_salt("pages_list").max_height(max_h).show(ui, |ui| {
|
||||
@@ -238,6 +240,9 @@ fn pages(app: &mut FigApp, ui: &mut Ui) {
|
||||
}
|
||||
let sense = if filtering { Sense::click() } else { Sense::click_and_drag() };
|
||||
let (r, resp) = ui.allocate_exact_size(vec2(w, 32.0), sense);
|
||||
if scroll_to_cur && id == cur {
|
||||
ui.scroll_to_rect(r, None);
|
||||
}
|
||||
if !filtering {
|
||||
reorder.row_by(&resp, k, r, || if divider { tr("Divider").to_string() } else { name.clone() });
|
||||
}
|
||||
|
||||
@@ -507,3 +507,30 @@ fn the_pages_list_keeps_three_rows_and_leaves_the_layers_room() {
|
||||
// A panel too short for both keeps the three rows.
|
||||
assert_eq!(pages_list_height(Some(500.0), 100.0), 3.0 * ROW);
|
||||
}
|
||||
|
||||
/// Selecting a page that is far down the list automatically scrolls it into view.
|
||||
#[test]
|
||||
fn selecting_a_distant_page_scrolls_it_into_view() {
|
||||
let mut s = Session::new();
|
||||
let rect = id(s.execute("shape.rectangle", &json!({"x": 0, "y": 0, "width": 10, "height": 10})).unwrap());
|
||||
for _ in 0..40 {
|
||||
s.execute("page.add", &json!({})).unwrap();
|
||||
}
|
||||
let pages = s.doc().unwrap().pages.clone();
|
||||
let first = pages[0];
|
||||
let last = *pages.last().unwrap();
|
||||
s.execute("page.select", &json!({"id": first})).unwrap();
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
let mut u = Ui::new(s);
|
||||
let layer = u.row_at(rect);
|
||||
u.frame(vec![]);
|
||||
// Select the last page.
|
||||
u.app.run("page.select", json!({"id": last}));
|
||||
for _ in 0..15 {
|
||||
u.frame(vec![]);
|
||||
}
|
||||
assert_eq!(u.app.ui.pages_seen_page, Some(last));
|
||||
let opened = pages_down_to(&mut u, layer.y - 60.0);
|
||||
let top = pages.iter().position(|p| Some(p) == opened.first()).unwrap();
|
||||
assert!(top > 20, "the list scrolled past its first pages to reveal the selection (top row: page {top})");
|
||||
}
|
||||
|
||||
@@ -495,6 +495,8 @@ pub struct UiState {
|
||||
pub page_filter: String,
|
||||
/// The height asked for the pages list (`None`: a share of the panel).
|
||||
pub pages_height: Option<f32>,
|
||||
/// The active page when last drawn in the pages list, to scroll it into view when selected.
|
||||
pub pages_seen_page: Option<NodeId>,
|
||||
pub expanded: BTreeSet<NodeId>,
|
||||
/// The layer being renamed in the layers panel.
|
||||
pub rename: Option<layers::Rename>,
|
||||
@@ -667,6 +669,7 @@ impl Default for UiState {
|
||||
page_search: false,
|
||||
page_filter: String::new(),
|
||||
pages_height: None,
|
||||
pages_seen_page: None,
|
||||
expanded: BTreeSet::new(),
|
||||
rename: None,
|
||||
rename_page: None,
|
||||
|
||||
Reference in New Issue
Block a user