Files
OneCAD-Draft/src/scene/model/object.rs
T
ramox81andClaude Opus 5.5 4b00504453 Point cloud move gizmo
A lone unlocked point cloud selected in a 3D visual style shows a move
gizmo at its insertion point: X/Y/Z arrows and XY/YZ/ZX squares. Dragging
an arrow moves the cloud along that axis, a square moves it in that
plane; the hovered part is highlighted and each drag is one undo step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:09:00 +03:00

237 lines
8.9 KiB
Rust

// Shared value types used by the dispatch and grip systems.
use codec::types::{Color as AcadColor, Handle, 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),
/// Read-only display text with a tooltip explaining why it cannot be edited.
ReadOnlyWithTooltip { value: String, tooltip: String },
/// Editable numeric field.
EditText(String),
/// Editable text that must not be expression-evaluated.
PlainText(String),
/// Hyperlink collection summary. The value is display-only in the row;
/// the adjacent collection button opens the URL/description editor.
Hyperlink(String),
/// Layer name — rendered as a combo_box.
LayerChoice(String),
/// Generic string choice rendered as a combo_box.
Choice {
selected: String,
options: Vec<String>,
},
/// 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<String> },
/// ACI/RGB/ByLayer/ByBlock color — rendered as a color picker.
ColorChoice(AcadColor),
/// Color-book color with its file-provided display name.
NamedColorChoice { color: AcadColor, name: String },
/// Color varies across the current multi-selection.
ColorVaries,
/// Line weight — rendered as a combo_box.
LwChoice(LineWeight),
/// Object-specific line weight routed by field name.
FieldLwChoice {
field: &'static str,
value: LineWeight,
},
/// Object-specific lineweight varies across the current selection.
FieldLwVaries { field: &'static str },
/// 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 clickable link to one or more entities — the Constraints section's
/// row for one parametric constraint. Clicking it selects every
/// entity in `handles` in the viewport. `conflicting` mirrors
/// `ParametricConstraintSet::conflicts`, tinting the row the same danger
/// color the constraint's glyph pill already uses. `id` routes the row's
/// delete action back to that constraint in the active scope.
EntityLink {
id: crate::scene::parametric_constraints::ConstraintId,
handles: Vec<Handle>,
conflicting: bool,
},
/// One row of the document-wide named-parameter table (Parameters
/// section, shown when nothing is selected). `index` is the row's
/// position in `ParameterTable::iter()` order — stable across edits to
/// other rows, used to route `PropParamInput`/`PropParamCommit`/
/// `PropParamDelete` back to the right parameter without re-keying on a
/// name that might itself be mid-edit. `resolved` is the live value or
/// error, recomputed fresh every render (same "cheap enough to rebuild"
/// approach the old modal's preview column already used).
ParamRow {
index: usize,
name: String,
formula: String,
resolved: Result<f64, String>,
},
/// The trailing "+ Add parameter" row in the Parameters section.
ParamAddRow,
/// The Parameters section's leading header row (no-selection page only):
/// a global on/off toggle for whether any constraint pill in the
/// viewport shows its driven value/parameter-name text. Mirrors
/// `App::show_constraint_values`.
ParamsVisibilityToggle(bool),
}
/// 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,
Circle,
/// Screen-offset menu selector.
Dropdown,
/// Menu selector placed immediately beside its anchor grip.
DropdownAdjacent,
/// Move-gizmo arrow along world X (0), Y (1) or Z (2); the grip's world
/// point is the gizmo centre, the marker sits at the arrow tip.
GizmoAxis(u8),
/// Move-gizmo square between two axes: XY (0), YZ (1) or ZX (2).
GizmoPlane(u8),
}
/// 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-space marker direction, projected with the grip position.
pub dir: Option<glam::DVec3>,
/// World-space axis that constrains this grip's drag.
pub axis: Option<glam::DVec3>,
}
/// 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,
RectangleWidth,
RectangleHeight,
RectangleResize,
MoveParallel,
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,
ShowFit,
ShowControlVertices,
SectionPlane,
SectionSlice,
SectionBoundary,
SectionVolume,
MoveWithText,
StackText,
UnstackText,
}