This is a finite state machine with various states and transitions, see the diagram below for an example. Each transition also represents a "hint" that shows up in the status bar footer.
It is important to think of the tool menu as, conceptually, a mode selector for the behavior of editing within the viewport. You perform operations on the viewport using your mouse and keyboard, and those operations change the node graph for you. Depending on which mode you're in, different operations are applied. That mode is chosen by selecting the active tool in the toolbar, or you could think of it as the "tool mode" in the "tool mode selector bar".
Each of these "modes" will be given its own FSM definition designed to model the exact behavior for the user experience of the tool.
The state machines will probably be pretty gnarly, it is way easier to work with them in a format resembling the Nomnoml diagram code (see below) than it is to figure out all that in Rust code. So the FSM for each tool will be defined as a text file. This probably makes extensions easier to support in the future also. We will need to design a format grammar and write a parser to construct the internal FSM data structure, which is implemented as:
- Each tool has a HashMap to store all the
ToolState
s (orange and gold states in the graph).
- A
ToolState
stores: name: String; isIntermediate: boolean; transitions: Vec<Transition>; action: a closure or a string name to look up the closure in a HashMap;
- A
Transition
stores: condition: TransitionCondition; destination: string
(each Transition
is owned by its outgoing state within the Vec
)
- The "destination" string is the name of another
ToolState
. A TransitionCondition
is an enum with all the possible input events and stateful details about the tool options, editor, and document (examples: mouse move event, mouse button down and up event for each mouse button, key down and up events for every key), plus ε
(an instant, automatic transition). Perhaps we need a concept of event (which gets triggered) and a persistent condition (like a tool setting or some stateful characteristic about the document or editor). Or instead, perhaps transitions are only inputs or ε
, but they can be gated by persistent conditions. The array of TransitionCondition
s will probably set the precedence.
- The state machine is hard coded to begin with the
Ready
state. There is no end state, the machine never halts.
Example subset of the FSM for the Select tool:
Nomnoml diagram link
Orange is a main state that shows up in the footer of the Graphite editor as an input hint. Yellow/gold is a "intermediate" state that doesn't show up in the footer, but instead the result of the state it leads to shows up. (You can get to Transform Selected through a LMB Down combined with a MouseMove, for example.)