feat(plot): page setup manager — named setups, layouts, <none>/<previous>
Restructure the plot dialog into a style-manager-style master/detail: a left list of page setups plus a right settings editor. The list shows <none> (defaults + PDF) and <previous> (the settings the dialog opened with), then the drawing's layouts (*Model*, *Layout1*, …) and its standalone named page setups. - Named page setups live in the ACAD_PLOTSETTINGS dictionary (src/scene/page_setup.rs: names/get/save/delete/rename, creating the dictionary if absent); DWG round-trip verified. - Toolbar New / Copy / Delete | Set current / Preview / Print. Selecting a row loads it into the editor; Set current writes to the active layout. Copy duplicates a layout or a setup into a new named setup; Delete/Rename apply only to named setups. - Scene::plot_settings_for(name) generalizes effective_plot_settings so any layout's settings can be loaded; on open the settings are snapshotted for <previous>. - Default selection: model space → <none>; a layout → its own setup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d37aacd895
commit
a1ee4d9269
8 changed files with 649 additions and 25 deletions
|
|
@ -39,6 +39,39 @@ fn format_annotation_scale_name(anno: f32) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// `<none>` / `<previous>` are pseudo-entries, not real page setups.
|
||||
pub(super) fn is_special_entry(s: &str) -> bool {
|
||||
s == crate::ui::window::plot::SETUP_NONE || s == crate::ui::window::plot::SETUP_PREV
|
||||
}
|
||||
|
||||
/// A page-setup list entry wrapped in `*…*` is a layout (its embedded page
|
||||
/// setup), not a standalone named page setup.
|
||||
pub(super) fn is_layout_entry(s: &str) -> bool {
|
||||
s.len() >= 2 && s.starts_with('*') && s.ends_with('*')
|
||||
}
|
||||
|
||||
/// The layout name inside a `*name*` list entry.
|
||||
pub(super) fn layout_entry_name(s: &str) -> &str {
|
||||
s.trim_start_matches('*').trim_end_matches('*')
|
||||
}
|
||||
|
||||
/// Infer the closest A-series paper label and orientation from sheet
|
||||
/// dimensions (mm). Falls back to A4 when nothing is close.
|
||||
pub(super) fn paper_label_from_dims(w: f64, h: f64) -> (String, String) {
|
||||
use crate::io::paper_sizes::PaperSize;
|
||||
let orient = if w >= h { "Landscape" } else { "Portrait" };
|
||||
let (short, long) = if w <= h { (w, h) } else { (h, w) };
|
||||
let mut best = ("A4".to_string(), f64::INFINITY);
|
||||
for p in PaperSize::ALL {
|
||||
let (pw, ph) = p.dimensions_mm(); // portrait: pw < ph
|
||||
let err = (pw - short).abs() + (ph - long).abs();
|
||||
if err < best.1 {
|
||||
best = (p.label().to_string(), err);
|
||||
}
|
||||
}
|
||||
(best.0, orient.to_string())
|
||||
}
|
||||
|
||||
pub(super) fn parse_plot_scale(s: &str) -> (f64, f64) {
|
||||
if s == "Fit" {
|
||||
return (1.0, 1.0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue