fix(annotate): align annotation ribbon workflows

This commit is contained in:
ramox81 committed 2026-09-14 11:55:08 +03:00
1 parent fc1788df65
commit 6505b27818
26 files changed
+1921 -345

No files matched your search

+99 -15
View File
@@ -10,12 +10,12 @@
// (DXF group 340); editing/erasing them stays in sync via that link.
use acadrust::entities::mtext::AttachmentPoint;
use acadrust::entities::{Leader, LeaderCreationType, MText};
use acadrust::entities::{Leader, LeaderCreationType, LeaderPathType, MText};
use acadrust::types::Vector3;
use acadrust::EntityType;
use glam::{DVec3, Mat4, Vec3};
use crate::command::{CadCommand, CmdResult, WorkingPlane};
use crate::command::{CadCommand, CmdOption, CmdResult, InputKind, WorkingPlane};
use crate::modules::{IconKind, ModuleEvent, ToolDef};
use crate::scene::model::wire_model::WireModel;
use crate::t;
@@ -31,8 +31,17 @@ pub fn tool() -> ToolDef {
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum Step {
Points,
Format,
}
pub struct LeaderCommand {
verts: Vec<DVec3>,
step: Step,
path_type: LeaderPathType,
arrow_enabled: bool,
plane: WorkingPlane,
dimension_style: String,
text_style: String,
@@ -56,6 +65,9 @@ impl LeaderCommand {
Self {
verts: Vec::new(),
step: Step::Points,
path_type: LeaderPathType::StraightLine,
arrow_enabled: true,
plane: WorkingPlane::default(),
dimension_style: defaults.style_name,
text_style: defaults.text_style_name,
@@ -91,7 +103,7 @@ impl LeaderCommand {
let mut leader_points = local.clone();
let first = local[0];
let elbow = local[1];
let elbow = *local.last().unwrap_or(&first);
let sign = if elbow.x >= first.x { 1.0 } else { -1.0 };
let landing_end = DVec3::new(
@@ -102,7 +114,7 @@ impl LeaderCommand {
leader_points.push(landing_end);
let leader = build_leader(
let mut leader = build_leader(
&leader_points,
Mat4::IDENTITY,
&self.dimension_style,
@@ -110,6 +122,8 @@ impl LeaderCommand {
self.gap,
self.arrow_size,
);
leader.path_type = self.path_type;
leader.arrow_enabled = self.arrow_enabled;
// The MTEXT starts at the real end of the landing.
let (anchor, attach) =
@@ -150,25 +164,95 @@ impl CadCommand for LeaderCommand {
}
fn prompt(&self) -> String {
if self.verts.is_empty() {
t!("LEADER Specify arrowhead point:").into_owned()
if self.step == Step::Format {
return t!("LEADER Enter leader formatting option [Spline/Straight/Arrow/None] <exit>:")
.into_owned();
}
match self.verts.len() {
0 => t!("LEADER Specify leader start point:").into_owned(),
1 => t!("LEADER Specify next point:").into_owned(),
_ => t!("LEADER Specify next point or [Annotation/Format/Undo] <Annotation>:")
.into_owned(),
}
}
fn options(&self) -> Vec<CmdOption> {
if self.step == Step::Format {
return vec![
CmdOption::new("Spline", "SPLINE"),
CmdOption::new("Straight", "STRAIGHT"),
CmdOption::new("Arrow", "ARROW"),
CmdOption::new("None", "NONE"),
];
}
if self.verts.len() >= 2 {
vec![
CmdOption::new("Annotation", "ANNOTATION"),
CmdOption::new("Format", "FORMAT"),
CmdOption::new("Undo", "UNDO"),
]
} else {
t!("LEADER Specify landing point:").into_owned()
Vec::new()
}
}
fn input_kind(&self) -> InputKind {
if self.step == Step::Format {
InputKind::SingleToken
} else {
InputKind::Point
}
}
fn point_step_accepts_keywords(&self) -> bool {
self.step == Step::Points && self.verts.len() >= 2
}
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
let keyword = text.trim().to_ascii_uppercase();
if self.step == Step::Format {
match keyword.as_str() {
"S" | "SPLINE" => self.path_type = LeaderPathType::Spline,
"ST" | "STRAIGHT" => self.path_type = LeaderPathType::StraightLine,
"A" | "ARROW" => self.arrow_enabled = true,
"N" | "NONE" => self.arrow_enabled = false,
_ => return None,
}
self.step = Step::Points;
return Some(CmdResult::NeedPoint);
}
if self.verts.len() < 2 {
return None;
}
match keyword.as_str() {
"A" | "ANNOTATION" => Some(self.finish()),
"F" | "FORMAT" => {
self.step = Step::Format;
Some(CmdResult::NeedPoint)
}
"U" | "UNDO" => {
self.verts.pop();
Some(CmdResult::NeedPoint)
}
_ => None,
}
}
fn on_point(&mut self, pt: DVec3) -> CmdResult {
self.verts.push(pt);
if self.verts.len() >= 2 {
self.finish()
} else {
CmdResult::NeedPoint
if self.step != Step::Points {
return CmdResult::NeedPoint;
}
self.verts.push(pt);
CmdResult::NeedPoint
}
fn on_enter(&mut self) -> CmdResult {
self.finish()
if self.step == Step::Format {
self.step = Step::Points;
CmdResult::NeedPoint
} else {
self.finish()
}
}
fn on_escape(&mut self) -> CmdResult {
@@ -176,7 +260,7 @@ impl CadCommand for LeaderCommand {
}
fn on_mouse_move(&mut self, pt: DVec3) -> Option<WireModel> {
if self.verts.is_empty() {
if self.step != Step::Points || self.verts.is_empty() {
return None;
}
let mut pts: Vec<Vec3> = self