Skip to main content

geop_core_editor/editing/
form.rs

1//! [`Form`]: what an operation shows for a step while it is edited, and
2//! [`Event`]: what reaches it of what the user did.
3
4use geop_core_math::{
5    primitives::{CoordinateSystem, Pose},
6    scalars::Scalar,
7    vector::Vector3,
8};
9
10use super::{CanvasEvent, Dialog, Extent, Gizmo, Layout, Prompt, Value, Visual};
11
12/// What an operation has in hand while a step is edited (see
13/// [`Form::tool`]).
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
15pub enum InHand {
16    /// Nothing: a click selects, and a draggable visual is dragged.
17    #[default]
18    Nothing,
19    /// A tool that clicks — drawing a line, say: clicks go to it rather
20    /// than select, and draggable visuals are not dragged.
21    Clicks,
22    /// A tool that also strokes — trimming, say: besides its clicks, a
23    /// press anywhere grabs, and the drag goes to it as a
24    /// [`CanvasEvent::Stroke`].
25    Strokes,
26}
27
28/// What a step asks of the state while it is edited, for the editor to
29/// solve the program with: an operation never sets the state itself, it
30/// says where it wants it pulled, and the constraints have the last word.
31#[derive(Clone, Debug, PartialEq)]
32pub enum Pull {
33    /// The point `local` of a placed part — in its own frame — pulled
34    /// towards the point `target`: a drag. The part is named by the state
35    /// its pose is.
36    Point {
37        parameter: String,
38        local: Vector3,
39        target: Vector3,
40    },
41    /// A placed part pulled to the pose `target` as a whole: placed where
42    /// it was typed in, turned by a gizmo.
43    Pose { parameter: String, target: Pose },
44    /// The number the state `parameter` is, set to `value` and held there:
45    /// a joint's coordinate typed in, which the parts move to.
46    Value { parameter: String, value: Scalar },
47}
48
49/// What an operation shows for a step: the fields of its dialog and what
50/// it draws, and what the editor needs to know to edit it the same way as
51/// every other step — what is selected, what the operation has in hand,
52/// what it drags. Plain data: what a field does when it is set is the
53/// operation's to say when it is sent the [`Event`].
54#[derive(Clone, Debug, PartialEq)]
55pub struct Form {
56    pub dialog: Dialog,
57    /// Where the dialog is shown: beside the viewport, or as a popup over
58    /// it (see [`Layout`]).
59    pub layout: Layout,
60    pub visuals: Vec<Visual>,
61    /// A plane to work in, its `u`/`v` plane: the viewer faces it head on,
62    /// stops orbiting, and draws a grid on it. Draggable visuals are
63    /// dragged in it.
64    pub focus: Option<CoordinateSystem>,
65    /// A sheet of its own the step is edited on — a drawing's paper, laid
66    /// in `focus` — and how far it reaches: the viewer shows the step's
67    /// visuals alone, without the part, framed to it.
68    pub sheet: Option<Extent>,
69    /// What the operation has in hand: clicks — and, for a tool that
70    /// strokes, drags — go to it rather than select.
71    pub tool: InHand,
72    /// The keys of the visuals selected. A click on a selectable visual
73    /// changes it, and the operation is sent the new selection
74    /// ([`Event::Select`]) to keep.
75    pub selection: Vec<String>,
76    /// Whether a drag from nothing, with nothing in hand, draws a box that
77    /// selects: the operation is sent it ([`CanvasEvent::SelectBox`]) and
78    /// decides what lies in it, from what its visuals stand for.
79    pub select_box: bool,
80    /// What the step pulls the state towards: the editor solves the
81    /// program with them.
82    pub pulls: Vec<Pull>,
83    /// A value asked for in place, in the viewport.
84    pub prompt: Option<Prompt>,
85    /// A gizmo to move, turn or scale something by: its drags are sent as
86    /// [`CanvasEvent::Gizmo`].
87    pub gizmo: Option<Gizmo>,
88    /// Solids and faces of the part, by name, not to draw while the step
89    /// is edited: what the step builds, when its visuals show it better —
90    /// a control cage shown alone.
91    pub hidden: Vec<String>,
92}
93
94impl Default for Form {
95    fn default() -> Self {
96        Self {
97            dialog: Dialog::new(),
98            layout: Layout::default(),
99            visuals: Vec::new(),
100            focus: None,
101            sheet: None,
102            tool: InHand::Nothing,
103            selection: Vec::new(),
104            select_box: false,
105            pulls: Vec::new(),
106            prompt: None,
107            gizmo: None,
108            hidden: Vec::new(),
109        }
110    }
111}
112
113/// What reaches an operation of what the user did, once the editor has
114/// done what it does alike for every operation: arming a reference field
115/// and picking for it, dragging a number's handle, selecting.
116#[derive(Clone, Debug, PartialEq)]
117#[allow(
118    clippy::large_enum_variant,
119    reason = "an event is made once and read once; a stroke carries its points"
120)]
121pub enum Event {
122    /// The field `key` of the dialog set to `value` — typed, chosen, picked
123    /// for in the viewport or dragged by its handle.
124    Field { key: String, value: Value },
125    /// The visuals selected now, by their keys.
126    Select(Vec<String>),
127    /// What the pointer or a key did beyond that.
128    Canvas(CanvasEvent),
129}