use super::*; impl OpenCADStudio { pub(super) fn dispatch_layerprops(&mut self, cmd: &str, i: usize) -> Option> { match cmd { // ── LAYER management ───────────────────────────────────────── cmd if cmd == "LAYER" || cmd.starts_with("LAYER ") || cmd.starts_with("LA ") => { use codec::tables::Layer; let raw_rest = if cmd.starts_with("LAYER ") { cmd.trim_start_matches("LAYER ").trim() } else if cmd.starts_with("LA ") { cmd.trim_start_matches("LA ").trim() } else { "" }; let parts: Vec<&str> = raw_rest.split_whitespace().collect(); let sub = parts.get(0).map(|s| s.to_uppercase()).unwrap_or_default(); match sub.as_str() { "" | "LIST" | "?" => { let info: Vec = self.tabs[i] .scene .document .layers .iter() .map(|l| { let state = if l.flags.frozen { "frozen" } else if l.flags.off { "off" } else if l.flags.locked { "locked" } else { "on" }; format!("{}({})", l.name, state) }) .collect(); self.command_line .push_output(crate::tf!("Layers: {}", info.join(", ")).as_ref()); } "NEW" | "N" => { let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string(); if name.is_empty() { self.command_line .push_error(crate::t!("Usage: LAYER NEW ").as_ref()); } else if self.tabs[i].scene.document.layers.contains(&name) { self.command_line.push_error( crate::tf!("LAYER: '{}' already exists.", name).as_ref(), ); } else { let mut layer = Layer::new(&name); // Allocate a unique handle so the layer survives a // DWG save (handle-based format; issue #67). layer.handle = self.tabs[i].scene.document.allocate_handle(); let _ = self.tabs[i].scene.document.layers.add(layer); self.push_undo_snapshot(i, "LAYER NEW"); self.tabs[i].dirty = true; self.command_line .push_output(crate::tf!("LAYER: '{}' created.", name).as_ref()); } } "ON" => { for name in &parts[1..] { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(name) { l.flags.off = false; l.flags.frozen = false; } } self.push_undo_snapshot(i, "LAYER ON"); self.tabs[i].dirty = true; self.command_line .push_output(crate::t!("LAYER: layers turned on.").as_ref()); } "OFF" => { for name in &parts[1..] { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(name) { l.flags.off = true; } } self.push_undo_snapshot(i, "LAYER OFF"); self.tabs[i].dirty = true; self.command_line .push_output(crate::t!("LAYER: layers turned off.").as_ref()); } "FREEZE" | "FR" => { for name in &parts[1..] { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(name) { l.flags.frozen = true; } } self.push_undo_snapshot(i, "LAYER FREEZE"); self.tabs[i].dirty = true; self.command_line .push_output(crate::t!("LAYER: layers frozen.").as_ref()); } "THAW" | "TH" => { for name in &parts[1..] { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(name) { l.flags.frozen = false; } } self.push_undo_snapshot(i, "LAYER THAW"); self.tabs[i].dirty = true; self.command_line .push_output(crate::t!("LAYER: layers thawed.").as_ref()); } "LOCK" | "LO" => { for name in &parts[1..] { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(name) { l.flags.locked = true; } } self.push_undo_snapshot(i, "LAYER LOCK"); self.tabs[i].dirty = true; self.refresh_properties(); self.command_line .push_output(crate::t!("LAYER: layers locked.").as_ref()); } "UNLOCK" | "UL" => { for name in &parts[1..] { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(name) { l.flags.locked = false; } } self.push_undo_snapshot(i, "LAYER UNLOCK"); self.tabs[i].dirty = true; self.refresh_properties(); self.command_line .push_output(crate::t!("LAYER: layers unlocked.").as_ref()); } "COLOR" | "C" => { // LAYER COLOR let layer_name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string(); let color_str = parts.get(2).map(|s| s.trim()).unwrap_or(""); if let Ok(idx) = color_str.parse::() { if let Some(l) = self.tabs[i].scene.document.layers.get_mut(&layer_name) { l.color = codec::types::Color::from_index(idx); l.color_name = None; l.book_name = None; self.push_undo_snapshot(i, "LAYER COLOR"); self.tabs[i].dirty = true; // By-layer colour is baked into every wire on // this layer. The dependency index maps block // children back to their top-level INSERTs, so // unrelated entities stay warm. self.tabs[i].scene.invalidate_layer_dependencies( std::slice::from_ref(&layer_name), ); self.command_line.push_output( crate::tf!("LAYER: '{}' color set to ACI {}.", layer_name, idx) .as_ref(), ); } else { self.command_line.push_error( crate::tf!("LAYER: '{}' not found.", layer_name).as_ref(), ); } } else { self.command_line.push_error( crate::t!("Usage: LAYER COLOR ").as_ref(), ); } } "SET" | "S" | "CURRENT" => { let name = parts.get(1).map(|s| s.trim()).unwrap_or("").to_string(); if self.tabs[i].scene.document.layers.contains(&name) { self.tabs[i].layers.current_layer = name.clone(); self.command_line.push_output( crate::tf!("LAYER: current layer set to '{}'.", name).as_ref(), ); } else { self.command_line .push_error(crate::tf!("LAYER: '{}' not found.", name).as_ref()); } } _ => { self.command_line.push_info( crate::t!("Usage: LAYER LIST | NEW | ON/OFF/FREEZE/THAW/LOCK/UNLOCK | COLOR | SET ").as_ref() ); } } } // Bare UCS → interactive front-end (option then value as steps), so // `UCS Z 90` is typable in the command line and works headlessly. // The front-end delegates back to the inline handler below. (#169) "UCS" => { use crate::modules::view::ucs_cmd::UcsCommand; let cmd_obj = UcsCommand::new(); self.command_line.push_info(&cmd_obj.prompt()); self.tabs[i].active_cmd = Some(Box::new(cmd_obj)); } // ── UCS management (inline `UCS