diff --git a/src/app/commands/draw.rs b/src/app/commands/draw.rs index fc707b846..2ed934146 100644 --- a/src/app/commands/draw.rs +++ b/src/app/commands/draw.rs @@ -808,7 +808,7 @@ impl OpenCADStudio { scale, angle, annotative, - ).with_appearance(entity,self.tabs[i].scene.document.header.current_entity_color); + ).with_appearance(entity,self.tabs[i].scene.document.header.current_entity_color,self.tabs[i].scene.document.current_entity_transparency()); self.command_line.push_info(&cmd.prompt()); self.tabs[i].active_cmd = Some(Box::new(cmd)); } else { @@ -816,7 +816,7 @@ impl OpenCADStudio { .push_error(crate::t!("HATCHEDIT: selected entity is not a hatch.").as_ref()); } } else { - let cmd = HatcheditCommand::new(); + let cmd = HatcheditCommand::new().with_appearance(None,self.tabs[i].scene.document.header.current_entity_color,self.tabs[i].scene.document.current_entity_transparency()); self.command_line.push_info(&cmd.prompt()); self.tabs[i].active_cmd = Some(Box::new(cmd)); } diff --git a/src/app/commands/mod.rs b/src/app/commands/mod.rs index e3650b5d1..16412b2e0 100644 --- a/src/app/commands/mod.rs +++ b/src/app/commands/mod.rs @@ -368,6 +368,7 @@ inventory::submit!(crate::command::CommandRegistration { "COLOR", "COLOUR", "CECOLOR", + "CETRANSPARENCY", "DDCOLOR", "BYLAYER", // Synchronise block attributes. diff --git a/src/app/commands/styleprops.rs b/src/app/commands/styleprops.rs index b99da19b4..ac579628b 100644 --- a/src/app/commands/styleprops.rs +++ b/src/app/commands/styleprops.rs @@ -3,6 +3,10 @@ use super::*; impl OpenCADStudio { pub(super) fn dispatch_styleprops(&mut self, cmd: &str, i: usize) -> Option> { match cmd { + "CETRANSPARENCY" => return self.dispatch_styleprops("SETVAR CETRANSPARENCY", i), + cmd if cmd.starts_with("CETRANSPARENCY ") => { + return self.dispatch_styleprops(&format!("SETVAR {cmd}"), i); + } "FRAMES0" => return self.dispatch_styleprops("SETVAR FRAME 0", i), "FRAMES1" => return self.dispatch_styleprops("SETVAR FRAME 1", i), "FRAMES2" => return self.dispatch_styleprops("SETVAR FRAME 2", i), @@ -941,9 +945,33 @@ impl OpenCADStudio { let value = it.next().map(|s| s.trim().to_string()); if name.is_empty() || name == "?" { self.command_line.push_info( - crate::t!("SETVAR: LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG TEXTFILL CLIPROMPTLINES COMMANDLINEFADETIME ATTREQ ATTDIA DIMASSOC DIMCONTINUEMODE ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE DONUTID DONUTOD CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE COLORTHEME SELECTIONAREA SELECTIONAREAOPACITY SELECTIONEFFECT SELECTIONEFFECTCOLOR WINDOWSAREACOLOR CROSSINGAREACOLOR SELECTIONPREVIEW GRIPSIZE GRIPCOLOR GRIPHOT GRIPHOVER GRIPOBJLIMIT | CLAYER CELTYPE TEXTSTYLE (read-only)").as_ref(), + crate::t!("SETVAR: CETRANSPARENCY LTSCALE CELTSCALE PDMODE PDSIZE TEXTSIZE ORTHOMODE FILLMODE MIRRTEXT FRAME IMAGEFRAME PDFFRAME WIPEOUTFRAME XCLIPFRAME POINTCLOUDCLIPFRAME ZOOMWHEEL ZOOMFACTOR CURSORSIZE PICKBOX CURSORTYPE SNAPANG TEXTFILL CLIPROMPTLINES COMMANDLINEFADETIME ATTREQ ATTDIA DIMASSOC DIMCONTINUEMODE ANGBASE ANGDIR SKETCHINC SKPOLY SKTOLERANCE DONUTID DONUTOD CENTEREXE CENTERLAYER CENTERLTYPE CENTERLTSCALE CENTERLTYPEFILE CENTERCROSSSIZE CENTERCROSSGAP CENTERMARKEXE COLORTHEME SELECTIONAREA SELECTIONAREAOPACITY SELECTIONEFFECT SELECTIONEFFECTCOLOR WINDOWSAREACOLOR CROSSINGAREACOLOR SELECTIONPREVIEW GRIPSIZE GRIPCOLOR GRIPHOT GRIPHOVER GRIPOBJLIMIT | CLAYER CELTYPE TEXTSTYLE (read-only)").as_ref(), ); } else { + if name == "CETRANSPARENCY" { + let current = self.tabs[i].scene.document.current_entity_transparency(); + if let Some(value) = &value { + match crate::scene::creation_style::parse_current_transparency(value) { + Some(transparency) => { + if current != transparency { + self.push_undo_snapshot(i, &name); + if !self.tabs[i].scene.document.set_current_entity_transparency(transparency) { + self.command_line.push_error("CETRANSPARENCY: drawing variable dictionary is invalid."); + return Some(self.finish_dispatch(cmd)); + } + self.tabs[i].dirty = true; + self.refresh_properties(); + } + self.command_line.push_output(&format!("CETRANSPARENCY = {}", crate::scene::creation_style::current_transparency_label(transparency))); + } + None => self.command_line.push_error("CETRANSPARENCY: expected ByLayer (-1), ByBlock (-2), or an integer from 0 to 90."), + } + } else { + self.command_line.push_output(&format!("Enter new value for CETRANSPARENCY <{}>:", crate::scene::creation_style::current_transparency_label(current))); + self.pending_setvar = Some(name.clone()); + } + return Some(self.finish_dispatch(cmd)); + } if matches!(name.as_str(), "SHOWHIST" | "SOLIDHIST") { let current = if name == "SHOWHIST" { self.tabs[i].scene.document.header.show_solid_history.clamp(0, 2) diff --git a/src/app/properties.rs b/src/app/properties.rs index 79bf7c7c8..49c0edaaa 100644 --- a/src/app/properties.rs +++ b/src/app/properties.rs @@ -306,7 +306,7 @@ impl OpenCADStudio { label: t!("Transparency").into_owned(), field: "transparency", value: PropValue::EditChoice { - value: "ByLayer".to_string(), + value: crate::scene::creation_style::current_transparency_label(self.tabs[i].scene.document.current_entity_transparency()), options: vec!["ByLayer".to_string(), "ByBlock".to_string()], }, }, diff --git a/src/app/update/command.rs b/src/app/update/command.rs index 23df084a7..0b927aabf 100644 --- a/src/app/update/command.rs +++ b/src/app/update/command.rs @@ -2808,7 +2808,17 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task { } else { match field { "transparency" => { - self.tabs[i].dirty = true; + let Some(transparency) = crate::scene::creation_style::parse_current_transparency(&value) else { + self.command_line.push_error("Transparency: expected ByLayer, ByBlock, or an integer from 0 to 90."); + self.refresh_properties(); + return Task::none(); + }; + self.push_undo_snapshot(i, "CETRANSPARENCY"); + if self.tabs[i].scene.document.set_current_entity_transparency(transparency) { + self.tabs[i].dirty = true; + } else { + self.command_line.push_error("CETRANSPARENCY: drawing variable dictionary is invalid."); + } self.refresh_properties(); } "material" => { diff --git a/src/modules/draw/draw/hatchedit.rs b/src/modules/draw/draw/hatchedit.rs index 807babf52..984965e0b 100644 --- a/src/modules/draw/draw/hatchedit.rs +++ b/src/modules/draw/draw/hatchedit.rs @@ -35,6 +35,7 @@ pub struct HatcheditCommand { boundary_selection: Vec, source_appearance: Option<(acadrust::types::Color,String,acadrust::types::Transparency)>, current_color: acadrust::types::Color, + current_transparency: acadrust::types::Transparency, boundary_region: bool, } @@ -51,6 +52,7 @@ impl HatcheditCommand { boundary_selection: Vec::new(), source_appearance: None, current_color: acadrust::types::Color::ByLayer, + current_transparency: acadrust::types::Transparency::ByLayer, boundary_region: false, } } @@ -78,6 +80,7 @@ impl HatcheditCommand { boundary_selection: Vec::new(), source_appearance: None, current_color: acadrust::types::Color::ByLayer, + current_transparency: acadrust::types::Transparency::ByLayer, boundary_region: false, } } @@ -105,9 +108,9 @@ impl HatcheditCommand { let mut command=Self::with_handle(handle,name,scale,angle,false); command.input=Some("associate-select");command } - pub fn with_appearance(mut self,entity:Option<&acadrust::EntityType>,current_color:acadrust::types::Color)->Self { + pub fn with_appearance(mut self,entity:Option<&acadrust::EntityType>,current_color:acadrust::types::Color,current_transparency:acadrust::types::Transparency)->Self { self.source_appearance=entity.map(|e|{let c=e.common();(c.color,c.layer.clone(),c.transparency)}); - self.current_color=current_color;self + self.current_color=current_color;self.current_transparency=current_transparency;self } fn update_operation(&self) -> HatchEditOperation { @@ -249,7 +252,7 @@ impl CadCommand for HatcheditCommand { } "layer"=>if !text.trim().is_empty(){return self.apply_result(appearance(None,Some(text.trim().to_owned()),None));}, "transparency"=>{ - let value=match keyword.as_str(){"BYLAYER"=>Some(Transparency::BY_LAYER),"BYBLOCK"=>Some(Transparency::BY_BLOCK), + let value=match keyword.as_str(){"."=>Some(self.current_transparency),"BYLAYER"=>Some(Transparency::BY_LAYER),"BYBLOCK"=>Some(Transparency::BY_BLOCK), n=>n.parse::().ok().filter(|v|*v<=90).map(|v|Transparency::from_percent(v as f64 / 100.0))}; if let Some(value)=value{return self.apply_result(appearance(None,None,Some(value)));} } diff --git a/src/scene/creation_style.rs b/src/scene/creation_style.rs index 442d61189..fa2902f74 100644 --- a/src/scene/creation_style.rs +++ b/src/scene/creation_style.rs @@ -252,7 +252,27 @@ fn apply_object_defaults(doc: &CadDocument, entity: &mut EntityType) { } pub fn apply_current_creation_styles(doc: &CadDocument, entity: &mut EntityType) { + entity.common_mut().transparency = doc.current_entity_transparency(); apply_text_defaults(doc, entity); apply_dimension_defaults(doc, entity); apply_object_defaults(doc, entity); } + +pub(crate) fn parse_current_transparency(value: &str) -> Option { + use acadrust::types::Transparency; + match value.trim().to_ascii_uppercase().as_str() { + "BYLAYER" | "-1" => Some(Transparency::ByLayer), + "BYBLOCK" | "-2" => Some(Transparency::ByBlock), + value => value.parse::().ok().filter(|value| *value <= 90) + .map(|value| Transparency::from_percent(value as f64 / 100.0)), + } +} + +pub(crate) fn current_transparency_label(value: acadrust::types::Transparency) -> String { + use acadrust::types::Transparency; + match value { + Transparency::ByLayer => "ByLayer".into(), + Transparency::ByBlock => "ByBlock".into(), + Transparency::Explicit(_) => format!("{:.0}", value.as_percent() * 100.0), + } +} diff --git a/src/scene/entity.rs b/src/scene/entity.rs index 02ed14956..2943e7458 100644 --- a/src/scene/entity.rs +++ b/src/scene/entity.rs @@ -2671,6 +2671,8 @@ impl Scene { if let Some((color, transparency)) = entity_style { entity.common_mut().color = color; entity.common_mut().transparency = transparency; + } else { + entity.common_mut().transparency = self.document.current_entity_transparency(); } self.add_entity(entity)