improve design and add right click support

This commit is contained in:
hippoz 2021-10-30 19:20:27 +03:00
parent c573e750eb
commit 7fb4e97f9e
No known key found for this signature in database
GPG key ID: 7C52899193467641
2 changed files with 94 additions and 24 deletions

View file

@ -69,6 +69,10 @@ class InputController():
self.parser.add_handler("u", { self.parser.add_handler("u", {
"button": "int" "button": "int"
}) })
# Mouse button click
self.parser.add_handler("c", {
"button": "int"
})
def button_code_to_object(self, button_code: int): def button_code_to_object(self, button_code: int):
# HACK # HACK
obj = None obj = None
@ -92,6 +96,9 @@ class InputController():
elif code == "u": elif code == "u":
print("u", args["button"]) 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"]))
elif code == "c":
print("c", args["button"])
self.mouse_controller.click(self.button_code_to_object(args["button"]))
elif code == "s": elif code == "s":
print("s", args["x"], args["y"]) print("s", args["x"], args["y"])
self.mouse_controller.scroll(args["x"], args["y"]) self.mouse_controller.scroll(args["x"], args["y"])

View file

@ -6,8 +6,13 @@
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <title>Document</title> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"> <title>Document</title>
<script> <script>
"use strict";
const domlog = message => document.body.appendChild(document.createTextNode(message));
window.onerror = e => domlog(` ERROR - ${e} `);
const HOLDING_THRESHOLD_MS = 300; const HOLDING_THRESHOLD_MS = 300;
const SINGLE_CLICK_BUTTON_UP_MS = 5;
const SCROLL_X_DAMPENING = 0.05; const SCROLL_X_DAMPENING = 0.05;
const SCROLL_Y_DAMPENING = 0.06; const SCROLL_Y_DAMPENING = 0.06;
@ -59,11 +64,10 @@
} }
class Connection { class Connection {
constructor(url, logMessages=false) { constructor(url) {
this.ws = null; this.ws = null;
this.log = Logger(["Connection"], ["log"]).log; this.log = Logger(["Connection"], ["log"]).log;
this.messageLog = Logger(["Connection", "Message"], ["log"]).log; this.messageLog = Logger(["Connection", "Message"], ["log"]).log;
this.logMessages = logMessages;
this.url = url; this.url = url;
} }
@ -87,7 +91,6 @@
else else
message += param + ";"; message += param + ";";
}); });
if (this.logMessages) this.messageLog(message);
this.ws.send(message); this.ws.send(message);
return message; return message;
@ -120,16 +123,29 @@
return buttonCode; return buttonCode;
} }
// takes a gesture name and a touch list
// adds the gesture name to the touch and returns false if that touch already had that gesture
_gesture(gestureName, touchList) {
for (let i = 0; i < touchList.length; i++) {
const touch = this.ongoingTouches[touchList[i].identifier];
if (touch.gestured.includes(gestureName)) return false;
touch.gestured.push(gestureName);
}
return true;
}
_sendRelativeMouseMovement(dx, dy) { _sendRelativeMouseMovement(dx, dy) {
if (dx === 0 && dy === 0) if (dx === 0 && dy === 0)
return; return false;
this.connection.sendMessage("r", [dx, dy]); this.connection.sendMessage("r", [dx, dy]);
return true;
} }
_sendRelativeMouseScroll(dx, dy) { _sendRelativeMouseScroll(dx, dy) {
if (dx === 0 && dy === 0) if (dx === 0 && dy === 0)
return; return false;
this.connection.sendMessage("s", [dx, dy]); this.connection.sendMessage("s", [dx, dy]);
return true;
} }
_sendMouseButtonDown(button="left") { _sendMouseButtonDown(button="left") {
@ -141,11 +157,7 @@
} }
_sendSingleClick(button="left") { _sendSingleClick(button="left") {
this._sendMouseButtonDown(button); this.connection.sendMessage("c", [this.getButtonCode(button)]);
setTimeout(
() => this._sendMouseButtonUp(button),
SINGLE_CLICK_BUTTON_UP_MS
);
} }
bindTo(element) { bindTo(element) {
@ -155,11 +167,10 @@
} }
onTouchMove(event) { onTouchMove(event) {
const touches = event.touches; const touches = event.changedTouches;
event.preventDefault(); event.preventDefault();
for (let i = 0; i < touches.length; i++) { event.stopPropagation();
this.ongoingTouches[touches[i].identifier].hasMoved = true;
}
const targetTouch = touches[0]; const targetTouch = touches[0];
this.currentMoveX = targetTouch.pageX; this.currentMoveX = targetTouch.pageX;
@ -178,21 +189,44 @@
this.lastMoveX = this.currentMoveX; this.lastMoveX = this.currentMoveX;
this.lastMoveY = this.currentMoveY; this.lastMoveY = this.currentMoveY;
// if two touches moved at the same time, assume scrolling intent // if two touches moved at the same time, assume scrolling intent
// if _sendRelativeMouseScroll or _sendRelativeMouseMovement return true, it means that the delta values are non-zero and a packet has been sent to the server
// in that case, the touches will be marked as moved
let shouldMarkTouchesAsMoved = false;
if (touches.length === 2) { if (touches.length === 2) {
this._sendRelativeMouseScroll(deltaX * SCROLL_X_DAMPENING, deltaY * SCROLL_Y_DAMPENING); if (
this._sendRelativeMouseScroll(deltaX * SCROLL_X_DAMPENING, deltaY * SCROLL_Y_DAMPENING)
) {
shouldMarkTouchesAsMoved = true;
}
} else if (touches.length === 3 && this._gesture("GESTURE_RIGHT_CLICK", touches)) {
shouldMarkTouchesAsMoved = true;
this._sendSingleClick("right");
} else { } else {
this._sendRelativeMouseMovement(deltaX, deltaY); if (
this._sendRelativeMouseMovement(deltaX, deltaY)
) {
shouldMarkTouchesAsMoved = true;
}
}
if (shouldMarkTouchesAsMoved) {
for (let i = 0; i < touches.length; i++) {
this.ongoingTouches[touches[i].identifier].hasMoved = true;
}
} }
} }
onTouchEnd(event) { onTouchEnd(event) {
const changedTouches = event.changedTouches; const changedTouches = event.changedTouches;
event.preventDefault(); event.preventDefault();
event.stopPropagation();
this.shouldResetLastMove = true; this.shouldResetLastMove = true;
if (changedTouches.length === 1) { if (changedTouches.length === 1) {
// This is a single tap - left click // This is a single tap - left click
if (!this.ongoingTouches[changedTouches[0].identifier].hasMoved) { if (!this.ongoingTouches[changedTouches[0].identifier].hasMoved) {
this._sendSingleClick("left"); this._sendSingleClick("left");
// We were in "holding mode" and now that touch event has ended, // We were in "holding mode" and now that touch event has ended,
// thus we have to stop holding the left click button // thus we have to stop holding the left click button
} else if (this.isInHoldingMode) { } else if (this.isInHoldingMode) {
@ -200,6 +234,8 @@
this.isInHoldingMode = false; this.isInHoldingMode = false;
} }
} }
// remove all ended touches
for (let i = 0; i < changedTouches.length; i++) { for (let i = 0; i < changedTouches.length; i++) {
const touch = changedTouches[i]; const touch = changedTouches[i];
this.ongoingTouches[touch.identifier] = null; this.ongoingTouches[touch.identifier] = null;
@ -210,6 +246,7 @@
onTouchStart(event) { onTouchStart(event) {
const changedTouches = event.changedTouches; const changedTouches = event.changedTouches;
event.preventDefault(); event.preventDefault();
event.stopPropagation();
// Clear the hold mode time out if another touch begins // Clear the hold mode time out if another touch begins
if (this.holdModeTimeout) if (this.holdModeTimeout)
@ -234,13 +271,14 @@
identifier: touch.identifier, identifier: touch.identifier,
clientX: touch.clientX, clientX: touch.clientX,
clientY: touch.clientY, clientY: touch.clientY,
hasMoved: false hasMoved: false,
gestured: []
}; };
} }
} }
} }
const connection = new Connection(`ws://${location.host}/gateway`, true); const connection = new Connection(`ws://${location.host}/gateway`);
const controller = new TouchpadController(connection); const controller = new TouchpadController(connection);
function main() { function main() {
connection.connect(); connection.connect();
@ -249,10 +287,35 @@
</script> </script>
<style> <style>
:root {
--body-bg-color: #2e2e2e;
--accent-bg-color: #d4d3d3;
--accent-color: #949494;
--grayed-text-color: #949494;
--button-accent-color: #3d3d3d;
--selected-bg-color: #2e2e2e;
--hover-bg-color: #4d4d4d;
--card-border-radius: 1rem;
--button-border-radius: 0.5rem;
--main-font-weight: 500;
--fonts-regular: "Noto Sans", "Liberation Sans", sans-serif;
}
body {
font-weight: var(--main-font-weight);
font-family: var(--fonts-regular);
background-color: var(--body-bg-color);
color: var(--accent-bg-color);
margin: 0;
padding: 24px;
}
.touchpad { .touchpad {
width: 75vw; height: 30rem;
height: 50vh; width: 100%;
background-color: blue; background-color: var(--accent-bg-color);
border-radius: var(--card-border-radius);
} }
</style> </style>
</head> </head>