diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f5d08389e1573ecdc83f6612e6f5776dff80d41..b880389397ad2b8dea2402c3b4a1670d05f69f3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,10 @@ Note that since we don't clearly distinguish between a public and private interf ## [Unreleased] - Avoid `renderMarkingDepth` for fully transparent renderables -- Remove `camera.far` doubeling workaround +- Remove `camera.far` doubling workaround - Add `ModifiersKeys.areNone` helper function - Add "Zoom All", "Orient Axes", "Reset Axes" buttons to the "Reset Camera" button +- Improve trackball move-state handling when key bindings use modifiers ## [v3.33.0] - 2023-04-02 diff --git a/src/mol-canvas3d/controls/trackball.ts b/src/mol-canvas3d/controls/trackball.ts index 08647f650748495102273cf365518354ff0ea358..a3f02d4a3a16cc4020c4ed3e4f4202e0f5eb83bf 100644 --- a/src/mol-canvas3d/controls/trackball.ts +++ b/src/mol-canvas3d/controls/trackball.ts @@ -45,10 +45,10 @@ export const DefaultTrackballBindings = { keyMoveDown: Binding([Key('KeyF')], 'Move down', 'Press ${triggers}'), keyRollLeft: Binding([Key('KeyQ')], 'Roll left', 'Press ${triggers}'), keyRollRight: Binding([Key('KeyE')], 'Roll right', 'Press ${triggers}'), - keyPitchUp: Binding([Key('ArrowUp')], 'Pitch up', 'Press ${triggers}'), - keyPitchDown: Binding([Key('ArrowDown')], 'Pitch down', 'Press ${triggers}'), - keyYawLeft: Binding([Key('ArrowLeft')], 'Yaw left', 'Press ${triggers}'), - keyYawRight: Binding([Key('ArrowRight')], 'Yaw right', 'Press ${triggers}'), + keyPitchUp: Binding([Key('ArrowUp', M.create({ shift: true }))], 'Pitch up', 'Press ${triggers}'), + keyPitchDown: Binding([Key('ArrowDown', M.create({ shift: true }))], 'Pitch down', 'Press ${triggers}'), + keyYawLeft: Binding([Key('ArrowLeft', M.create({ shift: true }))], 'Yaw left', 'Press ${triggers}'), + keyYawRight: Binding([Key('ArrowRight', M.create({ shift: true }))], 'Yaw right', 'Press ${triggers}'), boostMove: Binding([Key('ShiftLeft')], 'Boost move', 'Press ${triggers}'), enablePointerLock: Binding([Key('Space', M.create({ control: true }))], 'Enable pointer lock', 'Press ${triggers}'), @@ -679,30 +679,67 @@ namespace TrackballControls { function onKeyUp({ modifiers, code, x, y }: KeyInput) { if (outsideViewport(x, y)) return; - if (Binding.matchKey(b.keyMoveForward, code, modifiers)) { - keyState.moveForward = 0; - } else if (Binding.matchKey(b.keyMoveBack, code, modifiers)) { - keyState.moveBack = 0; - } else if (Binding.matchKey(b.keyMoveLeft, code, modifiers)) { - keyState.moveLeft = 0; - } else if (Binding.matchKey(b.keyMoveRight, code, modifiers)) { - keyState.moveRight = 0; - } else if (Binding.matchKey(b.keyMoveUp, code, modifiers)) { - keyState.moveUp = 0; - } else if (Binding.matchKey(b.keyMoveDown, code, modifiers)) { - keyState.moveDown = 0; - } else if (Binding.matchKey(b.keyRollLeft, code, modifiers)) { - keyState.rollLeft = 0; - } else if (Binding.matchKey(b.keyRollRight, code, modifiers)) { - keyState.rollRight = 0; - } else if (Binding.matchKey(b.keyPitchUp, code, modifiers)) { - keyState.pitchUp = 0; - } else if (Binding.matchKey(b.keyPitchDown, code, modifiers)) { - keyState.pitchDown = 0; - } else if (Binding.matchKey(b.keyYawLeft, code, modifiers)) { - keyState.yawLeft = 0; - } else if (Binding.matchKey(b.keyYawRight, code, modifiers)) { - keyState.yawRight = 0; + let isModifierCode = false; + + if (code.startsWith('Alt')) { + isModifierCode = true; + modifiers.alt = true; + } else if (code.startsWith('Shift')) { + isModifierCode = true; + modifiers.shift = true; + } else if (code.startsWith('Control')) { + isModifierCode = true; + modifiers.control = true; + } else if (code.startsWith('Meta')) { + isModifierCode = true; + modifiers.meta = true; + } + + const codes = []; + + if (isModifierCode) { + if (keyState.moveForward) codes.push(b.keyMoveForward.triggers[0]?.code || ''); + if (keyState.moveBack) codes.push(b.keyMoveBack.triggers[0]?.code || ''); + if (keyState.moveLeft) codes.push(b.keyMoveLeft.triggers[0]?.code || ''); + if (keyState.moveRight) codes.push(b.keyMoveRight.triggers[0]?.code || ''); + if (keyState.moveUp) codes.push(b.keyMoveUp.triggers[0]?.code || ''); + if (keyState.moveDown) codes.push(b.keyMoveDown.triggers[0]?.code || ''); + if (keyState.rollLeft) codes.push(b.keyRollLeft.triggers[0]?.code || ''); + if (keyState.rollRight) codes.push(b.keyRollRight.triggers[0]?.code || ''); + if (keyState.pitchUp) codes.push(b.keyPitchUp.triggers[0]?.code || ''); + if (keyState.pitchDown) codes.push(b.keyPitchDown.triggers[0]?.code || ''); + if (keyState.yawLeft) codes.push(b.keyYawLeft.triggers[0]?.code || ''); + if (keyState.yawRight) codes.push(b.keyYawRight.triggers[0]?.code || ''); + } else { + codes.push(code); + } + + for (const code of codes) { + if (Binding.matchKey(b.keyMoveForward, code, modifiers)) { + keyState.moveForward = 0; + } else if (Binding.matchKey(b.keyMoveBack, code, modifiers)) { + keyState.moveBack = 0; + } else if (Binding.matchKey(b.keyMoveLeft, code, modifiers)) { + keyState.moveLeft = 0; + } else if (Binding.matchKey(b.keyMoveRight, code, modifiers)) { + keyState.moveRight = 0; + } else if (Binding.matchKey(b.keyMoveUp, code, modifiers)) { + keyState.moveUp = 0; + } else if (Binding.matchKey(b.keyMoveDown, code, modifiers)) { + keyState.moveDown = 0; + } else if (Binding.matchKey(b.keyRollLeft, code, modifiers)) { + keyState.rollLeft = 0; + } else if (Binding.matchKey(b.keyRollRight, code, modifiers)) { + keyState.rollRight = 0; + } else if (Binding.matchKey(b.keyPitchUp, code, modifiers)) { + keyState.pitchUp = 0; + } else if (Binding.matchKey(b.keyPitchDown, code, modifiers)) { + keyState.pitchDown = 0; + } else if (Binding.matchKey(b.keyYawLeft, code, modifiers)) { + keyState.yawLeft = 0; + } else if (Binding.matchKey(b.keyYawRight, code, modifiers)) { + keyState.yawRight = 0; + } } if (Binding.matchKey(b.boostMove, code, modifiers)) { @@ -742,7 +779,7 @@ namespace TrackballControls { } } - function onLeave() { + function unsetKeyState() { keyState.moveForward = 0; keyState.moveBack = 0; keyState.moveLeft = 0; @@ -758,6 +795,10 @@ namespace TrackballControls { keyState.boostMove = 0; } + function onLeave() { + unsetKeyState(); + } + function dispose() { if (disposed) return; disposed = true;