From 65161e82db0b6f1fa90ef08b29d8314934f360ae Mon Sep 17 00:00:00 2001 From: ramox81 <184937705+ramox81@users.noreply.github.com> Date: Fri, 11 Sep 2026 13:55:23 +0300 Subject: [PATCH] Add independent layer property settings during selection --- src/app/commands/styleprops.rs | 2 +- src/modules/draw/modify/setbylayer.rs | 54 ++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/app/commands/styleprops.rs b/src/app/commands/styleprops.rs index 9f43c15ad..4b7a452c9 100644 --- a/src/app/commands/styleprops.rs +++ b/src/app/commands/styleprops.rs @@ -655,7 +655,7 @@ impl OpenCADStudio { crate::modules::draw::modify::setbylayer::set_mode(mode); } else { self.command_line.push_error("SETBYLAYERMODE requires an integer from 0 to 255."); } } - "SETBYLAYER" => { + "SETBYLAYER" | "-SETBYLAYER" => { let command = crate::modules::draw::modify::setbylayer::SetByLayerCommand::new( self.tabs[i].scene.selected.iter().copied().collect(), ); diff --git a/src/modules/draw/modify/setbylayer.rs b/src/modules/draw/modify/setbylayer.rs index d266ab542..e13b43165 100644 --- a/src/modules/draw/modify/setbylayer.rs +++ b/src/modules/draw/modify/setbylayer.rs @@ -34,19 +34,21 @@ pub fn apply_mask(common: &mut acadrust::entities::EntityCommon, mask: u8, chang *common != before } -enum Step { Selection, ByBlock, Blocks } +enum Step { Selection, Settings, ByBlock, Blocks } pub struct SetByLayerCommand { selected: Vec, step: Step, change_byblock: bool, include_blocks: bool, + pending_mode: u8, } impl SetByLayerCommand { pub fn new(selected: Vec) -> Self { let step = if selected.is_empty() { Step::Selection } else { Step::ByBlock }; - Self { selected, step, change_byblock: mode() & 32 != 0, include_blocks: mode() & 64 != 0 } + let pending_mode = mode(); + Self { selected, step, change_byblock: pending_mode & 32 != 0, include_blocks: pending_mode & 64 != 0, pending_mode } } fn answer(&mut self, yes: bool) -> CmdResult { @@ -57,13 +59,13 @@ impl SetByLayerCommand { CmdResult::NeedPoint } Step::Blocks => { - let flags = (mode() & !(32 | 64)) | if self.change_byblock { 32 } else { 0 } | if yes { 64 } else { 0 }; + let flags = (self.pending_mode & !(32 | 64)) | if self.change_byblock { 32 } else { 0 } | if yes { 64 } else { 0 }; set_mode(flags); CmdResult::Relaunch( format!("SETBYLAYER_APPLY {} {}", u8::from(self.change_byblock), u8::from(yes)), self.selected.clone(), ) }, - Step::Selection => CmdResult::NeedPoint, + Step::Selection | Step::Settings => CmdResult::NeedPoint, } } } @@ -72,7 +74,13 @@ impl CadCommand for SetByLayerCommand { fn name(&self) -> &'static str { "SETBYLAYER" } fn prompt(&self) -> String { match self.step { - Step::Selection => "Select objects:".into(), + Step::Selection => "Select objects or [Settings]:".into(), + Step::Settings => { + let active = [(1, "Color"), (2, "Linetype"), (4, "Lineweight"), (128, "Transparency"), (8, "Material")] + .into_iter().filter_map(|(bit, label)| (self.pending_mode & bit != 0).then_some(label)) + .collect::>().join(" "); + format!("Current active settings: {active}\nEnter a property to toggle [Color/LType/LWeight/Transparency/Material]:") + } Step::ByBlock => format!("Change ByBlock to ByLayer? [Yes/No] <{}>:", if self.change_byblock { "Yes" } else { "No" }), Step::Blocks => format!("Include blocks? [Yes/No] <{}>:", if self.include_blocks { "Yes" } else { "No" }), } @@ -83,19 +91,45 @@ impl CadCommand for SetByLayerCommand { CmdResult::NeedPoint } fn options(&self) -> Vec { - if self.is_selection_gathering() { Vec::new() } - else { vec![CmdOption::new("Yes", "Y"), CmdOption::new("No", "N")] } + match self.step { + Step::Selection => vec![CmdOption::new("Settings", "S")], + Step::Settings => vec![CmdOption::new("Color", "C"), CmdOption::new("LType", "LT"), CmdOption::new("LWeight", "LW"), CmdOption::new("Transparency", "T"), CmdOption::new("Material", "M")], + _ => vec![CmdOption::new("Yes", "Y"), CmdOption::new("No", "N")], + } } - fn wants_text_input(&self) -> bool { !self.is_selection_gathering() } + fn wants_text_input(&self) -> bool { true } fn on_point(&mut self, _: DVec3) -> CmdResult { CmdResult::NeedPoint } fn on_enter(&mut self) -> CmdResult { + if matches!(self.step, Step::Settings) { + self.step = Step::Selection; + return CmdResult::NeedPoint; + } if self.is_selection_gathering() { if self.selected.is_empty() { CmdResult::Cancel } else { self.step = Step::ByBlock; CmdResult::NeedPoint } } else { self.answer(if matches!(self.step, Step::ByBlock) { self.change_byblock } else { self.include_blocks }) } } fn on_text_input(&mut self, text: &str) -> Option { - Some(match text.trim().to_uppercase().as_str() { + let text = text.trim().trim_start_matches('_').to_uppercase(); + if matches!(self.step, Step::Selection) { + return if matches!(text.as_str(), "S" | "SETTINGS") { + self.step = Step::Settings; + Some(CmdResult::NeedPoint) + } else { None }; + } + if matches!(self.step, Step::Settings) { + let bit = match text.as_str() { + "C" | "COLOR" => 1, + "LT" | "LTYPE" => 2, + "LW" | "LWEIGHT" => 4, + "T" | "TRANSPARENCY" => 128, + "M" | "MATERIAL" => 8, + _ => return Some(CmdResult::NeedPoint), + }; + self.pending_mode ^= bit; + return Some(CmdResult::NeedPoint); + } + Some(match text.as_str() { "Y" | "YES" => self.answer(true), "N" | "NO" => self.answer(false), _ => CmdResult::NeedPoint, @@ -116,7 +150,7 @@ impl CadCommand for ModeCommand { } else { CmdResult::NeedPoint }) } } -inventory::submit!(crate::command::CommandRegistration { names: &["SETBYLAYERMODE"] }); +inventory::submit!(crate::command::CommandRegistration { names: &["SETBYLAYERMODE", "-SETBYLAYER"] }); #[cfg(test)] mod tests {