117 lines
4.2 KiB
Rust
117 lines
4.2 KiB
Rust
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>,
|
||
}
|