Keep diagram viewport stable when modal remounts canvas

This commit is contained in:
2026-09-05 21:35:30 +03:00
parent 0a8a6f5f5c
commit 366ce4480d
2 changed files with 55 additions and 1 deletions
+4 -1
View File
@@ -1468,8 +1468,11 @@ impl App {
Message::WindowResized(size) => self.window_size = size,
Message::CanvasResized(size) => {
let first_measurement = self.canvas_size.is_none();
let size_changed = self.canvas_size != Some(size);
self.canvas_size = Some(size);
if first_measurement || self.fit_to_view {
// Modal overlays can remount the sensor and repeat on_show at
// the same size. Keep the viewport stable after model edits.
if first_measurement || (size_changed && self.fit_to_view) {
self.fit();
}
}
+51
View File
@@ -171,6 +171,57 @@ fn fit_adapts_to_canvas_returning_after_help_but_preserves_manual_navigation() {
assert_eq!((app.zoom, app.pan), manual);
}
#[test]
fn reopening_canvas_for_a_modal_preserves_viewport_after_route_edits() {
let mut p = Project::empty();
let sender = p.add(Kind::Activity, "Report", 0., 0.);
let target = p.add(Kind::Activity, "Receive", 600., 0.);
let edge = p.relate(RelationKind::Interaction, "Report signal", sender, target);
let diagram = p.ensure_diagram(Layer::Oa);
let mut app = App::with_project(p);
let canvas = iced::Size::new(900., 600.);
send(&mut app, Message::CanvasResized(canvas));
let viewport = (app.zoom, app.pan);
send(
&mut app,
Message::Command(Command::SetEdgeRoute {
diagram,
route: EdgeRoute {
edge,
waypoints: vec![Position { x: 400., y: 400. }],
label: Some(EdgeLabel {
fraction: 0.5,
offset: Position { x: 0., y: 150. },
}),
},
}),
);
assert_eq!((app.zoom, app.pan), viewport);
let mut fitted = App::with_project(app.project().clone());
send(&mut fitted, Message::CanvasResized(canvas));
assert_ne!(
(fitted.zoom, fitted.pan),
viewport,
"The edited route must change the fitted bounds to expose an accidental refit"
);
// The shared file modal remounts the canvas sensor. Its on_show measurement
// describes the existing viewport, not a user request to fit the edited model.
send(&mut app, Message::Export);
assert!(app.file_prompt.is_some());
send(&mut app, Message::CanvasResized(canvas));
assert_eq!((app.zoom, app.pan), viewport);
send(&mut app, Message::CancelFile);
send(&mut app, Message::CanvasResized(canvas));
assert_eq!((app.zoom, app.pan), viewport);
let compact = iced::Size::new(650., 400.);
send(&mut app, Message::CanvasResized(compact));
send(&mut fitted, Message::CanvasResized(compact));
assert_eq!((app.zoom, app.pan), (fitted.zoom, fitted.pan));
assert_ne!((app.zoom, app.pan), viewport);
}
#[test]
fn source_navigation_waits_for_editor_layout_and_cancels_on_edit() {
let p = fixture();