add basic click support

This commit is contained in:
hippoz 2021-10-28 17:03:04 +03:00
parent cc9ae32777
commit b2c0d0218b
Signed by: hippoz
GPG key ID: 7C52899193467641
2 changed files with 92 additions and 34 deletions

View file

@ -75,10 +75,12 @@ class InputController():
return False return False
elif code == "r": elif code == "r":
self.mouse_controller.move(args["x"], args["y"]) self.mouse_controller.move(args["x"], args["y"])
print(args["x"], args["y"]) print("r", args["x"], args["y"])
elif code == "d": elif code == "d":
print("d", args["button"])
self.mouse_controller.press(self.button_code_to_object(args["button"])) self.mouse_controller.press(self.button_code_to_object(args["button"]))
elif code == "u": elif code == "u":
print("u", args["button"])
self.mouse_controller.release(self.button_code_to_object(args["button"])) self.mouse_controller.release(self.button_code_to_object(args["button"]))
else: else:
print("got invalid code from parser (is this a bug with the MessageParser?)") print("got invalid code from parser (is this a bug with the MessageParser?)")

View file

@ -3,8 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <title>Document</title>
<title>Document</title>
<script> <script>
const loggerOfType = (components, type='log') => (...args) => { const loggerOfType = (components, type='log') => (...args) => {
@ -94,35 +93,95 @@
} }
} }
let connection = new Connection(`ws://${location.host}/gateway`, true); class TouchpadController {
constructor(connection) {
this.currentMoveX = 0;
this.currentMoveY = 0;
this.lastMoveX = 0;
this.lastMoveY = 0;
this.shouldResetLastMove = false;
this.ongoingTouches = {};
this.log = Logger(["TouchpadController"], ["log"]).log;
this.connection = connection;
}
_sendRelativeMouseMovement(dx, dy) {
if (dx === 0 && dy === 0)
return;
this.connection.sendMessage("r", [dx, dy]);
}
_sendSingleClick(button="left") {
let buttonCode = 0;
if (button === "right") buttonCode = 1;
this.connection.sendMessage("d", [buttonCode]);
setTimeout(
() =>this.connection.sendMessage("u", [buttonCode]),
5
);
}
bindTo(element) {
element.addEventListener("touchmove", this.onTouchMove.bind(this));
element.addEventListener("touchend", this.onTouchEnd.bind(this));
element.addEventListener("touchstart", this.onTouchStart.bind(this));
}
onTouchMove({ touches }) {
const targetTouch = touches[0];
this.ongoingTouches[targetTouch.identifier].hasMoved = true;
this.currentMoveX = targetTouch.clientX;
this.currentMoveY = targetTouch.clientY;
// When ending a touch and starting a new one in another part of the touchpad,
// the cursor "rubber bands" to that position.
// To solve this, the "last move" parameters are reset when a touch is ended
// (see onTouchEnd())
if (this.shouldResetLastMove) {
this.shouldResetLastMove = false;
this.lastMoveX = this.currentMoveX;
this.lastMoveY = this.currentMoveY;
}
const deltaX = this.currentMoveX - this.lastMoveX;
const deltaY = this.currentMoveY - this.lastMoveY;
this.lastMoveX = this.currentMoveX;
this.lastMoveY = this.currentMoveY;
this._sendRelativeMouseMovement(deltaX, deltaY);
}
onTouchEnd({ changedTouches }) {
this.shouldResetLastMove = true;
// A single tap = left click
if (changedTouches.length === 1 && !this.ongoingTouches[changedTouches[0].identifier].hasMoved)
this._sendSingleClick("left");
for (let i = 0; i < changedTouches.length; i++) {
const touch = changedTouches[i];
this.ongoingTouches[touch.identifier] = null;
delete this.ongoingTouches[touch.identifier];
}
}
onTouchStart({ changedTouches }) {
for (let i = 0; i < changedTouches.length; i++) {
const touch = changedTouches[i];
this.ongoingTouches[touch.identifier] = {
identifier: touch.identifier,
clientX: touch.clientX,
clientY: touch.clientY,
hasMoved: false
};
}
}
}
const connection = new Connection(`ws://${location.host}/gateway`, true);
const controller = new TouchpadController(connection);
function main() { function main() {
connection.connect(); connection.connect();
const touchpad = document.querySelector(".touchpad"); controller.bindTo(document.querySelector(".touchpad"));
const movementState = {
currentX: 0,
currentY: 0,
lastCheckedX: 0,
lastCheckedY: 0,
shouldResetTouch: false,
}
touchpad.addEventListener("touchmove", (event) => {
movementState.currentX = event.touches[0].clientX;
movementState.currentY = event.touches[0].clientY;
if (movementState.shouldResetTouch) {
movementState.shouldResetTouch = false;
movementState.lastCheckedX = movementState.currentX;
movementState.lastCheckedY = movementState.currentY;
}
const deltaX = movementState.currentX - movementState.lastCheckedX;
const deltaY = movementState.currentY - movementState.lastCheckedY;
movementState.lastCheckedX = movementState.currentX;
movementState.lastCheckedY = movementState.currentY;
connection.sendMessage("r", [deltaX, deltaY]);
});
touchpad.addEventListener("touchend", () => {
movementState.shouldResetTouch = true;
});
} }
</script> </script>
@ -135,9 +194,6 @@
</style> </style>
</head> </head>
<body onload="main();"> <body onload="main();">
<div class="touchpad"> <div class="touchpad"></div>
</div>
<button onClick="connection.sendMessage('r', [20, 20])">Move mouse test</button>
</body> </body>
</html> </html>