Better jog comments, use pointer events for robustness

This commit is contained in:
Julian Stirling 2026-02-13 10:36:13 +00:00
parent d9ba5d906d
commit 8478194e30
2 changed files with 59 additions and 20 deletions

View file

@ -243,7 +243,9 @@ export default {
eventBus.emit("globalTogglePreview", false); eventBus.emit("globalTogglePreview", false);
}, },
// Handle global mouse wheel events to be associated with navigation /**
* Handle global mouse wheel events to be associated with navigation
*/
wheelMonitor: function (event) { wheelMonitor: function (event) {
// Only capture scroll if the event target's parent contains the "scrollTarget" class // Only capture scroll if the event target's parent contains the "scrollTarget" class
if ( if (
@ -261,6 +263,13 @@ export default {
} }
}, },
/**
* Jog for key-presses.
*
* This is a similar to the function in stageControlButtons.vue however it uses
* uses the key repeat to fire in case a key up is missed. It debounes any
* request to jog that is too recent after the last jog.
*/
jog(x, y, z) { jog(x, y, z) {
// Manually debounce extra requests from keyboard repeat rate. // Manually debounce extra requests from keyboard repeat rate.
// This is used rather than and interval in case of missing a repeat. // This is used rather than and interval in case of missing a repeat.
@ -279,6 +288,13 @@ export default {
eventBus.emit("globalUpdatePositionEvent"); eventBus.emit("globalUpdatePositionEvent");
}, },
/**
* Stop jogging on key-up
*
* This is also similar to the function in stageControlButtons.vue. It handles
* stopping jogging and resetting the `lastJogTime` so there is no delay when
* starting a new jog after an old jog finished.
*/
jogStop() { jogStop() {
this.invokeAction("stage", "jog", { stop: true }); this.invokeAction("stage", "jog", { stop: true });
this.lastJogTime = 0; this.lastJogTime = 0;
@ -287,6 +303,9 @@ export default {
}, 100); }, 100);
}, },
/**
* Track which keys are still down on keypress (or key repeat).
*/
updateJogFromKeys() { updateJogFromKeys() {
let x = 0, let x = 0,
y = 0, y = 0,

View file

@ -12,9 +12,9 @@
v-if="showDpad" v-if="showDpad"
id="up-button" id="up-button"
class="uk-button uk-button-primary dpad-btn" class="uk-button uk-button-primary dpad-btn"
@mousedown.left="jog(0, 1, 0)" @pointerdown="jog($event, 0, 1, 0)"
@mouseup="jogStop()" @pointerup="jogStop()"
@mouseOut="jogStop()" @mouseLeave="jogStop()"
> >
<span class="material-symbols-outlined sync-icon"> arrow_upward </span> <span class="material-symbols-outlined sync-icon"> arrow_upward </span>
</button> </button>
@ -23,9 +23,9 @@
v-if="showDpad" v-if="showDpad"
id="left-button" id="left-button"
class="uk-button uk-button-primary dpad-btn" class="uk-button uk-button-primary dpad-btn"
@mousedown.left="jog(-1, 0, 0)" @pointerdown="jog($event, -1, 0, 0)"
@mouseup="jogStop()" @pointerup="jogStop()"
@mouseOut="jogStop()" @pointercancel="jogStop()"
> >
<span class="material-symbols-outlined sync-icon"> arrow_back </span> <span class="material-symbols-outlined sync-icon"> arrow_back </span>
</button> </button>
@ -34,9 +34,9 @@
v-if="showDpad" v-if="showDpad"
id="right-button" id="right-button"
class="uk-button uk-button-primary dpad-btn" class="uk-button uk-button-primary dpad-btn"
@mousedown.left="jog(1, 0, 0)" @pointerdown="jog($event, 1, 0, 0)"
@mouseup="jogStop()" @pointerup="jogStop()"
@mouseOut="jogStop()" @pointercancel="jogStop()"
> >
<span class="material-symbols-outlined sync-icon"> arrow_forward </span> <span class="material-symbols-outlined sync-icon"> arrow_forward </span>
</button> </button>
@ -45,9 +45,9 @@
v-if="showDpad" v-if="showDpad"
id="down-button" id="down-button"
class="uk-button uk-button-primary dpad-btn" class="uk-button uk-button-primary dpad-btn"
@mousedown.left="jog(0, -1, 0)" @pointerdown="jog($event, 0, -1, 0)"
@mouseup="jogStop()" @pointerup="jogStop()"
@mouseOut="jogStop()" @pointercancel="jogStop()"
> >
<span class="material-symbols-outlined sync-icon"> arrow_downward </span> <span class="material-symbols-outlined sync-icon"> arrow_downward </span>
</button> </button>
@ -56,9 +56,9 @@
v-if="showFocusControls" v-if="showFocusControls"
id="focus-out-button" id="focus-out-button"
class="uk-button uk-button-primary dpad-btn" class="uk-button uk-button-primary dpad-btn"
@mousedown.left="jog(0, 0, -1)" @pointerdown="jog($event, 0, 0, -1)"
@mouseup="jogStop()" @pointerup="jogStop()"
@mouseOut="jogStop()" @pointercancel="jogStop()"
> >
<span class="material-symbols-outlined sync-icon"> remove </span> <span class="material-symbols-outlined sync-icon"> remove </span>
</button> </button>
@ -67,9 +67,9 @@
v-if="showFocusControls" v-if="showFocusControls"
id="focus-in-button" id="focus-in-button"
class="uk-button uk-button-primary dpad-btn" class="uk-button uk-button-primary dpad-btn"
@mousedown.left="jog(0, 0, 1)" @pointerdown="jog($event, 0, 0, 1)"
@mouseup="jogStop()" @pointerup="jogStop()"
@mouseOut="jogStop()" @pointercancel="jogStop()"
> >
<span class="material-symbols-outlined sync-icon"> add </span> <span class="material-symbols-outlined sync-icon"> add </span>
</button> </button>
@ -98,10 +98,24 @@ export default {
jogTime: 300, jogTime: 300,
}), }),
methods: { methods: {
jog(x, y, z) { /**
* Jog d-pad and focus buttons.
*
* This is a similar to the function in App.vue, however it uses an Interval rather
* than the one in App.vue that uses key repeats.
*/
jog(keyevent, x, y, z) {
// Only respond to primary button (left mouse / primary touch)
if (keyevent.button !== 0) return;
if (this.jogIntervalId) { if (this.jogIntervalId) {
clearInterval(this.jogIntervalId); clearInterval(this.jogIntervalId);
} }
// Designate this element to get the pointers next pointerup event wherever that
// pointer is.
keyevent.target.setPointerCapture(keyevent.pointerId);
const navigationInvert = this.$store.state.navigationInvert; const navigationInvert = this.$store.state.navigationInvert;
let invokeJog = () => let invokeJog = () =>
this.invokeAction("stage", "jog", { this.invokeAction("stage", "jog", {
@ -112,6 +126,12 @@ export default {
invokeJog(); invokeJog();
this.jogIntervalId = setInterval(invokeJog, this.jogTime); this.jogIntervalId = setInterval(invokeJog, this.jogTime);
}, },
/**
* Stop jogging from d-pad and focus buttons.
*
* This is a similar to the function in App.vue, but it is designed to clear the
* interval used with the d-pad and focus buttons.
*/
jogStop() { jogStop() {
if (this.jogIntervalId) { if (this.jogIntervalId) {
clearInterval(this.jogIntervalId); clearInterval(this.jogIntervalId);