Layouts: first opening follows the page setup; viewports picked by their frame

- A layout opens for the first time when its page setup was never
  initialized (no paper size, no media name) or it was created in this
  session; its page setup is initialized then, and with
  LAYOUTCREATEVIEWPORT it gets its first viewport. A layout never opened
  is saved with an uninitialized page setup and no viewports, so it gets
  its viewport when the file is opened again, here or in the reference.
- Select Viewport for view: a viewport is selected when the pick box
  (PICKBOX pixels at the sheet's zoom) touches its frame; a pick well
  inside or outside selects nothing and the prompt repeats.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-10-13 12:02:26 +03:00
1 parent 006be8909e
commit c55dbb886e
7 files changed
+88 -6

No files matched your search

+58
View File
@@ -2360,6 +2360,9 @@ pub struct Scene {
/// Layouts created in this session and not opened yet: the first time
/// one opens it gets the LAYOUTCREATEVIEWPORT viewport.
pub(crate) unopened_layouts: std::collections::HashSet<String>,
/// The plot style table a layout's page setup takes when it is
/// initialized on first opening.
pub(crate) new_layout_plot_style: String,
layout_names_cache: RefCell<Option<(u64, std::sync::Arc<Vec<String>>)>>,
/// Bump on any annotation-scale list mutation.
scale_epoch: u64,
@@ -2773,6 +2776,7 @@ impl Scene {
layout_type_names_cache: RefCell::new(None),
layout_epoch: 0,
unopened_layouts: Default::default(),
new_layout_plot_style: String::new(),
layout_names_cache: RefCell::new(None),
scale_epoch: 0,
scale_picker_cache: RefCell::new(None),
@@ -4737,6 +4741,26 @@ impl Scene {
true
}
/// 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.
pub fn initialize_layout_page_setup(&mut self, layout_name: &str) -> bool {
let plot_style = self.new_layout_plot_style.clone();
for object in self.document.objects.values_mut() {
if let ObjectType::Layout(layout) = object {
if layout.name == layout_name {
if !page_setup_uninitialized(layout) {
return false;
}
crate::scene::apply_default_page_setup(layout, &plot_style);
self.bump_layout_epoch();
return true;
}
}
}
false
}
/// The viewport a layout gets when it first opens (LAYOUTCREATEVIEWPORT),
/// as the reference makes it: centred on the printable area, 0.8 of its
/// width and height, showing the model's extents.
@@ -12732,6 +12756,40 @@ vis_index={:.1} visible_probe={:.1}",
}
}
/// A page setup never initialized: no paper size and no media name (the
/// reference writes a layout so until it is first opened).
pub fn page_setup_uninitialized(layout: &codec::objects::Layout) -> bool {
layout.paper_size.trim().is_empty() && layout.paper_width <= 0.0 && layout.paper_height <= 0.0
}
/// A layout written as never opened: the page setup fields back to the
/// uninitialized state and no viewports, as the reference stores a layout
/// it has not opened yet.
pub(crate) fn write_layout_unopened(document: &mut codec::CadDocument, layout_name: &str) {
let fresh = codec::objects::Layout::new(layout_name);
let mut viewports = Vec::new();
for object in document.objects.values_mut() {
if let ObjectType::Layout(layout) = object {
if layout.name == layout_name {
layout.paper_size = fresh.paper_size.clone();
layout.paper_width = fresh.paper_width;
layout.paper_height = fresh.paper_height;
layout.plot_rotation = fresh.plot_rotation;
layout.plot_paper_units = fresh.plot_paper_units;
layout.min_limits = fresh.min_limits;
layout.max_limits = fresh.max_limits;
layout.min_extents = fresh.min_extents;
layout.max_extents = fresh.max_extents;
viewports = std::mem::take(&mut layout.viewports);
layout.viewport = Handle::NULL;
}
}
}
for handle in viewports {
document.remove_entity(handle);
}
}
/// LAYOUTCREATEVIEWPORT: a layout opened for the first time gets a viewport.
static LAYOUT_CREATE_VIEWPORT: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(true);