Keyboard and gestures¶
Status: PROPOSED
The complete planned key set comes from docs/ui/ui-plan.md:292–304.
Only P, Ctrl+L, Left, and Right are implemented today. Every other
binding and the focus-scoped dispatcher are PROPOSED.
Focus-scoping rule¶
PROPOSED — shortcuts dispatch by focused surface before they dispatch by
key. Bare digit and letter keys never fire while a text or numeric input has
focus. Space is playback only when the Simulate viewport has focus.
flowchart TD
K["KeyDown"] --> F{"Focused control?"}
F -->|Text / numeric input| I["Preserve typing and editing"]
F -->|Viewport / chrome| C{"Context"}
C -->|Paint mode| P["Paint bindings"]
C -->|Simulate viewport| S["Playback + viewport bindings"]
C -->|Other stage/chrome| G["Global modified commands"]
This replaces the current flat dispatcher. HOW IT IS —
ShellKeybindings.Handle currently compares exactly four keys with no focus
argument (src/Nps.Shell/Controls/ShellKeybindings.cs:73–113).
Keybindings¶
| Key | Planned action | Scope | Honesty |
|---|---|---|---|
P |
Play / pause | Simulate/playback context; Slicer without a playhead reports unavailable today | HOW IT IS dispatcher key (src/Nps.Shell/Controls/ShellKeybindings.cs:84–89); current Slicer stub at src/SlicerApp/MainWindow.axaml.cs:171–185 |
Ctrl+L |
Toggle inspector | Window | HOW IT IS (src/Nps.Shell/Controls/ShellKeybindings.cs:91–96) |
Left |
Step one move backward | Simulate/playback context | HOW IT IS dispatcher key (src/Nps.Shell/Controls/ShellKeybindings.cs:105–110); Slicer reports unavailable today |
Right |
Step one move forward | Simulate/playback context | HOW IT IS dispatcher key (src/Nps.Shell/Controls/ShellKeybindings.cs:98–103); Slicer reports unavailable today |
Ctrl+1 |
Switch to Prepare | Window | PROPOSED |
Ctrl+2 |
Switch to Preview | Window | PROPOSED |
Ctrl+3 |
Switch to Simulate | Window | PROPOSED |
Ctrl+O |
Open model | Window | PROPOSED |
Ctrl+Shift+O |
Open G-code | Window | PROPOSED |
Ctrl+E |
Open Export | Window; disabled with reason when no generated path | PROPOSED |
Ctrl+Enter |
Slice / Re-slice | Window; disabled with reason when no model | PROPOSED |
[ |
Layer down | Preview / Simulate viewport | PROPOSED |
] |
Layer up | Preview / Simulate viewport | PROPOSED |
T |
Toggle travels | Viewport, not while typing | PROPOSED binding over an existing display toggle |
X |
Toggle extrusions | Viewport, not while typing | PROPOSED binding over an existing display toggle |
G |
Toggle Ghost Compare | Preview / Simulate viewport, not while typing | PROPOSED |
B |
Enter / exit region paint mode | Prepare viewport, not while typing | PROPOSED |
F |
Zoom to Fit | Viewport, not while typing | PROPOSED binding over an existing toolbar action |
0 |
Reset camera | Viewport, not while typing | PROPOSED binding over an existing toolbar action |
? |
Open keybinding cheat sheet | Window when not editing text/numeric input | PROPOSED |
Esc |
Exit paint, close overlay/dialog, or dismiss banner according to active context | Contextual; innermost transient surface first | PROPOSED |
Space |
Play / pause | Only when the Simulate viewport is focused | PROPOSED |
Note
P remains the current playback key. Space is not a second global
binding: it is restricted to the focused Simulate viewport so buttons,
text inputs, and other stages keep normal Space behavior.
Existing toolbar actions, planned keys¶
HOW IT IS — Reset, Isometric, Front, Top, Right, Zoom to Fit,
Travels, Extrusions, Layer Up, and Layer Down already exist as the ten controls
in ViewportToolbar (src/Nps.Shell/Controls/ViewportToolbar.cs:29–38,53–67).
The F, 0, T, X, [, and ] keyboard routes are PROPOSED; they reuse
the same actions rather than introducing different behavior.
The existing camera presets are Reset, Isometric, Front, Top, and Right
(src/Nps.Shell/ViewportController.cs:79–89). No XYZ snap hotkeys are promised.
Viewport gestures¶
| Gesture | Action | Scope | Honesty |
|---|---|---|---|
| Left-button drag | Orbit camera | Viewport, outside paint mode | HOW IT IS — current app handler updates rotation and calls SetCamera (src/SlicerApp/MainWindow.axaml.cs:819–842) |
| Other-button drag | Pan camera | Viewport, outside paint mode | HOW IT IS — same handler updates pan (src/SlicerApp/MainWindow.axaml.cs:833–842) |
| Mouse wheel | Zoom at cursor | Viewport, outside paint mode | PROPOSED — there is no wheel handler today |
| Left-button drag | Paint faces into active region | Viewport while paint mode is active | PROPOSED |
| Shift + left-button drag | Erase faces from active region | Viewport while paint mode is active | PROPOSED |
Esc |
Leave paint mode | Paint context | PROPOSED |
| Click finding marker | Focus the finding, layer, and move | Preview / Simulate | PROPOSED marker interaction over existing finding focus |
| Drag layer-band thumb | Change minimum or maximum visible layer | Preview / Simulate left sidebar | PROPOSED |
| Drag layer band | Move the visible min–max window | Preview / Simulate left sidebar | PROPOSED |
| Press / drag playback scrubber | Pause while scrubbing and preview target move | Simulate | HOW IT IS (src/Nps.Shell/Controls/PlaybackPanel.axaml.cs:326–390,454–484) |
| Release playback scrubber | Commit move; resume only if previously playing | Simulate | HOW IT IS app path (src/SimulatorApp/MainWindow.axaml.cs:868–915) |
Pointer events already travel from the shared shell to each app
(src/Nps.Shell/Controls/MainWindowShell.axaml.cs:35–37,269–290). Wheel zoom and
paint dispatch are PROPOSED additions to that route.
Cheat sheet¶
PROPOSED — ? opens an overlay containing the same table as this page,
grouped by Global, Stage, Viewport, Paint, and Playback. It closes with Esc and
does not change stage or engine state.
The overlay must derive from the same binding definitions used by dispatch; it must not advertise shortcuts that do not exist. In particular, the activity bar does not gain undocumented single-letter overlay keys.
Conflict rules¶
PROPOSED — dispatch follows these priorities:
- Active modal/dialog handles its own commands.
- Paint mode handles paint gestures and
Esc. - A focused text/numeric control keeps bare letters and digits.
- The focused Simulate viewport may handle
Spaceand playback keys. - Stage/viewport shortcuts run only in their declared scope.
- Modified global commands run once and mark the event handled.
- An unmatched key remains available to Avalonia or the focused control.
A key never both types into a field and triggers an action.
See also¶
- Prepare for open/slice actions and empty-state gating.
- Preview for layer, display, ghost, and export actions.
- Simulate for playback behavior.
- Slicer — interaction map for the four current keys and gestures.
- Simulator — interaction map for current playback and scrubber bindings.