Add Touchpad navigation: Shift to pan, Alt/Option to orbit (#1220)

An opt-in Touchpad navigation preset: Shift + pointer motion pans, Alt/Option + motion orbits, vertical scroll zooms, all without a mouse button. Existing presets are unchanged; view.navigate gains continuous motion for the control channel and scenarios.
This commit is contained in:
Emil Petersson authored and GitHub committed 2026-10-14 22:46:33 -04:00
1 parent b4edf05373
commit bd8db8ea1c
17 files changed
+717 -60

No files matched your search

+5
View File
@@ -42,3 +42,8 @@ Mouse and touch:
| Double-click the middle button | go Home: the home view, framing everything shown (Preferences › Navigation › Middle double-click: Home, Fit or Off) |
Help › Keyboard Shortcuts in the app lists the current bindings, including any you changed.
With the **Touchpad** navigation preset, hold **Shift** while moving the pointer to pan, or
**Alt/Option** to orbit, without pressing a mouse button. Vertical scrolling zooms. These
viewport gestures are separate from rebindable command shortcuts; mouse-button selection
and editing keep their existing modifiers.
+7 -1
View File
@@ -23,13 +23,19 @@
Esc or a click elsewhere closes the list. Clicking again on the same spot, with nothing changed
in between, selects the next thing in that list. The
wheel zooms at the cursor, the middle button pans and right-drag orbits freely (the mouse
< preset in Preferences switches to SolidWorks, Inventor, Alias or Tinkercad style). On a
preset in Preferences switches to SolidWorks, Inventor, Alias, Tinkercad, OpenSCAD or Touchpad style). On a
trackpad, pinch zooms and two-finger scroll pans (Navigation › Two-finger scroll pans;
off: scroll zooms like the wheel); mouse wheels zoom and the thumb wheel pans sideways.
Shift+middle orbits freely
in the default and Inventor presets. In every preset, Ctrl+left drag (Cmd on macOS) that starts
on empty space orbits; a Ctrl+click still adds to the selection. Shift+right-drag snaps to the nearest standard or
diagonal view; Shift does not request snapping when the preset already requires it to orbit.
With **Touchpad** selected in Preferences › Navigation, hold **Shift** and move the pointer to
pan, or hold **Alt** (**Option** on macOS) and move it to orbit—no mouse button is needed.
Vertical two-finger scrolling zooms in this preset, regardless of the saved two-finger pan
setting; switching presets restores that setting. Release the modifier to stop navigating.
Shift+click and Shift+left-drag still select. Combined Shift+Alt or Ctrl/Cmd modifiers do not
start pointer-only navigation.
The axis view shows the world's X/Y/Z directions in SolidCraft's colors. Click a signed
axis tip to look along that axis; click the aligned tip again to look from the opposite side.
Drag the axis view to orbit around the view centre, with Shift for snapping. Top and bottom
+12 -2
View File
@@ -106,7 +106,7 @@ unit regardless of the design, pass an expression with one: `"value": "50 mm"` o
| `ui.view` | `view`: `front`, `back`, `top`, `bottom`, `left`, `right`, `iso`, `home`, `fit`; `animate` (bool, default false: snap) | |
| `ui.start` | `command` | like a toolbar click: starts the sketch tool or dialog for the command |
| `ui.click` | `x`, `y` (screen points), `button?`: left/right/middle, `shift?`, `ctrl?`, `double?` | real pointer input |
| `ui.move` | `x`, `y` | |
| `ui.move` | `x`, `y`, `shift?`, `alt?`, `ctrl?`, `cmd?` | pointer movement without a button; modifiers apply until the next synthetic move/click; a move with omitted modifiers releases them. With `nav: "touchpad"`, Shift pans and Alt/Option orbits. |
| `ui.drag` | `x0`, `y0`, `x1`, `y1`, `button?`, `shift?`, `ctrl?`, `steps?`, `hold?`, `hold_end?` | press, move, release; a left drag on the model is a box selection (left to right: window, right to left: crossing); with OpenSCAD navigation, plain left-drag on empty space orbits, Shift+left-drag box-selects, and drags starting on sketch geometry edit it; `hold` keeps the button down that many frames first (a right press-and-hold opens the marking menu, releasing over a direction picks it), `hold_end` that many frames at the end (a sketch drag shows its snap) |
| `ui.menu` | `x?`, `y?`, `target?`, `close?` | with a point: open a context menu there as a right-click would (the viewport's marking menu, or a browser menu with `target: {"type": "body", "name"} \| {"type": "sketch", "id"} \| {"type": "component", "id"}`); without: the open menu (`radial` and `items`: id, label, shortcut, enabled) |
| `ui.menuPick` | `item`: id or label | runs an item of the open menu, as clicking it does |
@@ -131,7 +131,7 @@ unit regardless of the design, pass an expression with one: `"value": "50 mm"` o
| `ui.home` | `open?`: bool; `sample?`: index | the start page: show or hide it, open a built-in sample (once built); returns `open` and the recent designs |
| `ui.shortcut` | `command`, `key?`, `replace?` | a command's key, or rebinds it (`""` clears; a key another command uses is refused unless `replace`) |
| `ui.help` | `item?`: `about`, `shortcuts` (read only), `report` (opens a report draft for review), `crashes` (the Crash Reports window) | the version, commit, build date and diagnostic text |
| `ui.prefs` | any of `default_units`, `nav` (`fusion`, `solidworks`, `inventor`, `alias`, `tinkercad`, `openscad`), `zoom_reverse`, `zoom_to_cursor`, `smooth_wheel_zoom` (default true), `trackpad_pan` (default true: two-finger scroll pans, pinch zooms), `orbit_cursor`, `look_at_anim`, `look_at_speed`, `middle_double_click` (`home` (default), `fit`, `off`), `msaa`, `length_decimals`, `angle_decimals`, `theme` (`dark`, `light`, `system`), `language` (`en`, `ja`, `de`, `fr`, `ko`, `ru`, `uk`, `zh`; see [localization](localization.md)), `ui_scale`, `up_axis` (`z`, `y`), `offer_stand_up`, `color_vision` (`off` (default), `protan`, `deutan`, `tritan`: colour vision modes, #778), `check_updates` (default true; [updates](book/src/guide/updates.md)); `open` (a page: General, Navigation, Keyboard Shortcuts, Design, Graphics, Sketch, Selection) opens the Preferences dialog there; `button`: `ok`, `cancel`, `apply`, `defaults`; `stand_up: true` stands up a just-opened Y-up file | sets preferences (kept between runs), returns them all plus `dialog` (the open page or null), `dark` and `stand_up_offer` |
| `ui.prefs` | any of `default_units`, `nav` (`fusion`, `solidworks`, `inventor`, `alias`, `tinkercad`, `openscad`, `touchpad`), `zoom_reverse`, `zoom_to_cursor`, `smooth_wheel_zoom` (default true), `trackpad_pan` (default true: two-finger scroll pans, except Touchpad always zooms; pinch zooms), `orbit_cursor`, `look_at_anim`, `look_at_speed`, `middle_double_click` (`home` (default), `fit`, `off`), `msaa`, `length_decimals`, `angle_decimals`, `theme` (`dark`, `light`, `system`), `language` (`en`, `ja`, `de`, `fr`, `ko`, `ru`, `uk`, `zh`; see [localization](localization.md)), `ui_scale`, `up_axis` (`z`, `y`), `offer_stand_up`, `color_vision` (`off` (default), `protan`, `deutan`, `tritan`: colour vision modes, #778), `check_updates` (default true; [updates](book/src/guide/updates.md)); `open` (a page: General, Navigation, Keyboard Shortcuts, Design, Graphics, Sketch, Selection) opens the Preferences dialog there; `button`: `ok`, `cancel`, `apply`, `defaults`; `stand_up: true` stands up a just-opened Y-up file | sets preferences (kept between runs), returns them all plus `dialog` (the open page or null), `dark` and `stand_up_offer` |
| `ui.capture` | `action?`: `capture`, `revert`, `cancel` | answers the Capture Position question (asked when a command starts or the design is saved while components were moved without capturing); without `action`, what waits |
| `ui.window` | `action`: minimize, maximize, restore, toggle, close | what the title bar's caption buttons do (on Windows and Linux the application bar is the title bar); close asks about unsaved designs first |
| `ui.agent_cursor` | `show` (bool), `speed`: a number from 1 to 5 (times the normal speed) or `"instant"` (no animation: the command runs at once and the pointer jumps to where it acted), `follow_camera` (bool); all optional | the settings. While the cursor is shown, `engine.execute` first glides to the command's toolbar button and to each pick, then runs and replies; later requests wait their turn. `"animate": false` on a call skips it |
@@ -142,6 +142,16 @@ unit regardless of the design, pass an expression with one: `"value": "50 mm"` o
Entering Render requires finishing the current modelling operation; returning restores
the Design camera. See [the integrated Render workspace](render-workspace.md).
### Continuous camera motion
Continuous camera motion is also available through `engine.execute` with command
`view.navigate`: pass `camera` (from `ui.inspect`) and `motion: "pan" | "orbit" | "zoom"`.
Pan and orbit take `delta: [dx,dy]` in screen points (each within ±10000); pan also requires
`viewport: [width,height]` (each 1..1000000). Orbit accepts a world-space `pivot` with the
viewport size. Zoom takes `factor` (0.05..20, below 1 zooms in) and an optional world-space
`anchor`. The returned `camera` is applied immediately by the UI, without animation,
document edits, undo steps or a success-log entry per movement.
## MCP
`solidcraft-cli mcp --connect 127.0.0.1:PORT` bridges an MCP client (an AI agent) to this