// 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, }, /// Editable text plus a dropdown of existing options (block reference /// Name row): picking an option re-points the reference, submitting a /// new name renames the definition. EditChoice { value: String, options: Vec, }, /// 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 }, /// A 0-based index navigated with ◀ / ▶ buttons (e.g. a polyline's Current /// Vertex). `display` is the label shown between the arrows (e.g. "2 / 7"). Stepper { field: &'static str, display: String }, /// 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, } // ── 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, Circle, } /// 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, /// Split the polyline at this vertex (a closed one opens here; an open /// one splits into two). Handled by the driver — it replaces the entity. BreakVertex, ConvertToLine, StretchVertex, AddLeader, RemoveLeader, ReverseArrows, MoveWithDimLine, MoveWithLeader, MoveIndependent, ResetText, RotateText, AboveDimLine, Center, OriginPoint, HatchAngle, HatchScale, HatchPattern, TangentDirection, AddFitPoint, RemoveFitPoint, Refit, RefineVertices, MoveWithText, StackText, UnstackText, }