cad-editor/src/modules/view/mod.rs
Hakan Seven c45fe0267c feat(plot): QUICKPRINT/QP — plot a selection's bounding box to PDF (#325)
Run QUICKPRINT (or QP), select objects, then Enter: the selection's
bounding box becomes the plot window and a PDF is written next to the
drawing (<name>_<timestamp>.pdf) using the active page setup, with no
dialog. Model space.

Implemented as a selection-gathering CadCommand (src/modules/view/
quick_print.rs) returning CmdResult::QuickPrint(handles); the host
(on_quick_print_handles) unions the picked entities' AABBs, sets the
plot window, and reuses the tested clipped window-export path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 12:57:35 +03:00

157 lines
7 KiB
Rust

// View module — viewport tools, navigation, visual styles, palettes, interface.
mod cascade;
mod file_tabs;
mod hidden;
mod layout_tabs;
mod orbit;
mod ortho;
mod pan;
mod persp;
pub mod plot_window;
pub mod quick_print;
mod properties_palette;
mod sheetset;
mod solid;
mod tile_horiz;
mod tile_vert;
mod tool_palettes;
pub mod ucs_cmd;
mod ucs_icon;
mod view_front;
mod view_iso;
mod view_right;
mod view_top;
mod viewcube;
mod vports_config;
mod vports_join;
mod vports_named;
mod vports_restore;
mod wireframe;
mod xray;
mod zoom_ext;
mod zoom_in;
mod zoom_out;
pub mod zoom_window;
use crate::modules::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem, ToolDef};
pub struct ViewModule;
impl CadModule for ViewModule {
fn id(&self) -> &'static str {
"view"
}
fn title(&self) -> &'static str {
"View"
}
fn ribbon_groups(&self) -> &[RibbonGroup] {
static GROUPS: std::sync::OnceLock<Vec<RibbonGroup>> = std::sync::OnceLock::new();
GROUPS.get_or_init(|| {
vec![
// ── Viewport Tools ───────────────────────────────────────────────
RibbonGroup {
title: "Viewport Tools",
tools: vec![
RibbonItem::LargeTool(ucs_icon::tool()),
RibbonItem::LargeTool(viewcube::tool()),
],
},
// ── Navigate ─────────────────────────────────────────────────────
RibbonGroup {
title: "Navigate",
tools: vec![
RibbonItem::LargeTool(zoom_ext::tool()),
RibbonItem::Tool(zoom_window::tool()),
RibbonItem::Tool(zoom_in::tool()),
RibbonItem::Tool(zoom_out::tool()),
RibbonItem::Tool(pan::tool()),
RibbonItem::Tool(orbit::tool()),
],
},
// ── Model Viewports ───────────────────────────────────────────────
RibbonGroup {
title: "Model Viewports",
tools: vec![
RibbonItem::LargeTool(vports_config::tool()),
RibbonItem::Tool(vports_named::tool()),
RibbonItem::Tool(vports_join::tool()),
RibbonItem::Tool(vports_restore::tool()),
],
},
// ── Visual Style ──────────────────────────────────────────────────
RibbonGroup {
// WIREFRAME and SOLID ids are special-cased in ribbon.rs
// for toggle-state highlighting based on Ribbon::wireframe.
title: "Visual Style",
tools: vec![RibbonItem::LargeDropdown {
id: "VISUAL_STYLE",
label: "Visual\nStyle",
icon: wireframe::tool().icon,
items: vec![
("WIREFRAME", "Wireframe", wireframe::tool().icon),
("SOLID", "Shaded", solid::tool().icon),
("HIDDEN", "Hidden", hidden::tool().icon),
("XRAY", "X-Ray", xray::tool().icon),
],
default: "WIREFRAME",
}],
},
// ── Projection ────────────────────────────────────────────────────
RibbonGroup {
// ORTHO and PERSP ids are special-cased in ribbon.rs
// for toggle-state highlighting based on Camera::projection.
title: "Projection",
tools: vec![
RibbonItem::LargeTool(ortho::tool()),
RibbonItem::LargeTool(persp::tool()),
],
},
// ── Preset Views ──────────────────────────────────────────────────
RibbonGroup {
title: "Preset",
tools: vec![
RibbonItem::Tool(view_top::tool()),
RibbonItem::Tool(view_front::tool()),
RibbonItem::Tool(view_right::tool()),
RibbonItem::Tool(view_iso::tool()),
],
},
// ── Palettes ──────────────────────────────────────────────────────
RibbonGroup {
title: "Palettes",
tools: vec![
RibbonItem::LargeTool(tool_palettes::tool()),
RibbonItem::LargeTool(properties_palette::tool()),
RibbonItem::LargeTool(sheetset::tool()),
],
},
// ── Interface ─────────────────────────────────────────────────────
RibbonGroup {
title: "Interface",
tools: vec![
RibbonItem::LargeTool(file_tabs::tool()),
RibbonItem::LargeTool(layout_tabs::tool()),
RibbonItem::Tool(tile_horiz::tool()),
RibbonItem::Tool(tile_vert::tool()),
RibbonItem::Tool(cascade::tool()),
],
},
// ── Plot ──────────────────────────────────────────────────────────
// Model space has no paper-space side toolbar, so Page Setup
// (format/orientation/pick window for PLOTWINDOW) needs an
// entry here too.
RibbonGroup {
title: "Plot",
tools: vec![RibbonItem::Tool(ToolDef {
id: "PAGESETUP",
label: "Page Setup",
icon: IconKind::Svg(include_bytes!("../../../assets/icons/pagesetup.svg")),
event: ModuleEvent::Command("PAGESETUP".to_string()),
})],
},
]
})
}
}