diff --git a/plugins/highway_3d/screen.js b/plugins/highway_3d/screen.js index ae7f8a7..beeaf12 100644 --- a/plugins/highway_3d/screen.js +++ b/plugins/highway_3d/screen.js @@ -1607,14 +1607,13 @@ ss.isCanvasFocused(highwayCanvas)); } - // A/B toggle for the wide-pane horizontal-FOV-hold. Flips - // window.__h3dAspectTune.enabled so the running app can switch between the - // current framing (off, the baseline) and the Hor+ framing (on) with one - // keypress, across all panes at once. Registered once per session via a - // module-level guard (it toggles a shared global, so per-instance - // registration would stack duplicate handlers and cancel itself out); it's - // a harmless debug control, so it is never unregistered. No-ops where the - // core shortcut API isn't present (older core / borrowed contexts). + // Shortcut for the wide-pane framing tuner. Opens/closes the floating panel + // (the A/B on/off and the per-pane target live inside it now). Registered + // once per session via a module-level guard (it drives shared module state, + // so per-instance registration would stack duplicate handlers and cancel + // itself out); it's a harmless debug control, so it is never unregistered. + // No-ops where the core shortcut API isn't present (older core / borrowed + // contexts). let _abShortcutRegistered = false; function _registerAspectAbShortcut() { if (_abShortcutRegistered) return; @@ -1623,17 +1622,13 @@ try { window.registerShortcut({ key: 'A', // uppercase e.key → produced with Shift held (Shift+A) - description: '3D Highway: toggle wide-pane framing A/B (Shift+A)', + description: '3D Highway: open/close wide-pane framing tuner (Shift+A)', scope: 'player', handler: () => { - const t = _aspectTune(); - t.enabled = !t.enabled; - try { console.log('[h3d] wide-pane framing', t.enabled ? 'ON' : 'OFF'); } catch (e) {} - // Surface the live tuner panel whenever the feature is on, - // hide it when off. Built lazily on first use. - _ensureAspectPanel(); - _setAspectPanelVisible(t.enabled); - _syncAspectPanel(); + // Open/close the live tuner panel. The A/B on/off and the + // per-pane target now live in the panel itself, so the + // shortcut is just a dismiss/reveal. + _toggleAspectPanel(); }, }); } catch (e) { @@ -1685,8 +1680,19 @@ let _aspectPanelEl = null; // the floating panel root (built once) let _aspectPanelRO = null; // readout
let _aspectPanelRAF = 0; // readout poll handle + let _aspectTargetSel = null; // the "Target" '); + assert.match(src, /function\s+_aspectRegisterPane\s*\(/, + '_aspectRegisterPane must record live panes for the picker'); + assert.match(src, /_aspectRegisterPane\(\s*_paneKey\s*,/, + 'camUpdate must register its pane each frame'); +}); + +test('the panel has a dismiss (close) control', () => { + assert.match( + src, + /close\.textContent\s*=\s*'×'[\s\S]*?_setAspectPanelVisible\(\s*false\s*\)/, + 'the panel header must have a × button that hides the panel', + ); }); test('camUpdate only writes cam.fov when it actually changes', () => { @@ -153,14 +192,16 @@ test('camUpdate only writes cam.fov when it actually changes', () => { ); }); -// ── A/B toggle + lifecycle reset ────────────────────────────────────────────── +// ── Shortcut (open/close) + lifecycle reset ─────────────────────────────────── -test('an A/B toggle shortcut flips the tune enabled flag', () => { +test('the shortcut opens/closes the tuner panel', () => { assert.match( src, - /registerShortcut\(\{[\s\S]*?const\s+t\s*=\s*_aspectTune\(\)\s*;[\s\S]*?t\.enabled\s*=\s*!\s*t\.enabled/, - 'a registerShortcut handler must toggle the bridge enabled flag', + /registerShortcut\(\{[\s\S]*?_toggleAspectPanel\(\)/, + 'a registerShortcut handler must toggle the tuner panel', ); + assert.match(src, /function\s+_toggleAspectPanel\s*\(\)/, + '_toggleAspectPanel() must exist to reveal/dismiss the panel'); }); test('destroy() resets the pane aspect and restores the base fov', () => {