Refresh scenario viewport measurement when its identity changes

This commit is contained in:
2026-09-11 01:21:24 -07:00
parent 3978bbe23c
commit d114a271c5
4 changed files with 138 additions and 5 deletions
@@ -649,6 +649,8 @@ fn canvas_pane<'a, R: iced::advanced::text::Renderer + 'a>(
.width(Fill)
.height(Fill),
))
// A new owner/document needs its first measurement even at the same size.
.key((context.document, context.scenario))
.on_show(move |size| Message::ScenarioCanvas(CanvasEvent::Viewport(context, size)))
.on_resize(move |size| Message::ScenarioCanvas(CanvasEvent::Viewport(context, size))),
)
@@ -341,6 +341,85 @@ fn scenario_workspace_fit_uses_measured_inner_viewport_and_rejects_nonfinite_inp
);
}
#[test]
fn scenario_workspace_fit_reobserves_same_sized_owner_and_document_changes() {
use super::super::direct_tests::{navigation_event, navigation_fixture};
let (project, [a, b, _], [reference, _, _]) = navigation_fixture();
let mut app = App::with_project(project.clone());
let _ = app.update(Message::Select(a));
let _ = app.update(Message::Page(crate::app::Page::Behavior));
let size = Size::new(500., 570.);
let graph = Size::new(1800., 2400.);
let mut view = fixture_view(
&app.behavior.scenario,
app.scenario_context().unwrap(),
false,
68.,
);
let mut tree = widget::Tree::new(view.as_widget());
redraw(&mut view, &mut tree, size, &mut app);
let (_, first) = geometry(&mut view, &mut tree, size);
let measured = first.scrolls["scenario-canvas"].0.size();
assert_eq!(app.behavior.scenario.presentation.viewport, Some(measured));
let accepted = app.document.snapshot();
navigation_event(&mut app, |ctx| CanvasEvent::OpenUse(ctx, reference));
assert_eq!(app.scenario_context().unwrap().scenario, b);
assert_eq!(app.behavior.scenario.presentation.viewport, None);
view = fixture_view(
&app.behavior.scenario,
app.scenario_context().unwrap(),
false,
68.,
);
tree.diff(view.as_widget());
redraw(&mut view, &mut tree, size, &mut app);
let (_, second) = geometry(&mut view, &mut tree, size);
assert_eq!(second.scrolls["scenario-canvas"].0.size(), measured);
assert_eq!(app.behavior.scenario.presentation.viewport, Some(measured));
navigation_event(&mut app, |ctx| CanvasEvent::Zoom(ctx, None));
let fitted = app.behavior.scenario.presentation.scale(graph);
assert!(
fitted < 1.
&& graph.width * fitted <= measured.width - 16.
&& graph.height * fitted <= measured.height - 16.
);
assert!(std::sync::Arc::ptr_eq(&accepted, &app.document.snapshot()));
assert!(!app.document.can_undo());
let document = app.scenario_context().unwrap().document;
let mut replacement = App::with_project(project);
let _ = replacement.update(Message::Select(b));
let _ = replacement.update(Message::Page(crate::app::Page::Behavior));
assert_ne!(replacement.scenario_context().unwrap().document, document);
assert_eq!(replacement.behavior.scenario.presentation.viewport, None);
let accepted = replacement.document.snapshot();
view = fixture_view(
&replacement.behavior.scenario,
replacement.scenario_context().unwrap(),
false,
68.,
);
tree.diff(view.as_widget());
redraw(&mut view, &mut tree, size, &mut replacement);
let (_, replaced) = geometry(&mut view, &mut tree, size);
assert_eq!(replaced.scrolls["scenario-canvas"].0.size(), measured);
assert_eq!(
replacement.behavior.scenario.presentation.viewport,
Some(measured)
);
navigation_event(&mut replacement, |ctx| CanvasEvent::Zoom(ctx, None));
assert_eq!(
replacement.behavior.scenario.presentation.scale(graph),
fitted
);
assert!(std::sync::Arc::ptr_eq(
&accepted,
&replacement.document.snapshot()
));
assert!(!replacement.document.can_undo());
}
#[test]
fn scenario_workspace_open_and_back_restore_owner_and_mounted_scroll_after_preselection() {
use super::super::direct_tests::{navigation_event, navigation_fixture};
@@ -694,10 +773,9 @@ fn scenario_workspace_scaled_and_scrolled_scene_keeps_clicked_slots_and_message_
&canvas::Event::Mouse(event),
bounds,
mouse::Cursor::Available(cursor + scene.scroll_offset),
) {
if let Some(message) = action.into_inner().0 {
messages.push(message);
}
) && let Some(message) = action.into_inner().0
{
messages.push(message);
}
}
assert!(