feat(mline): align creation and editing

This commit is contained in:
Hakan Seven 2026-08-23 00:30:41 +03:00
commit 343b6cda7d
15 changed files with 2852 additions and 311 deletions

View file

@ -662,6 +662,26 @@ impl OpenCADStudio {
tab.dirty = true;
}
}
let mline_settings = self.tabs[self.active_tab]
.active_cmd
.as_ref()
.and_then(|command| command.mline_settings());
if let Some((scale, justification, style_name, style_handle)) = mline_settings {
let tab = &mut self.tabs[self.active_tab];
let header = &mut tab.scene.document.header;
let style_handle = style_handle.unwrap_or(acadrust::Handle::NULL);
let changed = (header.multiline_scale - scale).abs() > f64::EPSILON
|| header.multiline_justification != justification
|| !header.multiline_style.eq_ignore_ascii_case(&style_name)
|| header.current_multiline_style_handle != style_handle;
if changed {
header.multiline_scale = scale;
header.multiline_justification = justification;
header.multiline_style = style_name;
header.current_multiline_style_handle = style_handle;
tab.dirty = true;
}
}
let was_active = self.tabs[self.active_tab].active_cmd.is_some();
let preserve_selection =
matches!(result, CmdResult::Relaunch(..) | CmdResult::Dispatch(..));

View file

@ -13,27 +13,27 @@ impl OpenCADStudio {
"MLINE" => {
use crate::modules::draw::draw::mline::MlineCommand;
let style_name = self.tabs[i].scene.document.header.multiline_style.clone();
let style = self.tabs[i]
let header = &self.tabs[i].scene.document.header;
let style_name = header.multiline_style.clone();
let scale = header.multiline_scale;
let justification = header.multiline_justification;
let styles = self.tabs[i]
.scene
.document
.objects
.iter()
.find_map(|(handle, object)| match object {
acadrust::objects::ObjectType::MLineStyle(style)
if style.name.eq_ignore_ascii_case(&style_name) =>
{
Some((*handle, style.elements.len()))
.filter_map(|(handle, object)| match object {
acadrust::objects::ObjectType::MLineStyle(style) => {
Some((*handle, style.clone()))
}
_ => None,
});
let (style_handle, element_count) = style
.map(|(handle, count)| (Some(handle), count))
.unwrap_or((None, 2));
let cmd_obj = MlineCommand::with_style(
})
.collect();
let cmd_obj = MlineCommand::with_styles(
styles,
style_name,
style_handle,
element_count,
scale,
justification,
);
self.command_line.push_info(&cmd_obj.prompt());
self.tabs[i].active_cmd = Some(Box::new(cmd_obj));

View file

@ -286,6 +286,34 @@ impl OpenCADStudio {
self.tabs[i].active_cmd = Some(Box::new(cmd_obj));
}
"MLEDIT" => {
use crate::modules::draw::modify::mledit::{
MlineEditCommand, MlineEditTarget,
};
let document = &self.tabs[i].scene.document;
let targets = document
.entities()
.filter_map(|entity| {
let acadrust::EntityType::MLine(mline) = entity else {
return None;
};
let style = crate::entities::mline::resolved_mline_style(mline, document)
.cloned()
.unwrap_or_else(acadrust::objects::MLineStyle::standard);
Some((
entity.common().handle.value(),
MlineEditTarget {
entity: mline.clone(),
style,
},
))
})
.collect();
let command = MlineEditCommand::new(targets);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
"SPLINEDIT" => {
use crate::modules::draw::modify::splinedit::SplineditCommand;
let cmd_obj = SplineditCommand::new();

View file

@ -512,6 +512,8 @@ inventory::submit!(crate::command::CommandRegistration {
"SHADEDGE",
"MAXACTVP",
"CMLJUST",
"CMLSCALE",
"CMLSTYLE",
"TEXTQLTY",
"SORTENTS",
"FRAME",

View file

@ -920,6 +920,8 @@ impl OpenCADStudio {
| "SHADEDGE"
| "MAXACTVP"
| "CMLJUST"
| "CMLSCALE"
| "CMLSTYLE"
| "TEXTQLTY"
| "SORTENTS"
| "FRAME"
@ -1697,17 +1699,35 @@ impl OpenCADStudio {
}
},
"CMLJUST" => match &value {
Some(v) => v
.parse::<i16>()
.map(|x| {
Some(v) => match v.parse::<i16>() {
Ok(x @ 0..=2) => {
h.multiline_justification = x;
(format!("CMLJUST = {x}"), true)
})
.map_err(|_| "SETVAR: integer value required.".into()),
Ok((format!("CMLJUST = {x}"), true))
}
_ => Err("SETVAR: integer value from 0 to 2 required.".into()),
},
None => {
Ok((format!("CMLJUST = {}", h.multiline_justification), false))
}
},
"CMLSCALE" => match &value {
Some(v) => match v.parse::<f64>() {
Ok(x) if x.is_finite() => {
let changed = h.multiline_scale != x;
h.multiline_scale = x;
Ok((format!("CMLSCALE = {x}"), changed))
}
_ => Err("SETVAR: finite numeric value required.".into()),
},
None => Ok((format!("CMLSCALE = {}", h.multiline_scale), false)),
},
"CMLSTYLE" => match &value {
Some(_) => Err(
"SETVAR: CMLSTYLE is read-only here — use the MLSTYLE command."
.into(),
),
None => Ok((format!("CMLSTYLE = {}", h.multiline_style), false)),
},
"TEXTQLTY" => match &value {
Some(v) => v
.parse::<i16>()

View file

@ -2195,6 +2195,20 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
crate::command::WorkingPlane::default()
};
for &handle in &handles {
let mline_style = self.tabs[i]
.scene
.document
.get_entity(handle)
.and_then(|entity| match entity {
acadrust::EntityType::MLine(mline) => {
crate::entities::mline::resolved_mline_style(
mline,
&self.tabs[i].scene.document,
)
.cloned()
}
_ => None,
});
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle)
{
crate::scene::view::dispatch::apply_geom_prop_in_working_plane(
@ -2203,6 +2217,17 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
&value,
plane,
);
if matches!(field, "ml_justification" | "ml_scale") {
if let (
acadrust::EntityType::MLine(mline),
Some(style),
) = (entity, mline_style.as_ref())
{
crate::modules::draw::draw::mline::sync_mline_element_parameters(
mline, style,
);
}
}
}
}
}
@ -2399,6 +2424,20 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
)
.is_none()
{
let mline_style = self.tabs[i]
.scene
.document
.get_entity(handle)
.and_then(|entity| match entity {
acadrust::EntityType::MLine(mline) => {
crate::entities::mline::resolved_mline_style(
mline,
&self.tabs[i].scene.document,
)
.cloned()
}
_ => None,
});
if let Some(entity) = self.tabs[i]
.scene
.document
@ -2410,6 +2449,17 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
&val,
plane,
);
if field == "ml_scale" {
if let (
acadrust::EntityType::MLine(mline),
Some(style),
) = (entity, mline_style.as_ref())
{
crate::modules::draw::draw::mline::sync_mline_element_parameters(
mline, style,
);
}
}
}
}
}