From 500ebd7fb771302aa04d3ba96ff5f31288827273 Mon Sep 17 00:00:00 2001 From: Mathias Malmqvist Date: Tue, 28 Oct 2025 02:24:53 +0100 Subject: [PATCH] Allow finetuning with the keyboard arrows --- css/main.css | 1 + js/modals/finetune-modal.js | 57 ++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/css/main.css b/css/main.css index b240395..0e42965 100644 --- a/css/main.css +++ b/css/main.css @@ -15,6 +15,7 @@ dl.row dd { #left-stick-card, #right-stick-card { cursor: pointer; + outline: none !important; } .stick-card-active { diff --git a/js/modals/finetune-modal.js b/js/modals/finetune-modal.js index 39710cd..810690b 100644 --- a/js/modals/finetune-modal.js +++ b/js/modals/finetune-modal.js @@ -208,6 +208,7 @@ export class Finetune { this._initSliderListeners(lOrR); this._initButtonListeners(lOrR); + this._initKeyboardListeners(lOrR); }); } @@ -250,6 +251,24 @@ export class Finetune { }); } + /** + * Initialize keyboard event listeners for a specific stick card + */ + _initKeyboardListeners(lOrR) { + const stickCard = $(`#${lOrR}-stick-card`); + + stickCard.on('keydown', (e) => { + this._onKeyboardEvent(e, true); + }); + + stickCard.on('keyup', (e) => { + this._onKeyboardEvent(e, false); + }); + + // Make stick cards focusable + stickCard.attr('tabindex', '0'); + } + /** * Clean up event listeners for the finetune modal */ @@ -274,7 +293,7 @@ export class Finetune { _removeStickEventListeners() { LEFT_AND_RIGHT.forEach(lOrR => { // Remove stick card listeners - $(`#${lOrR}-stick-card`).off('click'); + $(`#${lOrR}-stick-card`).off('click keydown keyup'); // Remove slider listeners const sliderId = `#${lOrR}CircularitySlider`; @@ -343,6 +362,42 @@ export class Finetune { } } + /** + * Handle keyboard events for arrow key adjustments + * Arrow keys work like D-pad buttons for fine-tuning + */ + _onKeyboardEvent(event, isKeyDown) { + const key = event.key; + + // Map arrow keys to button names (D-pad) + const keyToButtonMap = { + 'ArrowLeft': 'left', + 'ArrowRight': 'right', + 'ArrowUp': 'up', + 'ArrowDown': 'down' + }; + + const button = keyToButtonMap[key]; + if (!button) return; + + event.preventDefault(); + + // Arrow keys work as D-pad buttons for adjustments + if (!this.active_stick) return; + + const changes = {}; + + if (isKeyDown) { + // Simulate button press by creating a change object + changes[button] = true; + this.handleDpadAdjustment(changes); + } else { + // Simulate button release + changes[button] = false; + this.handleDpadAdjustment(changes); + } + } + /* Set the quick calibrating state to prevent dialog destruction * @param {boolean} isCalibrating - Whether quick calibration is in progress */