cad-editor/src/app/document.rs
2026-05-12 10:36:15 +03:00

117 lines
4.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::command::CadCommand;
use crate::linetypes;
use crate::modules::home::modify::refedit::RefEditSession;
use crate::scene::grip::GripEdit;
use crate::scene::GripDef;
use crate::scene::Scene;
use crate::snap::SnapResult;
use crate::ui::{LayerPanel, PropertiesPanel};
use acadrust::tables::Ucs;
use acadrust::{CadDocument, Handle};
use iced;
use std::path::PathBuf;
// ── Per-document tab state ─────────────────────────────────────────────────
pub(super) struct DocumentTab {
pub(super) scene: Scene,
pub(super) current_path: Option<PathBuf>,
pub(super) dirty: bool,
pub(super) tab_title: String,
pub(super) properties: PropertiesPanel,
pub(super) layers: LayerPanel,
pub(super) active_cmd: Option<Box<dyn CadCommand>>,
pub(super) last_cmd: Option<String>,
pub(super) snap_result: Option<SnapResult>,
pub(super) active_grip: Option<GripEdit>,
pub(super) selected_grips: Vec<GripDef>,
pub(super) selected_handle: Option<Handle>,
pub(super) wireframe: bool,
pub(super) visual_style: String,
pub(super) last_cursor_world: glam::Vec3,
pub(super) last_cursor_screen: iced::Point,
pub(super) history: HistoryState,
pub(super) active_layer: String,
/// Currently active UCS. `None` means WCS (identity transform).
pub(super) active_ucs: Option<Ucs>,
/// Custom model-space background color. `None` = default dark grey.
pub(super) bg_color: Option<[f32; 4]>,
/// Custom paper-space background color. `None` = default off-white grey.
pub(super) paper_bg_color: Option<[f32; 4]>,
/// Active REFEDIT session, if any.
pub(super) refedit_session: Option<RefEditSession>,
/// Currently active MLeader style name.
pub(super) active_mleader_style: String,
/// Last camera_generation value written back to the document.
pub(super) last_synced_camera_gen: u64,
}
impl DocumentTab {
pub(super) fn new_drawing(n: usize) -> Self {
let mut scene = Scene::new();
linetypes::populate_document(&mut scene.document);
// Override acadrust's imperial default limits (12×9) with A4 landscape.
for obj in scene.document.objects.values_mut() {
if let acadrust::objects::ObjectType::Layout(l) = obj {
if l.name != "Model" {
l.min_limits = (0.0, 0.0);
l.max_limits = (297.0, 210.0);
l.min_extents = (0.0, 0.0, 0.0);
l.max_extents = (297.0, 210.0, 0.0);
}
}
}
Self {
scene,
current_path: None,
dirty: false,
tab_title: format!("Drawing{}", n),
properties: PropertiesPanel::empty(),
layers: LayerPanel::default(),
active_cmd: None,
last_cmd: None,
snap_result: None,
active_grip: None,
selected_grips: vec![],
selected_handle: None,
wireframe: false,
visual_style: "Shaded".into(),
last_cursor_world: glam::Vec3::ZERO,
last_cursor_screen: iced::Point::ORIGIN,
history: HistoryState::default(),
active_layer: "0".to_string(),
active_ucs: None,
bg_color: None,
paper_bg_color: None,
refedit_session: None,
active_mleader_style: "Standard".to_string(),
last_synced_camera_gen: 0,
}
}
pub(super) fn tab_display_name(&self) -> String {
match &self.current_path {
Some(p) => p
.file_name()
.unwrap_or_default()
.to_string_lossy()
.to_string(),
None => self.tab_title.clone(),
}
}
}
#[derive(Clone)]
pub(super) struct HistorySnapshot {
pub(super) document: CadDocument,
pub(super) current_layout: String,
pub(super) selected: Vec<Handle>,
pub(super) dirty: bool,
pub(super) label: String,
}
#[derive(Default)]
pub(super) struct HistoryState {
pub(super) undo_stack: Vec<HistorySnapshot>,
pub(super) redo_stack: Vec<HistorySnapshot>,
}