feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
//! Plot / Print dialog — a full plot setup surface rendered as an in-canvas
|
|
|
|
|
//! modal (Plan B). Bundles printer choice, paper, scale, offset, plot style,
|
|
|
|
|
//! quality and output options into one dialog; on commit it either sends the
|
|
|
|
|
//! current layout to a system printer (with the chosen options) or writes a
|
|
|
|
|
//! PDF. Styled to match the other OCS dialogs (dark pills + fields).
|
|
|
|
|
|
|
|
|
|
use crate::app::Message;
|
|
|
|
|
use crate::io::paper_sizes::PaperSize;
|
|
|
|
|
use iced::widget::{
|
2026-07-09 12:25:46 +03:00
|
|
|
button, checkbox, column, container, mouse_area, pick_list, row, scrollable, text, text_input,
|
|
|
|
|
Space,
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
};
|
|
|
|
|
use iced::{Background, Border, Color, Element, Fill, Length, Theme};
|
|
|
|
|
|
|
|
|
|
const TB: Color = Color { r: 0.13, g: 0.13, b: 0.13, a: 1.0 };
|
|
|
|
|
const BG: Color = Color { r: 0.15, g: 0.15, b: 0.15, a: 1.0 };
|
|
|
|
|
const BORDER: Color = Color { r: 0.35, g: 0.35, b: 0.35, a: 1.0 };
|
|
|
|
|
const TEXT: Color = Color { r: 0.88, g: 0.88, b: 0.88, a: 1.0 };
|
|
|
|
|
const DIM: Color = Color { r: 0.55, g: 0.55, b: 0.55, a: 1.0 };
|
|
|
|
|
const ACCENT: Color = Color { r: 0.25, g: 0.50, b: 0.85, a: 1.0 };
|
|
|
|
|
const FIELD: Color = Color { r: 0.10, g: 0.10, b: 0.10, a: 1.0 };
|
2026-07-09 12:25:46 +03:00
|
|
|
const ACTIVE: Color = Color { r: 0.20, g: 0.40, b: 0.70, a: 1.0 };
|
|
|
|
|
const LIST: Color = Color { r: 0.12, g: 0.12, b: 0.12, a: 1.0 };
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
|
|
|
|
|
/// Sentinel entries in the printer dropdown (not real printer names).
|
|
|
|
|
pub const OUT_DEFAULT: &str = "System default printer";
|
|
|
|
|
pub const OUT_PDF: &str = "Save to PDF file…";
|
|
|
|
|
|
2026-07-09 12:25:46 +03:00
|
|
|
/// Top-of-list entries: no page setup (defaults + PDF), and the last-used
|
|
|
|
|
/// settings captured when the dialog opened.
|
|
|
|
|
pub const SETUP_NONE: &str = "<none>";
|
|
|
|
|
pub const SETUP_PREV: &str = "<previous>";
|
|
|
|
|
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
/// One of the many boolean plot options (folded into a single message so the
|
|
|
|
|
/// dialog needn't carry a variant per checkbox).
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
|
pub enum PlotFlag {
|
|
|
|
|
Center,
|
|
|
|
|
ScaleLw,
|
|
|
|
|
Mono,
|
|
|
|
|
Lineweights,
|
|
|
|
|
WithStyles,
|
|
|
|
|
Transparency,
|
|
|
|
|
PaperspaceLast,
|
|
|
|
|
HidePaperspace,
|
|
|
|
|
Stamp,
|
|
|
|
|
SaveLayout,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Every edit the Plot dialog can emit. Wrapped in `Message::PlotDlg` so the
|
|
|
|
|
/// top-level match stays a single arm.
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub enum PlotDlgMsg {
|
|
|
|
|
Close,
|
|
|
|
|
Commit,
|
|
|
|
|
Preview,
|
|
|
|
|
Printer(String),
|
|
|
|
|
Paper(String),
|
|
|
|
|
Orientation(String),
|
|
|
|
|
Rotation(String),
|
|
|
|
|
Area(String),
|
|
|
|
|
Scale(String),
|
|
|
|
|
Quality(String),
|
|
|
|
|
Shade(String),
|
|
|
|
|
Copies(String),
|
|
|
|
|
OffsetX(String),
|
|
|
|
|
OffsetY(String),
|
|
|
|
|
Dpi(String),
|
|
|
|
|
Flag(PlotFlag),
|
|
|
|
|
LoadStyle,
|
|
|
|
|
ClearStyle,
|
|
|
|
|
PickWindow,
|
2026-07-09 12:25:46 +03:00
|
|
|
// ── Named page-setup manager ─────────────────────────────────────────
|
|
|
|
|
/// Pick a named page setup (loads its values into the editor).
|
|
|
|
|
SelectSetup(String),
|
|
|
|
|
/// Write the current editor values into the active layout.
|
|
|
|
|
SetCurrent,
|
|
|
|
|
/// Create a new named page setup from the current editor values.
|
|
|
|
|
NewSetup,
|
|
|
|
|
/// Duplicate the selected page setup.
|
|
|
|
|
CopySetup,
|
|
|
|
|
/// Begin an inline rename of the given page setup row.
|
|
|
|
|
RenameStart(String),
|
|
|
|
|
/// Delete the selected named page setup.
|
|
|
|
|
DeleteSetup,
|
|
|
|
|
/// Live edit of the new/rename name field.
|
|
|
|
|
NameInput(String),
|
|
|
|
|
/// Confirm the new/rename name.
|
|
|
|
|
NameCommit,
|
|
|
|
|
/// Cancel the new/rename name row.
|
|
|
|
|
NameCancel,
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Transient state backing the Plot dialog. Seeded from the layout's plot
|
|
|
|
|
/// settings when the dialog opens; consumed on commit.
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct PlotDialogState {
|
|
|
|
|
/// Printer names discovered on the system (via `lpstat`), never the
|
|
|
|
|
/// sentinels.
|
|
|
|
|
pub printers: Vec<String>,
|
|
|
|
|
/// Chosen printer name, or `None` for the system default.
|
|
|
|
|
pub printer: Option<String>,
|
|
|
|
|
/// Output goes to a PDF file instead of a printer.
|
|
|
|
|
pub to_file: bool,
|
|
|
|
|
pub paper: String,
|
|
|
|
|
pub orientation: String,
|
|
|
|
|
pub rotation: String,
|
|
|
|
|
pub copies: String,
|
|
|
|
|
pub area: String,
|
|
|
|
|
pub center: bool,
|
|
|
|
|
pub offset_x: String,
|
|
|
|
|
pub offset_y: String,
|
|
|
|
|
pub scale: String,
|
|
|
|
|
pub scale_lw: bool,
|
|
|
|
|
pub quality: String,
|
|
|
|
|
pub dpi: String,
|
|
|
|
|
pub shade: String,
|
|
|
|
|
pub mono: bool,
|
|
|
|
|
pub lineweights: bool,
|
|
|
|
|
pub with_styles: bool,
|
|
|
|
|
pub transparency: bool,
|
|
|
|
|
pub paperspace_last: bool,
|
|
|
|
|
pub hide_paperspace: bool,
|
|
|
|
|
pub stamp: bool,
|
|
|
|
|
pub save_layout: bool,
|
|
|
|
|
/// Display name of the active plot style table ("" = none).
|
|
|
|
|
pub style_name: String,
|
2026-07-09 12:25:46 +03:00
|
|
|
/// Named page setups in the document (refreshed when the dialog opens).
|
|
|
|
|
pub page_setups: Vec<String>,
|
|
|
|
|
/// Currently selected named page setup ("" = none / current layout).
|
|
|
|
|
pub selected_setup: String,
|
|
|
|
|
/// When `Some`, a name-entry row is showing (for New / Rename).
|
|
|
|
|
pub name_input: Option<String>,
|
|
|
|
|
/// `true` when `name_input` is renaming the selected setup, else creating.
|
|
|
|
|
pub name_rename: bool,
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for PlotDialogState {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
printers: Vec::new(),
|
|
|
|
|
printer: None,
|
|
|
|
|
to_file: false,
|
|
|
|
|
paper: "A4".into(),
|
|
|
|
|
orientation: "Landscape".into(),
|
|
|
|
|
rotation: "0°".into(),
|
|
|
|
|
copies: "1".into(),
|
|
|
|
|
area: "Window".into(),
|
|
|
|
|
center: true,
|
|
|
|
|
offset_x: "0.0".into(),
|
|
|
|
|
offset_y: "0.0".into(),
|
|
|
|
|
scale: "Fit".into(),
|
|
|
|
|
scale_lw: true,
|
|
|
|
|
quality: "Normal".into(),
|
|
|
|
|
dpi: "300".into(),
|
|
|
|
|
shade: "As displayed".into(),
|
|
|
|
|
mono: false,
|
|
|
|
|
lineweights: true,
|
|
|
|
|
with_styles: true,
|
|
|
|
|
transparency: false,
|
|
|
|
|
paperspace_last: false,
|
|
|
|
|
hide_paperspace: false,
|
|
|
|
|
stamp: false,
|
|
|
|
|
save_layout: false,
|
|
|
|
|
style_name: String::new(),
|
2026-07-09 12:25:46 +03:00
|
|
|
page_setups: Vec::new(),
|
|
|
|
|
selected_setup: String::new(),
|
|
|
|
|
name_input: None,
|
|
|
|
|
name_rename: false,
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PlotDialogState {
|
2026-07-09 12:25:46 +03:00
|
|
|
/// Copy the plot-setting fields (paper, scale, output options, …) from
|
|
|
|
|
/// `o`, leaving list / rename / runtime UI state untouched. Used to restore
|
|
|
|
|
/// the `<previous>` snapshot.
|
|
|
|
|
pub fn copy_settings_from(&mut self, o: &PlotDialogState) {
|
|
|
|
|
self.printer = o.printer.clone();
|
|
|
|
|
self.to_file = o.to_file;
|
|
|
|
|
self.paper = o.paper.clone();
|
|
|
|
|
self.orientation = o.orientation.clone();
|
|
|
|
|
self.rotation = o.rotation.clone();
|
|
|
|
|
self.copies = o.copies.clone();
|
|
|
|
|
self.area = o.area.clone();
|
|
|
|
|
self.center = o.center;
|
|
|
|
|
self.offset_x = o.offset_x.clone();
|
|
|
|
|
self.offset_y = o.offset_y.clone();
|
|
|
|
|
self.scale = o.scale.clone();
|
|
|
|
|
self.scale_lw = o.scale_lw;
|
|
|
|
|
self.quality = o.quality.clone();
|
|
|
|
|
self.dpi = o.dpi.clone();
|
|
|
|
|
self.shade = o.shade.clone();
|
|
|
|
|
self.mono = o.mono;
|
|
|
|
|
self.lineweights = o.lineweights;
|
|
|
|
|
self.with_styles = o.with_styles;
|
|
|
|
|
self.transparency = o.transparency;
|
|
|
|
|
self.paperspace_last = o.paperspace_last;
|
|
|
|
|
self.hide_paperspace = o.hide_paperspace;
|
|
|
|
|
self.stamp = o.stamp;
|
|
|
|
|
self.save_layout = o.save_layout;
|
|
|
|
|
self.style_name = o.style_name.clone();
|
|
|
|
|
}
|
|
|
|
|
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
/// Load the persisted print preferences (printer, copies, quality, output
|
|
|
|
|
/// options) from `<config>/OpenCADStudio/plot.txt`. Drawing-specific fields
|
|
|
|
|
/// (paper, scale, offset, rotation…) are NOT persisted here — they are
|
|
|
|
|
/// seeded from the active layout each time the dialog opens.
|
|
|
|
|
pub fn load() -> Self {
|
|
|
|
|
#[cfg(target_arch = "wasm32")]
|
|
|
|
|
{
|
|
|
|
|
Self::default()
|
|
|
|
|
}
|
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
|
|
|
{
|
|
|
|
|
let mut s = Self::default();
|
|
|
|
|
if let Some(body) = prefs_path().and_then(|p| std::fs::read_to_string(p).ok()) {
|
|
|
|
|
let flag = |v: &str| v == "1";
|
|
|
|
|
for line in body.lines() {
|
|
|
|
|
let Some((k, v)) = line.split_once('=') else {
|
|
|
|
|
continue;
|
|
|
|
|
};
|
|
|
|
|
let (k, v) = (k.trim(), v.trim());
|
|
|
|
|
match k {
|
|
|
|
|
"printer" => {
|
|
|
|
|
s.printer = if v.is_empty() { None } else { Some(v.to_string()) }
|
|
|
|
|
}
|
|
|
|
|
"to_file" => s.to_file = flag(v),
|
|
|
|
|
"area" => s.area = v.to_string(),
|
|
|
|
|
"scale" => s.scale = v.to_string(),
|
|
|
|
|
"copies" => s.copies = v.to_string(),
|
|
|
|
|
"quality" => s.quality = v.to_string(),
|
|
|
|
|
"dpi" => s.dpi = v.to_string(),
|
|
|
|
|
"shade" => s.shade = v.to_string(),
|
|
|
|
|
"mono" => s.mono = flag(v),
|
|
|
|
|
"lineweights" => s.lineweights = flag(v),
|
|
|
|
|
"with_styles" => s.with_styles = flag(v),
|
|
|
|
|
"transparency" => s.transparency = flag(v),
|
|
|
|
|
"paperspace_last" => s.paperspace_last = flag(v),
|
|
|
|
|
"hide_paperspace" => s.hide_paperspace = flag(v),
|
|
|
|
|
"stamp" => s.stamp = flag(v),
|
|
|
|
|
"save_layout" => s.save_layout = flag(v),
|
|
|
|
|
"scale_lw" => s.scale_lw = flag(v),
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Best-effort persist of the print preferences (silent on failure).
|
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
|
|
|
pub fn save(&self) {
|
|
|
|
|
let Some(path) = prefs_path() else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
if let Some(dir) = path.parent() {
|
|
|
|
|
let _ = std::fs::create_dir_all(dir);
|
|
|
|
|
}
|
|
|
|
|
let b = |v: bool| if v { "1" } else { "0" };
|
|
|
|
|
let printer = self.printer.clone().unwrap_or_default();
|
|
|
|
|
let body = format!(
|
|
|
|
|
"printer={}\nto_file={}\narea={}\nscale={}\ncopies={}\nquality={}\ndpi={}\nshade={}\nmono={}\n\
|
|
|
|
|
lineweights={}\nwith_styles={}\ntransparency={}\npaperspace_last={}\n\
|
|
|
|
|
hide_paperspace={}\nstamp={}\nsave_layout={}\nscale_lw={}\n",
|
|
|
|
|
printer,
|
|
|
|
|
b(self.to_file),
|
|
|
|
|
self.area,
|
|
|
|
|
self.scale,
|
|
|
|
|
self.copies,
|
|
|
|
|
self.quality,
|
|
|
|
|
self.dpi,
|
|
|
|
|
self.shade,
|
|
|
|
|
b(self.mono),
|
|
|
|
|
b(self.lineweights),
|
|
|
|
|
b(self.with_styles),
|
|
|
|
|
b(self.transparency),
|
|
|
|
|
b(self.paperspace_last),
|
|
|
|
|
b(self.hide_paperspace),
|
|
|
|
|
b(self.stamp),
|
|
|
|
|
b(self.save_layout),
|
|
|
|
|
b(self.scale_lw),
|
|
|
|
|
);
|
|
|
|
|
let _ = std::fs::write(path, body);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// No-op persist on the web build (no filesystem).
|
|
|
|
|
#[cfg(target_arch = "wasm32")]
|
|
|
|
|
pub fn save(&self) {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
|
|
|
|
fn prefs_path() -> Option<std::path::PathBuf> {
|
|
|
|
|
Some(crate::config::config_dir()?.join("plot.txt"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn btn(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
|
|
|
|
move |_: &Theme, st| button::Style {
|
|
|
|
|
background: Some(Background::Color(match (accent, st) {
|
|
|
|
|
(true, button::Status::Hovered | button::Status::Pressed) => {
|
|
|
|
|
Color { r: 0.20, g: 0.42, b: 0.72, a: 1.0 }
|
|
|
|
|
}
|
|
|
|
|
(false, button::Status::Hovered | button::Status::Pressed) => {
|
|
|
|
|
Color { r: 0.28, g: 0.28, b: 0.28, a: 1.0 }
|
|
|
|
|
}
|
|
|
|
|
(true, _) => ACCENT,
|
|
|
|
|
_ => Color { r: 0.22, g: 0.22, b: 0.22, a: 1.0 },
|
|
|
|
|
})),
|
|
|
|
|
text_color: TEXT,
|
|
|
|
|
border: Border { color: BORDER, width: 1.0, radius: 4.0.into() },
|
|
|
|
|
shadow: iced::Shadow::default(),
|
|
|
|
|
snap: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn field_style(_: &Theme, _: text_input::Status) -> text_input::Style {
|
|
|
|
|
text_input::Style {
|
|
|
|
|
background: Background::Color(FIELD),
|
|
|
|
|
border: Border { color: BORDER, width: 1.0, radius: 3.0.into() },
|
|
|
|
|
icon: TEXT,
|
|
|
|
|
placeholder: DIM,
|
|
|
|
|
value: TEXT,
|
|
|
|
|
selection: ACCENT,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn hdivider<'a>() -> Element<'a, Message> {
|
|
|
|
|
container(Space::new().width(Fill).height(1))
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.height(1)
|
|
|
|
|
.style(|_: &Theme| container::Style {
|
|
|
|
|
background: Some(Background::Color(BORDER)),
|
|
|
|
|
..Default::default()
|
|
|
|
|
})
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn section_label<'a>(s: &'static str) -> Element<'a, Message> {
|
|
|
|
|
text(s).size(11).color(DIM).into()
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-09 12:25:46 +03:00
|
|
|
fn vsep<'a>() -> Element<'a, Message> {
|
|
|
|
|
container(Space::new().width(1).height(Fill))
|
|
|
|
|
.width(1)
|
|
|
|
|
.height(Fill)
|
|
|
|
|
.style(|_: &Theme| container::Style {
|
|
|
|
|
background: Some(Background::Color(BORDER)),
|
|
|
|
|
..Default::default()
|
|
|
|
|
})
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// One row in the page-setup list: a selectable name, or an inline rename field
|
|
|
|
|
/// when this row is being renamed.
|
|
|
|
|
fn setup_row<'a>(
|
|
|
|
|
name: &'a str,
|
|
|
|
|
selected: &str,
|
|
|
|
|
renaming: Option<&str>,
|
|
|
|
|
rename_buf: &'a str,
|
|
|
|
|
) -> Element<'a, Message> {
|
|
|
|
|
if renaming == Some(name) {
|
|
|
|
|
return text_input("", rename_buf)
|
|
|
|
|
.on_input(|v| Message::PlotDlg(PlotDlgMsg::NameInput(v)))
|
|
|
|
|
.on_submit(Message::PlotDlg(PlotDlgMsg::NameCommit))
|
|
|
|
|
.style(field_style)
|
|
|
|
|
.size(11)
|
|
|
|
|
.padding([4, 8])
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.into();
|
|
|
|
|
}
|
|
|
|
|
let is_sel = name == selected;
|
|
|
|
|
let cell = container(text(name.to_string()).size(11).color(TEXT))
|
|
|
|
|
.padding([4, 8])
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.style(move |_: &Theme| container::Style {
|
|
|
|
|
background: is_sel.then_some(Background::Color(ACTIVE)),
|
|
|
|
|
text_color: Some(TEXT),
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
mouse_area(cell)
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::SelectSetup(name.to_string())))
|
|
|
|
|
.on_double_click(Message::PlotDlg(PlotDlgMsg::RenameStart(name.to_string())))
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
/// A `label : dropdown` row. `ctor` turns the picked string into a dialog
|
|
|
|
|
/// message.
|
|
|
|
|
fn drop_row<'a>(
|
|
|
|
|
label: &'a str,
|
|
|
|
|
options: Vec<String>,
|
|
|
|
|
selected: Option<String>,
|
|
|
|
|
ctor: fn(String) -> PlotDlgMsg,
|
|
|
|
|
) -> Element<'a, Message> {
|
|
|
|
|
let pl = pick_list(options, selected, move |s| Message::PlotDlg(ctor(s)))
|
|
|
|
|
.text_size(12)
|
|
|
|
|
.padding([3, 6])
|
|
|
|
|
.width(Length::Fill);
|
|
|
|
|
row![text(label).size(11).color(DIM).width(92), pl]
|
|
|
|
|
.spacing(8)
|
|
|
|
|
.align_y(iced::Center)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A `label : text field` row.
|
|
|
|
|
fn field_row<'a>(
|
|
|
|
|
label: &'a str,
|
|
|
|
|
value: &'a str,
|
|
|
|
|
ctor: fn(String) -> PlotDlgMsg,
|
|
|
|
|
width: u16,
|
|
|
|
|
) -> Element<'a, Message> {
|
|
|
|
|
row![
|
|
|
|
|
text(label).size(11).color(DIM).width(92),
|
|
|
|
|
text_input("", value)
|
|
|
|
|
.on_input(move |s| Message::PlotDlg(ctor(s)))
|
|
|
|
|
.style(field_style)
|
|
|
|
|
.size(12)
|
|
|
|
|
.width(width as f32),
|
|
|
|
|
]
|
|
|
|
|
.spacing(8)
|
|
|
|
|
.align_y(iced::Center)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A single option checkbox bound to a `PlotFlag`.
|
|
|
|
|
fn check<'a>(label: &'a str, on: bool, flag: PlotFlag) -> Element<'a, Message> {
|
|
|
|
|
checkbox(on)
|
|
|
|
|
.label(label)
|
|
|
|
|
.on_toggle(move |_| Message::PlotDlg(PlotDlgMsg::Flag(flag)))
|
|
|
|
|
.size(14)
|
|
|
|
|
.text_size(11)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn strs(items: &[&str]) -> Vec<String> {
|
|
|
|
|
items.iter().map(|s| s.to_string()).collect()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn view_window(s: &PlotDialogState) -> Element<'_, Message> {
|
|
|
|
|
// ── Toolbar: Cancel … Preview Print/Export ──────────────────────────
|
|
|
|
|
let action = if s.to_file { "Export PDF" } else { "Print" };
|
2026-07-09 12:25:46 +03:00
|
|
|
// `<none>` / `<previous>` are pseudo-entries; layout rows are `*name*`.
|
|
|
|
|
let is_special = s.selected_setup == SETUP_NONE || s.selected_setup == SETUP_PREV;
|
|
|
|
|
let sel_is_layout = s.selected_setup.len() >= 2
|
|
|
|
|
&& s.selected_setup.starts_with('*')
|
|
|
|
|
&& s.selected_setup.ends_with('*');
|
|
|
|
|
let can_copy = !s.selected_setup.is_empty() && !is_special;
|
|
|
|
|
let is_named = can_copy && !sel_is_layout;
|
|
|
|
|
let mut left_bar = row![button(text("New").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::NewSetup))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 12])]
|
|
|
|
|
.spacing(4);
|
|
|
|
|
if can_copy {
|
|
|
|
|
left_bar = left_bar.push(
|
|
|
|
|
button(text("Copy").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::CopySetup))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 12]),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if is_named {
|
|
|
|
|
left_bar = left_bar.push(
|
|
|
|
|
button(text("Delete").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::DeleteSetup))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 12]),
|
|
|
|
|
);
|
|
|
|
|
}
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
let toolbar = container(
|
|
|
|
|
row![
|
2026-07-09 12:25:46 +03:00
|
|
|
left_bar,
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
Space::new().width(Fill),
|
2026-07-09 12:25:46 +03:00
|
|
|
button(text("Set current").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::SetCurrent))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 12]),
|
|
|
|
|
Space::new().width(6),
|
|
|
|
|
button(text("Preview").size(11))
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::Preview))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 12]),
|
2026-07-09 12:25:46 +03:00
|
|
|
Space::new().width(6),
|
|
|
|
|
button(text(action).size(11))
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::Commit))
|
|
|
|
|
.style(btn(true))
|
2026-07-09 12:25:46 +03:00
|
|
|
.padding([4, 18]),
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
]
|
|
|
|
|
.align_y(iced::Center),
|
|
|
|
|
)
|
|
|
|
|
.style(|_: &Theme| container::Style {
|
|
|
|
|
background: Some(Background::Color(TB)),
|
|
|
|
|
..Default::default()
|
|
|
|
|
})
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.padding([5, 10]);
|
|
|
|
|
|
|
|
|
|
// ── Printer dropdown: default + discovered printers + PDF sentinel ────
|
|
|
|
|
let mut printer_opts = vec![OUT_DEFAULT.to_string()];
|
|
|
|
|
printer_opts.extend(s.printers.iter().cloned());
|
|
|
|
|
printer_opts.push(OUT_PDF.to_string());
|
|
|
|
|
let printer_sel = if s.to_file {
|
|
|
|
|
Some(OUT_PDF.to_string())
|
|
|
|
|
} else {
|
|
|
|
|
Some(s.printer.clone().unwrap_or_else(|| OUT_DEFAULT.to_string()))
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let paper_opts: Vec<String> = PaperSize::ALL.iter().map(|p| p.label().to_string()).collect();
|
|
|
|
|
|
2026-07-09 12:25:46 +03:00
|
|
|
// ── Left panel: named page-setup list (click selects, double-click renames)
|
|
|
|
|
let renaming = if s.name_rename && !s.selected_setup.is_empty() {
|
|
|
|
|
Some(s.selected_setup.as_str())
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
};
|
|
|
|
|
let rename_buf = s.name_input.as_deref().unwrap_or("");
|
|
|
|
|
let rows: Vec<Element<'_, Message>> = s
|
|
|
|
|
.page_setups
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|name| setup_row(name, &s.selected_setup, renaming, rename_buf))
|
|
|
|
|
.collect();
|
|
|
|
|
let list_body: Element<'_, Message> = if rows.is_empty() {
|
|
|
|
|
container(text("(no page setups)").size(11).color(DIM))
|
|
|
|
|
.padding([6, 8])
|
|
|
|
|
.into()
|
|
|
|
|
} else {
|
|
|
|
|
scrollable(column(rows).spacing(1)).height(Fill).into()
|
|
|
|
|
};
|
|
|
|
|
let list_panel = container(
|
|
|
|
|
column![
|
|
|
|
|
text("Page setups").size(10).color(DIM),
|
|
|
|
|
container(list_body)
|
|
|
|
|
.style(|_: &Theme| container::Style {
|
|
|
|
|
background: Some(Background::Color(LIST)),
|
|
|
|
|
border: Border {
|
|
|
|
|
color: BORDER,
|
|
|
|
|
width: 1.0,
|
|
|
|
|
radius: 3.0.into(),
|
|
|
|
|
},
|
|
|
|
|
..Default::default()
|
|
|
|
|
})
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.height(Fill)
|
|
|
|
|
.padding(2),
|
|
|
|
|
]
|
|
|
|
|
.spacing(4)
|
|
|
|
|
.height(Fill),
|
|
|
|
|
)
|
|
|
|
|
.width(160)
|
|
|
|
|
.height(Fill)
|
|
|
|
|
.padding(iced::Padding {
|
|
|
|
|
top: 12.0,
|
|
|
|
|
right: 8.0,
|
|
|
|
|
bottom: 12.0,
|
|
|
|
|
left: 12.0,
|
|
|
|
|
});
|
|
|
|
|
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
// ── Left column ──────────────────────────────────────────────────────
|
|
|
|
|
let style_label: String = if s.style_name.is_empty() {
|
|
|
|
|
"(none)".into()
|
|
|
|
|
} else {
|
|
|
|
|
s.style_name.clone()
|
|
|
|
|
};
|
|
|
|
|
let left = column![
|
|
|
|
|
section_label("Printer / plotter"),
|
|
|
|
|
drop_row("Output", printer_opts, printer_sel, PlotDlgMsg::Printer),
|
|
|
|
|
field_row("Copies", &s.copies, PlotDlgMsg::Copies, 60),
|
|
|
|
|
hdivider(),
|
|
|
|
|
section_label("Paper"),
|
|
|
|
|
drop_row("Size", paper_opts, Some(s.paper.clone()), PlotDlgMsg::Paper),
|
|
|
|
|
drop_row(
|
|
|
|
|
"Orientation",
|
|
|
|
|
strs(&["Portrait", "Landscape"]),
|
|
|
|
|
Some(s.orientation.clone()),
|
|
|
|
|
PlotDlgMsg::Orientation,
|
|
|
|
|
),
|
|
|
|
|
drop_row(
|
|
|
|
|
"Rotation",
|
|
|
|
|
strs(&["0°", "90°", "180°", "270°"]),
|
|
|
|
|
Some(s.rotation.clone()),
|
|
|
|
|
PlotDlgMsg::Rotation,
|
|
|
|
|
),
|
|
|
|
|
hdivider(),
|
|
|
|
|
section_label("Plot area"),
|
|
|
|
|
row![
|
|
|
|
|
container(
|
|
|
|
|
pick_list(
|
|
|
|
|
strs(&["Layout", "Extents", "Display", "Window"]),
|
|
|
|
|
Some(s.area.clone()),
|
|
|
|
|
move |v| Message::PlotDlg(PlotDlgMsg::Area(v)),
|
|
|
|
|
)
|
|
|
|
|
.text_size(12)
|
|
|
|
|
.padding([3, 6])
|
|
|
|
|
.width(Length::Fill)
|
|
|
|
|
)
|
|
|
|
|
.width(Fill),
|
|
|
|
|
button(text("Pick…").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::PickWindow))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 10]),
|
|
|
|
|
]
|
|
|
|
|
.spacing(8)
|
|
|
|
|
.align_y(iced::Center),
|
|
|
|
|
section_label("Plot offset"),
|
|
|
|
|
column![
|
|
|
|
|
field_row("X (mm)", &s.offset_x, PlotDlgMsg::OffsetX, 70),
|
|
|
|
|
field_row("Y (mm)", &s.offset_y, PlotDlgMsg::OffsetY, 70),
|
|
|
|
|
]
|
|
|
|
|
.spacing(9),
|
|
|
|
|
check("Center the plot", s.center, PlotFlag::Center),
|
|
|
|
|
]
|
|
|
|
|
.spacing(9)
|
|
|
|
|
.width(Fill);
|
|
|
|
|
|
|
|
|
|
// ── Right column ─────────────────────────────────────────────────────
|
|
|
|
|
let right = column![
|
|
|
|
|
section_label("Plot scale"),
|
|
|
|
|
drop_row(
|
|
|
|
|
"Scale",
|
|
|
|
|
strs(&["Fit", "1:1", "1:2", "1:5", "1:10", "1:20", "1:50", "1:100", "2:1"]),
|
|
|
|
|
Some(s.scale.clone()),
|
|
|
|
|
PlotDlgMsg::Scale,
|
|
|
|
|
),
|
|
|
|
|
check("Scale lineweights", s.scale_lw, PlotFlag::ScaleLw),
|
|
|
|
|
hdivider(),
|
|
|
|
|
section_label("Plot style table (pen assignments)"),
|
|
|
|
|
row![
|
|
|
|
|
container(text(style_label).size(12).color(TEXT))
|
|
|
|
|
.style(|_: &Theme| container::Style {
|
|
|
|
|
background: Some(Background::Color(FIELD)),
|
|
|
|
|
border: Border { color: BORDER, width: 1.0, radius: 3.0.into() },
|
|
|
|
|
..Default::default()
|
|
|
|
|
})
|
|
|
|
|
.padding([4, 8])
|
|
|
|
|
.width(Fill),
|
|
|
|
|
button(text("Load…").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::LoadStyle))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 10]),
|
|
|
|
|
button(text("Clear").size(11))
|
|
|
|
|
.on_press(Message::PlotDlg(PlotDlgMsg::ClearStyle))
|
|
|
|
|
.style(btn(false))
|
|
|
|
|
.padding([4, 10]),
|
|
|
|
|
]
|
|
|
|
|
.spacing(6)
|
|
|
|
|
.align_y(iced::Center),
|
|
|
|
|
hdivider(),
|
|
|
|
|
section_label("Quality"),
|
|
|
|
|
row![
|
|
|
|
|
container(
|
|
|
|
|
pick_list(
|
|
|
|
|
strs(&["Draft", "Normal", "High", "Maximum"]),
|
|
|
|
|
Some(s.quality.clone()),
|
|
|
|
|
move |v| Message::PlotDlg(PlotDlgMsg::Quality(v)),
|
|
|
|
|
)
|
|
|
|
|
.text_size(12)
|
|
|
|
|
.padding([3, 6])
|
|
|
|
|
.width(Length::Fill)
|
|
|
|
|
)
|
|
|
|
|
.width(Fill),
|
|
|
|
|
text("DPI").size(11).color(DIM),
|
|
|
|
|
text_input("", &s.dpi)
|
|
|
|
|
.on_input(move |v| Message::PlotDlg(PlotDlgMsg::Dpi(v)))
|
|
|
|
|
.style(field_style)
|
|
|
|
|
.size(12)
|
|
|
|
|
.width(56.0),
|
|
|
|
|
]
|
|
|
|
|
.spacing(8)
|
|
|
|
|
.align_y(iced::Center),
|
|
|
|
|
drop_row(
|
|
|
|
|
"Shaded plot",
|
|
|
|
|
strs(&["As displayed", "Wireframe", "Hidden", "Rendered"]),
|
|
|
|
|
Some(s.shade.clone()),
|
|
|
|
|
PlotDlgMsg::Shade,
|
|
|
|
|
),
|
|
|
|
|
hdivider(),
|
|
|
|
|
section_label("Plot options"),
|
|
|
|
|
row![
|
|
|
|
|
column![
|
|
|
|
|
check("Object lineweights", s.lineweights, PlotFlag::Lineweights),
|
|
|
|
|
check("Plot with styles", s.with_styles, PlotFlag::WithStyles),
|
|
|
|
|
check("Monochrome", s.mono, PlotFlag::Mono),
|
|
|
|
|
check("Plot transparency", s.transparency, PlotFlag::Transparency),
|
|
|
|
|
]
|
|
|
|
|
.spacing(6)
|
|
|
|
|
.width(Fill),
|
|
|
|
|
column![
|
|
|
|
|
check("Paperspace last", s.paperspace_last, PlotFlag::PaperspaceLast),
|
|
|
|
|
check("Hide paperspace", s.hide_paperspace, PlotFlag::HidePaperspace),
|
|
|
|
|
check("Plot stamp", s.stamp, PlotFlag::Stamp),
|
|
|
|
|
check("Save to layout", s.save_layout, PlotFlag::SaveLayout),
|
|
|
|
|
]
|
|
|
|
|
.spacing(6)
|
|
|
|
|
.width(Fill),
|
|
|
|
|
]
|
|
|
|
|
.spacing(10),
|
|
|
|
|
]
|
|
|
|
|
.spacing(9)
|
|
|
|
|
.width(Fill);
|
|
|
|
|
|
2026-07-09 12:25:46 +03:00
|
|
|
let detail = scrollable(
|
|
|
|
|
container(row![left, right].spacing(18).width(Fill)).padding(14),
|
|
|
|
|
)
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.height(Fill);
|
|
|
|
|
let body = row![list_panel, vsep(), detail].height(Fill);
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
|
2026-07-09 12:25:46 +03:00
|
|
|
container(column![toolbar, hdivider(), body].spacing(0))
|
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
|
|
|
.style(|_: &Theme| container::Style {
|
|
|
|
|
background: Some(Background::Color(BG)),
|
|
|
|
|
..Default::default()
|
|
|
|
|
})
|
|
|
|
|
.width(Fill)
|
|
|
|
|
.height(Fill)
|
|
|
|
|
.into()
|
|
|
|
|
}
|