forked from 1b-agent/opencadstudio-upstream
Added 15 SVG icons for all annotation tools (dimensions, leaders, table, wipeout, revision cloud, tolerance, ddedit). Annotate ribbon now has 6 groups matching standard CAD layout: - Text: MText (large dropdown) + Text + Edit Text - Dimensions: Linear (large dropdown with 6 types) + Continue + Baseline + Tolerance - Leaders: Multileader (large dropdown) + Leader - Tables: Table (large) - Markup: Wipeout + Rev Cloud - Annotation Scaling: Scale List, Add Scale, Scale Edit, Sync Scales Added pub tool() + ICON to all annotate tools that were missing them (aligned_dim, diameter_dim, dim_continue, dim_baseline, table_cmd, tolerance_cmd, ddedit), and to home/draw/wipeout and revcloud. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
98 lines
3.1 KiB
Rust
98 lines
3.1 KiB
Rust
// DDEDIT — edit text content of a Text or MText entity in-place.
|
|
//
|
|
// Workflow:
|
|
// 1. Pick a Text or MText entity (or fire from double-click with handle pre-set).
|
|
// 2. Enter new text. Press Enter to commit, Escape to cancel.
|
|
|
|
use acadrust::{EntityType, Handle};
|
|
use glam::Vec3;
|
|
|
|
use crate::command::{CadCommand, CmdResult};
|
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
|
|
|
pub const ICON: IconKind = IconKind::Svg(include_bytes!("../../../assets/icons/ddedit.svg"));
|
|
|
|
pub fn tool() -> ToolDef {
|
|
ToolDef {
|
|
id: "DDEDIT",
|
|
label: "Edit Text",
|
|
icon: ICON,
|
|
event: ModuleEvent::Command("DDEDIT".to_string()),
|
|
}
|
|
}
|
|
|
|
enum DdeditStep {
|
|
PickEntity,
|
|
EnterText { handle: Handle, current: String },
|
|
}
|
|
|
|
pub struct DdeditCommand {
|
|
step: DdeditStep,
|
|
}
|
|
|
|
impl DdeditCommand {
|
|
pub fn new() -> Self {
|
|
Self { step: DdeditStep::PickEntity }
|
|
}
|
|
|
|
/// Start with a pre-picked entity (for double-click use).
|
|
pub fn with_handle(handle: Handle, current: String) -> Self {
|
|
Self { step: DdeditStep::EnterText { handle, current } }
|
|
}
|
|
}
|
|
|
|
impl CadCommand for DdeditCommand {
|
|
fn name(&self) -> &'static str { "DDEDIT" }
|
|
|
|
fn prompt(&self) -> String {
|
|
match &self.step {
|
|
DdeditStep::PickEntity => "DDEDIT Select text entity:".into(),
|
|
DdeditStep::EnterText { current, .. } => {
|
|
format!("DDEDIT Enter new text <{current}>:")
|
|
}
|
|
}
|
|
}
|
|
|
|
fn needs_entity_pick(&self) -> bool {
|
|
matches!(self.step, DdeditStep::PickEntity)
|
|
}
|
|
|
|
fn on_entity_pick(&mut self, handle: Handle, _pt: Vec3) -> CmdResult {
|
|
if handle.is_null() { return CmdResult::NeedPoint; }
|
|
// The current value will be filled in by the caller (commands.rs dispatch)
|
|
// via on_text_input once the entity is known. Store handle here.
|
|
self.step = DdeditStep::EnterText { handle, current: String::new() };
|
|
CmdResult::NeedPoint
|
|
}
|
|
|
|
fn wants_text_input(&self) -> bool {
|
|
matches!(self.step, DdeditStep::EnterText { .. })
|
|
}
|
|
|
|
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
|
let (handle, current) = match &self.step {
|
|
DdeditStep::EnterText { handle, current } => (*handle, current.clone()),
|
|
_ => return None,
|
|
};
|
|
// Empty input → keep existing text
|
|
let new_text = if text.trim().is_empty() { current } else { text.to_string() };
|
|
Some(CmdResult::DdeditEntity { handle, new_text })
|
|
}
|
|
|
|
fn on_point(&mut self, _pt: Vec3) -> CmdResult { CmdResult::NeedPoint }
|
|
fn on_enter(&mut self) -> CmdResult { CmdResult::Cancel }
|
|
fn on_escape(&mut self) -> CmdResult { CmdResult::Cancel }
|
|
}
|
|
|
|
/// Extract the text content from a Text or MText entity.
|
|
pub fn entity_text(entity: &EntityType) -> Option<String> {
|
|
match entity {
|
|
EntityType::Text(t) => Some(t.value.clone()),
|
|
EntityType::MText(t) => Some(t.value.clone()),
|
|
EntityType::AttributeDefinition(a) => Some(a.default_value.clone()),
|
|
EntityType::AttributeEntity(a) => Some(a.get_value().to_string()),
|
|
_ => None,
|
|
}
|
|
}
|
|
|