fix(layout): a new layout keeps its sheet until it is saved unopened

add_layout took the sheet viewport out, so the first viewport added to
the layout afterwards (by automation, or a plugin) was read as the sheet
and the scale pill and paper camera followed it. The sheet now stays and
is fitted to the page when the layout first opens; a layout saved before
that is still written without viewports.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 5.5 committed 2026-10-14 09:08:39 +03:00
1 parent 0a0d57ed25
commit 39c830d213
3 files changed
+24 -18

No files matched your search

+3
View File
@@ -1385,6 +1385,9 @@ impl Scene {
// LAYOUTCREATEVIEWPORT, it gets its first viewport.
let unopened = self.unopened_layouts.remove(&layout);
let initialized = self.initialize_layout_page_setup(&layout);
if unopened && !initialized {
self.fit_layout_sheet(&layout);
}
self.ensure_sheet_viewport(&layout);
if unopened || initialized {
self.add_layout_default_viewport(&layout);
+3 -9
View File
@@ -24,15 +24,9 @@ impl Scene {
/// cached layout-name list is invalidated on insert.
pub fn add_layout(&mut self, name: &str) -> codec::Result<Handle> {
let handle = self.document.add_layout(name)?;
// The layout has no viewports until it first opens (the sheet the
// document makes for it is placed at the origin, not on its page);
// opening it makes the sheet and, with LAYOUTCREATEVIEWPORT, its
// first viewport.
let block = match self.document.objects.get(&handle) {
Some(ObjectType::Layout(layout)) => layout.block_record,
_ => codec::Handle::NULL,
};
crate::scene::drop_layout_viewports(&mut self.document, block);
// Opening it fits the sheet the document made for it (placed at the
// origin) to its page and, with LAYOUTCREATEVIEWPORT, gives it its
// first viewport; saved before that, it is written with none.
self.unopened_layouts.insert(name.to_string());
self.bump_layout_epoch();
Ok(handle)
+18 -9
View File
@@ -4819,6 +4819,22 @@ impl Scene {
true
}
/// Fit a layout's sheet viewport to its page. (Taking the sheet out
/// instead would leave a viewport onto the model looking like the sheet.)
pub fn fit_layout_sheet(&mut self, layout_name: &str) {
let layout = self.document.objects.values().find_map(|object| match object {
ObjectType::Layout(layout) if layout.name == layout_name => Some(layout.clone()),
_ => None,
});
let Some(layout) = layout else {
return;
};
let sheet = Self::layout_sheet_viewport_handle(&self.document, &layout);
if let Some(EntityType::Viewport(vp)) = self.document.get_entity_mut(sheet) {
fit_sheet_viewport(vp, layout.min_limits, layout.max_limits);
}
}
/// Gives a layout whose page setup was never initialized (no paper size
/// and no media name, as the reference leaves a layout until it is first
/// opened) the default page setup; true when it did.
@@ -4831,16 +4847,9 @@ impl Scene {
return false;
}
crate::scene::apply_default_page_setup(layout, &plot_style);
let limits = (layout.min_limits, layout.max_limits);
let layout = layout.clone();
// A sheet written for a layout never set up is not the
// page's; it is fitted to the page. (Taking it out instead
// would leave a viewport onto the model looking like the
// sheet.)
let sheet = Self::layout_sheet_viewport_handle(&self.document, &layout);
if let Some(EntityType::Viewport(vp)) = self.document.get_entity_mut(sheet) {
fit_sheet_viewport(vp, limits.0, limits.1);
}
// page's; it is fitted to the page.
self.fit_layout_sheet(layout_name);
self.bump_layout_epoch();
return true;
}