Keybind settings: New menu and revamped keybind support#1699
Open
tanish2k09 wants to merge 12 commits into
Open
Keybind settings: New menu and revamped keybind support#1699tanish2k09 wants to merge 12 commits into
tanish2k09 wants to merge 12 commits into
Conversation
New shared lib for unified, customizable keyboard shortcuts: - Action registry (3D PageScene actions to start), Binding by physical event.code, KeyGroup/Surface taxonomy. - Presets: Gamer (current WASD/QE default == BASE) + Blender-like (3D deltas). - Zustand+persist store: preset selection, per-action overrides with override→preset→base resolution, conflict detection, reset levels. - Matcher (ctrl/meta interchangeable, capture, shared editable-element guard), platform-aware formatter, useResolvedKeybinds/useKeybindCapture hooks, <Kbd> and <KeybindCaptureInput> primitives. - 13 unit tests (resolution, overrides, reset, conflicts, matcher) passing. No consumers wired yet. Also picks up nx-sync reference normalization.
keymap.ts now maps action ids → handlers and resolves key bindings from @storyteller/keybinds (buildKeymap(forAction), defaulting to the store). cameraMath's WASD/QE/arrow switches become resolved code→slot maps; useFreeCam and useViewportKeyboard subscribe via useResolvedKeybinds so changing the preset or an override re-binds live. Under the default Gamer preset the bindings are byte-for-byte the previous hardcoded set (no behavior change).
Shared <KeybindsSettings> (dependency-free) renders preset cards (Gamer / Blender-like), a searchable grouped action list with click-to-record rebinding, per-row + global reset, and same-surface conflict detection with a "rebind anyway" confirm. Wired into the desktop settings-modal (new Keybinds section) and the webapp SettingsModal (new Keybinds tab). Video editor shortcuts are noted as managed in their own dialog. Persists via the keybinds store.
…(3D) New remappable PageScene actions wired through the registry/presets: - Duplicate selected (Ctrl+D gamer / Shift+D blender) — editor.duplicateSelected. - Deselect all (Ctrl+Alt+A gamer / Alt+A blender). - Toggle grid (H) and toggle grid-snapping (N) — GizmoController.setSnapping makes the previously always-on snap switchable. - useFreeCam now ignores Ctrl/Cmd chords so command shortcuts (e.g. Ctrl+D) don't also strafe the camera. Select-all and frame-all are intentionally deferred (need deeper selection/ bbox-fit engine work) and are not registered yet.
Generalizes the moodboard's hold-Ctrl/Cmd cheatsheet into @storyteller/keybinds (useCheatsheetVisibility + <Cheatsheet surface=…>), rendered from the action registry and resolved live (reflects the active preset/overrides). Mounted on the 3D PageScene, which previously had no quick cheatsheet. Camera actions are marked cheatsheet-important so the WASD/QE scheme is discoverable.
Registers PageDraw undo/redo/copy/paste/delete in the keybinds registry and replaces the three ad-hoc hotkey hooks with a single usePagedrawKeybinds that resolves via matchAction (so Settings → Keybinds can rebind them). Mounts the shared hold-Ctrl cheatsheet on the 2D editor. Moodboard already ships its own complete cheatsheet/shortcuts and is left as a follow-up for full migration.
Registers moodboard tools/selection/group/delete/fit/undo-redo as remappable actions and consolidates the previous three hardcoded hooks (useKeyboardShortcuts, useUndoRedo, and the inline delete/escape handler) into one useMoodboardKeybinds driven by matchAction. Swaps the bespoke ShortcutCheatsheet for the shared registry-fed <Cheatsheet surface="moodboard">. Pan/zoom gestures and clipboard paste are unchanged. Removes the four superseded files (shortcuts.ts stays — the toolbar still uses its fmtShortcut helper).
New ModalTransformController: in the Blender preset, press G to grab the selection and move it with the mouse on a camera-facing plane; press X/Y/Z to constrain to a world axis (Shift+axis to exclude it), left-click/Enter to confirm (records one undoable TransformAction), Esc/right-click to cancel (restores the start). A modalTransformActive store flag makes free-cam and the normal keymap stand down while it's active; the gizmo detaches and re-attaches. Adds the `pagescene.transform.grab` action (G in Blender, unbound in Gamer); Blender's G no longer doubles as a gizmo-mode toggle (translate-mode stays on T). v1 covers translate; rotate/scale modal can follow.
The @storyteller/keybinds lib was never symlinked into node_modules (npm install hadn't been run after it landed), so Vite, TypeScript, and nx all failed to resolve the import. Running install registers it in the lockfile and pulls in the nx-sync TS project references. In the blender preset, camera-back (S) collided with scale (S). Move the blender camera off WASD/QE onto the numpad plus the top-row digits as a laptop-friendly mirror, freeing the letters for G/R/S/T transform ops. Look stays on the arrow keys. Add a preset-integrity test that fails on any same-surface binding clash (guards this whole class of bug across every preset), and fix a stale test that still encoded the pre-"grab" blender design.
… clearer layering Premium pass over the Settings → Keybinds section: - Search gains a Name | Key mode toggle. Name filters by label/group; Key arms a live listener (you press the actual shortcut, e.g. ⇧D) and filters to the actions bound to that combo — glyphs you can't type are no longer a problem. Backed by useKeybindCapture + bindingsEqual. - The free-text name matcher moves to settings/search.ts (pure, unit-tested): matches names, groups, and every binding rendering/synonym (ctrl/cmd, esc, arrows, numpad+digit mirror). - Collapsible per-surface accordions (3D / 2D / Moodboard) with grouped subsections, match counts, expand/collapse-all, and a grid-rows height reveal on a shared spring curve. Search auto-expands matched surfaces. - Preset selector becomes a styled dropdown (listbox) instead of cards. - Override-vs-preset layering made legible: an explainer line plus, on each overridden row, the dimmed preset default → revert ↺ → the accented live override. KeybindCaptureInput gains an `accent` prop for the override tint. Dependency-free (thin-line inline icons, no icon package). 27 unit tests pass.
✅ Deploy Preview for artcraft-webapp ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for storyteller-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for artcraft-website ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for artcraft-dashboard ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
bflatastic
approved these changes
Jun 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.