Merge pull request #384 from KevinGriffin-new/fix/matchprop-text
Match text style and height between TEXT/MTEXT objects (#361). MATCHPROP copied only the generic properties, so Text->Text and Text->MText matching left the destination's style and height unchanged. The MatchProperties handler now also carries style + height between text-like objects, both directions, like AutoCAD's "Text" special property. bump_geometry re-tessellates so matched text repaints at its new size. Conflict: the fix (command_driver.rs) auto-merged; only the additive test block in automation.rs conflicted with tests main added since the PR branched. Resolved by keeping all four tests. # Conflicts: # src/app/automation.rs
This commit is contained in:
commit
5afee1d71f
2 changed files with 89 additions and 0 deletions
|
|
@ -651,6 +651,69 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matchprop_matches_text_style_and_height() {
|
||||||
|
// MATCHPROP between text objects must carry the text-specific
|
||||||
|
// properties (style, height) to TEXT and MTEXT destinations, not just
|
||||||
|
// the generic layer/color/linetype set. Regression for #361.
|
||||||
|
use crate::command::StepInput;
|
||||||
|
use acadrust::{EntityType, MText, Text};
|
||||||
|
|
||||||
|
let mut app = OpenCADStudio::new_for_test();
|
||||||
|
app.automation_op(r#"{"op":"new"}"#);
|
||||||
|
let i = app.active_tab;
|
||||||
|
|
||||||
|
let mut src = Text::new();
|
||||||
|
src.value = "SRC".into();
|
||||||
|
src.height = 5.0;
|
||||||
|
src.style = "BIG".into();
|
||||||
|
let src_h = app.tabs[i].scene.add_entity(EntityType::Text(src));
|
||||||
|
|
||||||
|
let mut dst_text = Text::new();
|
||||||
|
dst_text.value = "DST".into();
|
||||||
|
dst_text.height = 1.0;
|
||||||
|
let dst_text_h = app.tabs[i].scene.add_entity(EntityType::Text(dst_text));
|
||||||
|
|
||||||
|
let mut dst_mtext = MText::new();
|
||||||
|
dst_mtext.value = "DSTM".into();
|
||||||
|
dst_mtext.height = 2.0;
|
||||||
|
let dst_mtext_h = app.tabs[i].scene.add_entity(EntityType::MText(dst_mtext));
|
||||||
|
|
||||||
|
// Drive the interactive command exactly as the viewport does:
|
||||||
|
// phase 1 source pick, phase 2 destination selection.
|
||||||
|
let _ = app.run_command_line("MATCHPROP");
|
||||||
|
assert!(app.tabs[i].active_cmd.is_some(), "MATCHPROP must start");
|
||||||
|
let _ = app.feed_command(StepInput::EntityPick(src_h, glam::DVec3::ZERO));
|
||||||
|
let _ = app.feed_command(StepInput::SelectionComplete(vec![
|
||||||
|
dst_text_h,
|
||||||
|
dst_mtext_h,
|
||||||
|
]));
|
||||||
|
|
||||||
|
let doc = &app.tabs[i].scene.document;
|
||||||
|
match doc.get_entity(dst_text_h) {
|
||||||
|
Some(EntityType::Text(t)) => {
|
||||||
|
assert_eq!(t.style, "BIG", "TEXT destination must take source style");
|
||||||
|
assert!(
|
||||||
|
(t.height - 5.0).abs() < 1e-9,
|
||||||
|
"TEXT destination must take source height, got {}",
|
||||||
|
t.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
other => panic!("dest TEXT missing: {other:?}"),
|
||||||
|
}
|
||||||
|
match doc.get_entity(dst_mtext_h) {
|
||||||
|
Some(EntityType::MText(m)) => {
|
||||||
|
assert_eq!(m.style, "BIG", "MTEXT destination must take source style");
|
||||||
|
assert!(
|
||||||
|
(m.height - 5.0).abs() < 1e-9,
|
||||||
|
"MTEXT destination must take source height, got {}",
|
||||||
|
m.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
other => panic!("dest MTEXT missing: {other:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn handing_over_an_already_open_drawing_switches_to_its_tab() {
|
fn handing_over_an_already_open_drawing_switches_to_its_tab() {
|
||||||
// Double-clicking a drawing that is already open should land on the tab
|
// Double-clicking a drawing that is already open should land on the tab
|
||||||
|
|
|
||||||
|
|
@ -793,6 +793,19 @@ impl OpenCADStudio {
|
||||||
c.line_weight,
|
c.line_weight,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
// Text-specific properties travel between text-like objects
|
||||||
|
// (TEXT ↔ MTEXT, both directions), like AutoCAD's "Text"
|
||||||
|
// special property (#361).
|
||||||
|
let text_props =
|
||||||
|
self.tabs[i]
|
||||||
|
.scene
|
||||||
|
.document
|
||||||
|
.get_entity(src)
|
||||||
|
.and_then(|e| match e {
|
||||||
|
acadrust::EntityType::Text(t) => Some((t.style.clone(), t.height)),
|
||||||
|
acadrust::EntityType::MText(m) => Some((m.style.clone(), m.height)),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
|
||||||
if let Some((layer, color, linetype, lt_scale, lw)) = props {
|
if let Some((layer, color, linetype, lt_scale, lw)) = props {
|
||||||
self.push_undo_snapshot(i, "MATCHPROP");
|
self.push_undo_snapshot(i, "MATCHPROP");
|
||||||
|
|
@ -803,6 +816,19 @@ impl OpenCADStudio {
|
||||||
crate::scene::view::dispatch::apply_line_weight(e, lw);
|
crate::scene::view::dispatch::apply_line_weight(e, lw);
|
||||||
e.common_mut().linetype = linetype.clone();
|
e.common_mut().linetype = linetype.clone();
|
||||||
e.common_mut().linetype_scale = lt_scale;
|
e.common_mut().linetype_scale = lt_scale;
|
||||||
|
if let Some((style, height)) = &text_props {
|
||||||
|
match e {
|
||||||
|
acadrust::EntityType::Text(t) => {
|
||||||
|
t.style = style.clone();
|
||||||
|
t.height = *height;
|
||||||
|
}
|
||||||
|
acadrust::EntityType::MText(m) => {
|
||||||
|
m.style = style.clone();
|
||||||
|
m.height = *height;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.tabs[i].dirty = true;
|
self.tabs[i].dirty = true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue