Merge pull request #1744 from ramox81/codex/layout-first-open-followups

Layouts: first opening follows the page setup; viewports picked by their frame
This commit is contained in:
Hakan Seven committed 2026-10-14 08:54:19 +03:00
commit 86df079182
8 files changed
+132 -6

No files matched your search

+93
View File
@@ -2437,6 +2437,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,
@@ -2857,6 +2860,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),
@@ -4832,6 +4836,30 @@ 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);
let block = layout.block_record;
// A sheet written for a layout never set up is not the
// page's; it is made again for the page.
drop_layout_viewports(&mut self.document, block);
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.
@@ -13053,6 +13081,71 @@ 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 block = Handle::NULL;
for object in document.objects.values_mut() {
if let ObjectType::Layout(layout) = object {
if layout.name == layout_name {
block = layout.block_record;
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;
layout.viewports.clear();
layout.viewport = Handle::NULL;
}
}
}
drop_layout_viewports(document, block);
}
/// Takes every viewport out of a layout's block (entity and membership).
pub(crate) fn drop_layout_viewports(document: &mut codec::CadDocument, block: Handle) {
if block.is_null() {
return;
}
let viewports: Vec<Handle> = document
.entities()
.filter_map(|entity| match entity {
EntityType::Viewport(viewport) if viewport.common.owner_handle == block => {
Some(viewport.common.handle)
}
_ => None,
})
.collect();
for handle in &viewports {
document.remove_entity(*handle);
}
if let Some(record) = document.block_records.iter_mut().find(|record| record.handle == block) {
record.entity_handles.retain(|handle| !viewports.contains(handle));
}
for object in document.objects.values_mut() {
if let ObjectType::Layout(layout) = object {
if layout.block_record == block {
layout.viewports.retain(|handle| !viewports.contains(handle));
if viewports.contains(&layout.viewport) {
layout.viewport = Handle::NULL;
}
}
}
}
}
/// 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);