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}