forked from 1b-agent/opencadstudio-upstream
Selecting an INSERT with attributes now adds an editable "Attributes" section to the Properties panel — each tag is a row whose value can be changed inline (Enter commits, undo works, the attribute text repaints). Previously attribute values could only be reached through ATTEDIT, which didn't let them be changed (#192). Attribute tags are runtime strings, so they can't ride the geometry edit path whose field key is `&'static str`; a dedicated PropValue:: AttrText variant plus PropAttrInput/PropAttrCommit messages carry the tag. Values are stored verbatim (no expression evaluation, since attribute text is free-form). Also guard the panel's in-progress edit buffer: it now only carries across a rebuild when the selection is unchanged (a commit-triggered refresh), so a typed-but-uncommitted value can't display or commit onto a different entity — e.g. two title blocks sharing a REV1 tag. This closes a latent stale-buffer leak that affected geometry fields too. Co-Authored-By: Claude Opus 4.8 <[email protected]>
156 lines
5.3 KiB
Rust
156 lines
5.3 KiB
Rust
// Shared value types used by the dispatch and grip systems.
|
|
|
|
use acadrust::types::{Color as AcadColor, LineWeight};
|
|
use glam::DVec3;
|
|
|
|
/// The kind of value held by a property row.
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub enum PropValue {
|
|
/// Read-only display text.
|
|
ReadOnly(String),
|
|
/// Editable numeric/text field.
|
|
EditText(String),
|
|
/// Layer name — rendered as a combo_box.
|
|
LayerChoice(String),
|
|
/// Generic string choice rendered as a combo_box.
|
|
Choice {
|
|
selected: String,
|
|
options: Vec<String>,
|
|
},
|
|
/// ACI/RGB/ByLayer/ByBlock color — rendered as a color picker.
|
|
ColorChoice(AcadColor),
|
|
/// Color varies across the current multi-selection.
|
|
ColorVaries,
|
|
/// Line weight — rendered as a combo_box.
|
|
LwChoice(LineWeight),
|
|
/// Lineweight varies across the current multi-selection.
|
|
LwVaries,
|
|
/// Linetype name — rendered as a combo_box.
|
|
LinetypeChoice(String),
|
|
/// Boolean flag — rendered as a toggle button (e.g. Invisible).
|
|
BoolToggle { field: &'static str, value: bool },
|
|
/// Hatch pattern name — rendered as a combo_box from the catalog.
|
|
HatchPatternChoice(String),
|
|
/// Block attribute value keyed by its (dynamic, runtime) tag — rendered as
|
|
/// an editable text_input. Unlike the other rows the routing key is the
|
|
/// tag carried here, not the row's `&'static str` field.
|
|
AttrText { tag: String, value: String },
|
|
}
|
|
|
|
/// A single property row in the Properties panel.
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct Property {
|
|
pub label: String,
|
|
/// Stable field identifier used in `PropGeomInput` / `PropGeomCommit` messages.
|
|
pub field: &'static str,
|
|
pub value: PropValue,
|
|
}
|
|
|
|
/// A named section of properties (e.g. "General", "Geometry").
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
pub struct PropSection {
|
|
pub title: String,
|
|
pub props: Vec<Property>,
|
|
}
|
|
|
|
// ── Grip types ─────────────────────────────────────────────────────────────
|
|
|
|
/// Visual marker shape for a grip point. The complete vocabulary that
|
|
/// matches the standard CAD grip conventions:
|
|
/// * `Square` — endpoint / vertex / centre. Drag → moves a single
|
|
/// point or translates the entity.
|
|
/// * `Rectangle` — direction-aware mid-segment stretch handle.
|
|
/// Drawn as a small box rotated along `dir` (the in-plane segment
|
|
/// direction in world XY). Used for polyline / wipeout / image /
|
|
/// dimension segment midpoints.
|
|
/// * `Triangle` — directional indicator (Phase 2: dynamic-block
|
|
/// parameters, dimension reverse-arrow flips, multi-functional
|
|
/// hover popups).
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
#[allow(dead_code)]
|
|
pub enum GripShape {
|
|
Square,
|
|
Rectangle,
|
|
Triangle,
|
|
}
|
|
|
|
/// Describes one grip point for an entity.
|
|
#[derive(Clone, Debug)]
|
|
pub struct GripDef {
|
|
/// Object-local identifier (stable index, unique per object instance).
|
|
pub id: usize,
|
|
/// World-space position of the grip, in f64. Entity coordinates can sit at
|
|
/// UTM magnitudes (1e7); casting to f32 before the world-offset subtraction
|
|
/// loses ~1 drawing unit and draws the grip visibly off the wire. Producers
|
|
/// fill this straight from the f64 entity data; the offset is subtracted in
|
|
/// f64 and only then cast for screen-space math.
|
|
pub world: glam::DVec3,
|
|
/// `true` → midpoint / centre grip (drags the whole shape).
|
|
/// `false` → endpoint / vertex grip (moves a single point).
|
|
pub is_midpoint: bool,
|
|
/// Visual marker shape for the grip.
|
|
pub shape: GripShape,
|
|
/// World-XY direction vector used to orient a `Rectangle` grip
|
|
/// along its segment. `None` for shapes that don't need rotation
|
|
/// (Square, Triangle in non-directional contexts).
|
|
pub dir: Option<[f32; 2]>,
|
|
}
|
|
|
|
/// How to apply a grip drag result.
|
|
#[derive(Clone, Debug)]
|
|
pub enum GripApply {
|
|
/// Move a specific vertex to this absolute world position.
|
|
Absolute(DVec3),
|
|
/// Translate the whole object by this delta vector.
|
|
Translate(DVec3),
|
|
}
|
|
|
|
/// One entry in the hover-popup menu that opens when the cursor dwells
|
|
/// on a grip. The `label` is the user-visible string; `action` is the
|
|
/// operation the entity will perform when the item is committed.
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub struct GripMenuItem {
|
|
pub label: &'static str,
|
|
pub action: GripMenuAction,
|
|
}
|
|
|
|
/// All operations a grip popup menu can dispatch. Entity-specific code
|
|
/// in `apply_grip_menu` decodes these into edits. `Stretch` is the
|
|
/// default no-op-equivalent — picking it just starts the regular
|
|
/// stretch drag, identical to clicking the grip with no popup open.
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
#[allow(dead_code)]
|
|
pub enum GripMenuAction {
|
|
Stretch,
|
|
Lengthen,
|
|
Radius,
|
|
ArcLength,
|
|
AddVertex,
|
|
RemoveVertex,
|
|
ConvertToArc,
|
|
ConvertToLine,
|
|
StretchVertex,
|
|
AddLeader,
|
|
RemoveLeader,
|
|
ReverseArrows,
|
|
MoveWithDimLine,
|
|
MoveWithLeader,
|
|
MoveIndependent,
|
|
ResetText,
|
|
RotateText,
|
|
AboveDimLine,
|
|
Center,
|
|
OriginPoint,
|
|
HatchAngle,
|
|
HatchScale,
|
|
HatchPattern,
|
|
TangentDirection,
|
|
AddFitPoint,
|
|
RemoveFitPoint,
|
|
Refit,
|
|
RefineVertices,
|
|
MoveWithText,
|
|
StackText,
|
|
UnstackText,
|
|
}
|