2026-03-22 14:56:27 +03:00
|
|
|
// Shared value types used by the dispatch and grip systems.
|
|
|
|
|
|
|
|
|
|
use acadrust::types::{Color as AcadColor, LineWeight};
|
|
|
|
|
use glam::Vec3;
|
|
|
|
|
|
|
|
|
|
/// 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),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 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 ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
refactor(grip): square-only marker set + oriented stretch handles
Phase 1 of bringing the grip vocabulary in line with the standard
CAD convention: drop the per-position-type shape encoding (Diamond
for translate, Circle for parameter) and use a plain square for
every endpoint / vertex / centre grip. The behavioural midpoint vs
vertex distinction stays — it lives on `GripDef::is_midpoint` and
drives `Translate` vs `Absolute` in the grip-edit dispatcher — only
the marker shape collapses.
- `GripShape` keeps `Square`, `Rectangle`, `Triangle`. Diamond /
Circle are gone.
- `GripDef` gains `dir: Option<[f32; 2]>` — a world-XY direction
vector consumed by `Rectangle` to orient the box along its
segment.
- `entities::common` exposes `square_grip`, `center_grip` (same
square marker, flagged as translate), `rectangle_grip(id, world,
dir)` for oriented mid-segment handles, and a kept-for-Phase-2
`triangle_grip`.
- `overlay::GripMarker` / `grips_to_screen[_paper]` thread `dir`
through to the canvas painter; the Rectangle path rotates the
box around the grip centre using the world-XY direction (flipping
the sin for screen-Y).
Every existing `diamond_grip(id, w)` call becomes `center_grip(id,
w)` — the visual change is square-replacing-diamond at line
midpoints / arc midpoints / circle centres / ellipse centres /
viewport / hatch loop centroids / dimension grips / image corners /
multileader / ray / underlay / ole2frame / solid3d.
`LwPolyline` grows a stretch handle on every segment (straight or
arc), drawn as the new oriented rectangle. The grip-edit path
translates both segment endpoints for straight segments and
adjusts the arc bulge from the new midpoint for arc segments.
2026-05-29 02:07:34 +03:00
|
|
|
/// 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).
|
2026-03-22 14:56:27 +03:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
2026-05-29 01:46:33 +03:00
|
|
|
#[allow(dead_code)]
|
2026-03-22 14:56:27 +03:00
|
|
|
pub enum GripShape {
|
|
|
|
|
Square,
|
2026-05-29 01:46:33 +03:00
|
|
|
Rectangle,
|
2026-03-22 14:56:27 +03:00
|
|
|
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.
|
|
|
|
|
pub world: Vec3,
|
refactor(grip): square-only marker set + oriented stretch handles
Phase 1 of bringing the grip vocabulary in line with the standard
CAD convention: drop the per-position-type shape encoding (Diamond
for translate, Circle for parameter) and use a plain square for
every endpoint / vertex / centre grip. The behavioural midpoint vs
vertex distinction stays — it lives on `GripDef::is_midpoint` and
drives `Translate` vs `Absolute` in the grip-edit dispatcher — only
the marker shape collapses.
- `GripShape` keeps `Square`, `Rectangle`, `Triangle`. Diamond /
Circle are gone.
- `GripDef` gains `dir: Option<[f32; 2]>` — a world-XY direction
vector consumed by `Rectangle` to orient the box along its
segment.
- `entities::common` exposes `square_grip`, `center_grip` (same
square marker, flagged as translate), `rectangle_grip(id, world,
dir)` for oriented mid-segment handles, and a kept-for-Phase-2
`triangle_grip`.
- `overlay::GripMarker` / `grips_to_screen[_paper]` thread `dir`
through to the canvas painter; the Rectangle path rotates the
box around the grip centre using the world-XY direction (flipping
the sin for screen-Y).
Every existing `diamond_grip(id, w)` call becomes `center_grip(id,
w)` — the visual change is square-replacing-diamond at line
midpoints / arc midpoints / circle centres / ellipse centres /
viewport / hatch loop centroids / dimension grips / image corners /
multileader / ray / underlay / ole2frame / solid3d.
`LwPolyline` grows a stretch handle on every segment (straight or
arc), drawn as the new oriented rectangle. The grip-edit path
translates both segment endpoints for straight segments and
adjusts the arc bulge from the new midpoint for arc segments.
2026-05-29 02:07:34 +03:00
|
|
|
/// `true` → midpoint / centre grip (drags the whole shape).
|
|
|
|
|
/// `false` → endpoint / vertex grip (moves a single point).
|
2026-03-22 14:56:27 +03:00
|
|
|
pub is_midpoint: bool,
|
|
|
|
|
/// Visual marker shape for the grip.
|
|
|
|
|
pub shape: GripShape,
|
refactor(grip): square-only marker set + oriented stretch handles
Phase 1 of bringing the grip vocabulary in line with the standard
CAD convention: drop the per-position-type shape encoding (Diamond
for translate, Circle for parameter) and use a plain square for
every endpoint / vertex / centre grip. The behavioural midpoint vs
vertex distinction stays — it lives on `GripDef::is_midpoint` and
drives `Translate` vs `Absolute` in the grip-edit dispatcher — only
the marker shape collapses.
- `GripShape` keeps `Square`, `Rectangle`, `Triangle`. Diamond /
Circle are gone.
- `GripDef` gains `dir: Option<[f32; 2]>` — a world-XY direction
vector consumed by `Rectangle` to orient the box along its
segment.
- `entities::common` exposes `square_grip`, `center_grip` (same
square marker, flagged as translate), `rectangle_grip(id, world,
dir)` for oriented mid-segment handles, and a kept-for-Phase-2
`triangle_grip`.
- `overlay::GripMarker` / `grips_to_screen[_paper]` thread `dir`
through to the canvas painter; the Rectangle path rotates the
box around the grip centre using the world-XY direction (flipping
the sin for screen-Y).
Every existing `diamond_grip(id, w)` call becomes `center_grip(id,
w)` — the visual change is square-replacing-diamond at line
midpoints / arc midpoints / circle centres / ellipse centres /
viewport / hatch loop centroids / dimension grips / image corners /
multileader / ray / underlay / ole2frame / solid3d.
`LwPolyline` grows a stretch handle on every segment (straight or
arc), drawn as the new oriented rectangle. The grip-edit path
translates both segment endpoints for straight segments and
adjusts the arc bulge from the new midpoint for arc segments.
2026-05-29 02:07:34 +03:00
|
|
|
/// 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]>,
|
2026-03-22 14:56:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// How to apply a grip drag result.
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
|
pub enum GripApply {
|
|
|
|
|
/// Move a specific vertex to this absolute world position.
|
|
|
|
|
Absolute(Vec3),
|
|
|
|
|
/// Translate the whole object by this delta vector.
|
|
|
|
|
Translate(Vec3),
|
|
|
|
|
}
|