forked from 1b-agent/opencadstudio-upstream
Double-clicking a block reference that has attributes, or running ATTEDIT on one, now opens an editor dialog listing every attribute (tag + editable value) with OK / Cancel. OK writes the values back to the block, with undo and a repaint; Cancel discards. A block with no attributes still enters in-place block edit (REFEDIT) on double-click as before. (#192) ATTEDIT opens the dialog directly when a suitable block is already selected; otherwise it runs the pick command and the dialog opens once a block is chosen. This replaces the earlier command-line, per-attribute prompt flow, which is removed along with its __ATTEDIT__ sentinel path and the now-unused attedit_set_attrs trait hook; the ATTEDIT command is reduced to a plain block picker. The dialog is a tab-scoped in-canvas modal (Plan B): its working copy holds a document-local handle, so closing that tab or switching away dismisses the editor rather than risk applying edits to another tab's document. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
2.0 KiB
Rust
66 lines
2.0 KiB
Rust
// ATTEDIT command — pick a block reference with attributes, then open the
|
|
// attribute editor dialog on it.
|
|
//
|
|
// This command only performs the entity pick. Once a block is chosen it
|
|
// reports the handle through `attedit_pending_handle`; the command host
|
|
// (`command_driver`) ends the command and opens the editor dialog. When a
|
|
// suitable block is already selected, the ATTEDIT dispatch opens the dialog
|
|
// directly and never starts this command (see `app::commands::inquiry`).
|
|
|
|
use glam::DVec3;
|
|
|
|
use crate::command::{CadCommand, CmdResult};
|
|
use crate::scene::model::wire_model::WireModel;
|
|
|
|
pub struct AtteditCommand {
|
|
/// The picked block reference, once the user clicks one.
|
|
picked: Option<acadrust::Handle>,
|
|
}
|
|
|
|
impl AtteditCommand {
|
|
pub fn new() -> Self {
|
|
Self { picked: None }
|
|
}
|
|
}
|
|
|
|
impl CadCommand for AtteditCommand {
|
|
fn name(&self) -> &'static str {
|
|
"ATTEDIT"
|
|
}
|
|
|
|
fn prompt(&self) -> String {
|
|
"ATTEDIT Select block with attributes:".to_string()
|
|
}
|
|
|
|
fn needs_entity_pick(&self) -> bool {
|
|
self.picked.is_none()
|
|
}
|
|
|
|
fn on_entity_pick(&mut self, handle: acadrust::Handle, _pt: DVec3) -> CmdResult {
|
|
if handle.is_null() {
|
|
return CmdResult::NeedPoint;
|
|
}
|
|
// Record the pick and yield: the host reads `attedit_pending_handle`
|
|
// and opens the editor dialog for this block.
|
|
self.picked = Some(handle);
|
|
CmdResult::NeedPoint
|
|
}
|
|
|
|
fn on_point(&mut self, _pt: DVec3) -> CmdResult {
|
|
CmdResult::NeedPoint
|
|
}
|
|
fn on_enter(&mut self) -> CmdResult {
|
|
CmdResult::Cancel
|
|
}
|
|
fn on_preview_wires(&mut self, _pt: DVec3) -> Vec<WireModel> {
|
|
vec![]
|
|
}
|
|
|
|
fn attedit_pending_handle(&self) -> Option<acadrust::Handle> {
|
|
self.picked
|
|
}
|
|
}
|
|
|
|
// ── Autocomplete registry ─────────────────────────────────
|
|
inventory::submit!(crate::command::CommandRegistration { names: &["ATTEDIT", "ATE"] });
|