forked from 1b-agent/opencadstudio-upstream
feat: DDEDIT command and double-click text editing
Add DDEDIT (ED alias) command that edits Text/MText/Attribute entities in-place via the command line. Double-clicking a text entity in model space now auto-launches DDEDIT for that entity. Supports Text, MText, AttributeDefinition, and AttributeEntity types. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
25ec6f66e5
commit
8078c4c9da
7 files changed
+187
-1
No files matched your search
@@ -619,6 +619,29 @@ impl H7CAD {
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
}
|
||||
CmdResult::DdeditEntity { handle, new_text } => {
|
||||
let mut updated = false;
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) {
|
||||
match entity {
|
||||
acadrust::EntityType::Text(t) => { t.value = new_text; updated = true; }
|
||||
acadrust::EntityType::MText(t) => { t.value = new_text; updated = true; }
|
||||
acadrust::EntityType::AttributeDefinition(a) => { a.default_value = new_text; updated = true; }
|
||||
acadrust::EntityType::AttributeEntity(a) => { a.set_value(new_text); updated = true; }
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
self.push_undo_snapshot(i, "DDEDIT");
|
||||
self.tabs[i].dirty = true;
|
||||
self.command_line.push_output("DDEDIT: text updated.");
|
||||
} else {
|
||||
self.command_line.push_error("DDEDIT: entity type not supported.");
|
||||
}
|
||||
self.tabs[i].active_cmd = None;
|
||||
self.tabs[i].snap_result = None;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.restore_pre_cmd_tangent();
|
||||
}
|
||||
}
|
||||
// Focus the command-line input while a command is active; blur it when the command ends.
|
||||
if self.tabs[i].active_cmd.is_some() {
|
||||
|
||||
@@ -906,6 +906,28 @@ impl H7CAD {
|
||||
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
|
||||
}
|
||||
|
||||
"DDEDIT"|"ED" => {
|
||||
use crate::modules::annotate::ddedit::{DdeditCommand, entity_text};
|
||||
// If a single text/mtext entity is already selected, skip the pick step.
|
||||
let sel = self.tabs[i].scene.selected_entities();
|
||||
if sel.len() == 1 {
|
||||
let (h, _) = sel[0];
|
||||
if let Some(e) = self.tabs[i].scene.document.get_entity(h) {
|
||||
if let Some(cur) = entity_text(e) {
|
||||
let cmd = DdeditCommand::with_handle(h, cur.clone());
|
||||
self.command_line.push_info(&format!("DDEDIT Enter new text <{cur}>:"));
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
} else {
|
||||
self.command_line.push_error("DDEDIT: selected entity is not text.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let cmd = DdeditCommand::new();
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
"MTEXT"|"MT" => {
|
||||
use crate::modules::annotate::mtext::MTextCommand;
|
||||
let new_cmd = MTextCommand::new();
|
||||
|
||||
@@ -1215,6 +1215,49 @@ impl H7CAD {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Double-click in Model Space: DDEDIT for Text/MText ────
|
||||
if is_click
|
||||
&& is_down
|
||||
&& self.tabs[i].active_cmd.is_none()
|
||||
&& self.tabs[i].scene.current_layout == "Model"
|
||||
{
|
||||
let now = Instant::now();
|
||||
let is_double_model = self
|
||||
.last_vp_click_time
|
||||
.map(|t| {
|
||||
let dt = now.duration_since(t).as_millis();
|
||||
let last = self.last_vp_click_pos.unwrap_or(p);
|
||||
let d = (p.x - last.x).hypot(p.y - last.y);
|
||||
dt < 400 && d < 8.0
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
self.last_vp_click_time = Some(now);
|
||||
self.last_vp_click_pos = Some(p);
|
||||
|
||||
if is_double_model {
|
||||
let (vw, vh) = self.tabs[i].scene.selection.borrow().vp_size;
|
||||
let bounds = iced::Rectangle { x: 0.0, y: 0.0, width: vw, height: vh };
|
||||
let vp_mat = self.tabs[i].scene.camera.borrow().view_proj(bounds);
|
||||
let all_wires = self.tabs[i].scene.hit_test_wires();
|
||||
let hit = scene::hit_test::click_hit(p, &all_wires, vp_mat, bounds)
|
||||
.and_then(|s| Scene::handle_from_wire_name(s));
|
||||
if let Some(handle) = hit {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity(handle) {
|
||||
use crate::modules::annotate::ddedit::{DdeditCommand, entity_text};
|
||||
if let Some(cur) = entity_text(entity) {
|
||||
let cmd = DdeditCommand::with_handle(handle, cur.clone());
|
||||
self.command_line.push_info(
|
||||
&format!("DDEDIT Enter new text <{cur}>:")
|
||||
);
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
return self.focus_cmd_input();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Double-click: enter/exit MSPACE ───────────────────────
|
||||
// Only when no command is running, no drag, and we're in paper space.
|
||||
if is_click
|
||||
|
||||
Reference in new issue
Block a user