Skip to content

Commit 232f96d

Browse files
mattgodboltclaude
andcommitted
Refactor mouse joystick to use proper API instead of direct event handling
- Replace event-driven approach with clean API methods: onMouseMove(), onMouseDown(), onMouseUp(), isEnabled() - Update main.js to use API methods instead of direct property manipulation - Fix config change handler to use updated parsedQuery values for immediate UI response - Remove debug console.log statements from MouseJoystickSource and VIA - Update tests to reflect new API-based approach - Remove event listener registration/cleanup code 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 8e5a758 commit 232f96d

File tree

3 files changed

+91
-186
lines changed

3 files changed

+91
-186
lines changed

src/main.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ const config = new Config(function (changed) {
245245
}
246246
// Handle ADC source changes
247247
if (changed.mouseJoystickEnabled !== undefined || changed.microphoneChannel !== undefined) {
248-
// Update sources based on new settings
248+
// Update sources based on new settings (parsedQuery already updated with changed values)
249249
updateAdcSources(parsedQuery.mouseJoystickEnabled, parsedQuery.microphoneChannel);
250250

251251
// Handle microphone initialization if needed
@@ -421,7 +421,23 @@ $cub.on("mousemove mousedown mouseup", function (evt) {
421421
const screenOffset = $screen.offset();
422422
const x = (evt.offsetX - cubOffset.left + screenOffset.left) / $screen.width();
423423
const y = (evt.offsetY - cubOffset.top + screenOffset.top) / $screen.height();
424+
425+
// Handle touchscreen
424426
if (processor.touchScreen) processor.touchScreen.onMouse(x, y, evt.buttons);
427+
428+
// Handle mouse joystick if enabled
429+
if (parsedQuery.mouseJoystickEnabled && mouseJoystickSource.isEnabled()) {
430+
// Use the API methods instead of direct manipulation
431+
mouseJoystickSource.onMouseMove(x, y);
432+
433+
// Handle button events
434+
if (evt.type === "mousedown" && evt.button === 0) {
435+
mouseJoystickSource.onMouseDown(0);
436+
} else if (evt.type === "mouseup" && evt.button === 0) {
437+
mouseJoystickSource.onMouseUp(0);
438+
}
439+
}
440+
425441
evt.preventDefault();
426442
});
427443

src/mouse-joystick-source.js

Lines changed: 27 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -16,115 +16,59 @@ export class MouseJoystickSource extends AnalogueSource {
1616
this.mouseY = 0.5; // Normalized position (0-1)
1717
this.isActive = false;
1818
this.via = null; // Will be set later
19-
20-
// Bind event handlers
21-
this.handleMouseMove = this.handleMouseMove.bind(this);
22-
this.handleMouseEnter = this.handleMouseEnter.bind(this);
23-
this.handleMouseLeave = this.handleMouseLeave.bind(this);
24-
this.handleMouseDown = this.handleMouseDown.bind(this);
25-
this.handleMouseUp = this.handleMouseUp.bind(this);
26-
this.handleGlobalMouseMove = this.handleGlobalMouseMove.bind(this);
27-
28-
// Attach event listeners
29-
this.canvas.addEventListener("mousemove", this.handleMouseMove);
30-
this.canvas.addEventListener("mouseenter", this.handleMouseEnter);
31-
this.canvas.addEventListener("mouseleave", this.handleMouseLeave);
32-
this.canvas.addEventListener("mousedown", this.handleMouseDown);
33-
this.canvas.addEventListener("mouseup", this.handleMouseUp);
34-
35-
// Also listen to global mouse moves to track position even when not over canvas
36-
document.addEventListener("mousemove", this.handleGlobalMouseMove);
3719
}
3820

3921
/**
40-
* Handle mouse movement over the canvas
41-
* @param {MouseEvent} event - The mouse event
22+
* Set the VIA reference for button handling
23+
* @param {object} via - The system VIA
4224
*/
43-
handleMouseMove(event) {
44-
if (!this.isActive) return;
45-
46-
const rect = this.canvas.getBoundingClientRect();
47-
const x = event.clientX - rect.left;
48-
const y = event.clientY - rect.top;
49-
50-
// Normalize to 0-1 range
51-
this.mouseX = x / rect.width;
52-
this.mouseY = y / rect.height;
53-
54-
// Clamp values
55-
this.mouseX = Math.max(0, Math.min(1, this.mouseX));
56-
this.mouseY = Math.max(0, Math.min(1, this.mouseY));
25+
setVia(via) {
26+
this.via = via;
5727
}
5828

5929
/**
60-
* Handle mouse entering the canvas
30+
* Handle mouse movement event from external handler
31+
* @param {number} x - Normalized X position (0-1)
32+
* @param {number} y - Normalized Y position (0-1)
6133
*/
62-
handleMouseEnter() {
34+
onMouseMove(x, y) {
35+
this.mouseX = Math.max(0, Math.min(1, x));
36+
this.mouseY = Math.max(0, Math.min(1, y));
6337
this.isActive = true;
6438
}
6539

6640
/**
67-
* Handle mouse leaving the canvas
41+
* Handle mouse button press from external handler
42+
* @param {number} button - Mouse button number (0 = left, 1 = middle, 2 = right)
6843
*/
69-
handleMouseLeave() {
70-
this.isActive = false;
71-
// Don't center when mouse leaves - keep last position
72-
}
73-
74-
/**
75-
* Handle global mouse movement (even when not over canvas)
76-
* @param {MouseEvent} event - The mouse event
77-
*/
78-
handleGlobalMouseMove(event) {
79-
const rect = this.canvas.getBoundingClientRect();
80-
const x = event.clientX - rect.left;
81-
const y = event.clientY - rect.top;
82-
83-
// Normalize to 0-1 range
84-
this.mouseX = x / rect.width;
85-
this.mouseY = y / rect.height;
86-
87-
// Clamp values to 0-1 range
88-
this.mouseX = Math.max(0, Math.min(1, this.mouseX));
89-
this.mouseY = Math.max(0, Math.min(1, this.mouseY));
90-
}
91-
92-
/**
93-
* Handle mouse button press
94-
* @param {MouseEvent} event - The mouse event
95-
*/
96-
handleMouseDown(event) {
97-
if (!this.isActive || !this.via) return;
44+
onMouseDown(button) {
45+
if (!this.via) return;
9846

9947
// Only handle left mouse button (button 0)
100-
if (event.button === 0) {
101-
// Set fire button 1 pressed (PB4)
48+
if (button === 0) {
10249
this.via.setJoystickButton(0, true);
103-
event.preventDefault();
10450
}
10551
}
10652

10753
/**
108-
* Handle mouse button release
109-
* @param {MouseEvent} event - The mouse event
54+
* Handle mouse button release from external handler
55+
* @param {number} button - Mouse button number (0 = left, 1 = middle, 2 = right)
11056
*/
111-
handleMouseUp(event) {
57+
onMouseUp(button) {
11258
if (!this.via) return;
11359

11460
// Only handle left mouse button (button 0)
115-
if (event.button === 0) {
116-
// Release fire button 1 (PB4)
61+
if (button === 0) {
11762
this.via.setJoystickButton(0, false);
118-
event.preventDefault();
11963
}
12064
}
12165

12266
/**
123-
* Set the VIA reference for button handling
124-
* @param {object} via - The system VIA
67+
* Check if mouse joystick is enabled and ready
68+
* @returns {boolean} True if mouse joystick can handle events
12569
*/
126-
setVia(via) {
127-
this.via = via;
70+
isEnabled() {
71+
return !!this.via;
12872
}
12973

13074
/**
@@ -152,15 +96,12 @@ export class MouseJoystickSource extends AnalogueSource {
15296
}
15397

15498
/**
155-
* Clean up event listeners when source is no longer needed
99+
* Clean up when source is no longer needed
156100
* Called by ADC when switching to a different source
157101
*/
158102
dispose() {
159-
this.canvas.removeEventListener("mousemove", this.handleMouseMove);
160-
this.canvas.removeEventListener("mouseenter", this.handleMouseEnter);
161-
this.canvas.removeEventListener("mouseleave", this.handleMouseLeave);
162-
this.canvas.removeEventListener("mousedown", this.handleMouseDown);
163-
this.canvas.removeEventListener("mouseup", this.handleMouseUp);
164-
document.removeEventListener("mousemove", this.handleGlobalMouseMove);
103+
// Reset state
104+
this.via = null;
105+
this.isActive = false;
165106
}
166107
}

0 commit comments

Comments
 (0)