From 24c7aefeb502143b2a76d1352795afd1c5c08832 Mon Sep 17 00:00:00 2001 From: Jordan Irwin Date: Fri, 1 Mar 2024 19:30:57 -0800 Subject: [PATCH] Move quick menu click listener registration to class for... ...global use https://github.com/arianne/stendhal/issues/417 --- .../stendhal/ui/quickmenu/QuickMenuButton.ts | 31 ++-------- srcjs/stendhal/util/ElementClickHandler.ts | 61 +++++++++++++++++++ 2 files changed, 65 insertions(+), 27 deletions(-) create mode 100644 srcjs/stendhal/util/ElementClickHandler.ts diff --git a/srcjs/stendhal/ui/quickmenu/QuickMenuButton.ts b/srcjs/stendhal/ui/quickmenu/QuickMenuButton.ts index 9ff9e7d8d35..e311ebc7da1 100644 --- a/srcjs/stendhal/ui/quickmenu/QuickMenuButton.ts +++ b/srcjs/stendhal/ui/quickmenu/QuickMenuButton.ts @@ -14,6 +14,7 @@ declare var stendhal: any; import { Component } from "../toolkit/Component"; import { ui } from "../UI"; import { Paths } from "../../data/Paths"; +import { ElementClickHandler } from "../../util/ElementClickHandler"; /** @@ -48,34 +49,10 @@ export abstract class QuickMenuButton extends Component { (this.componentElement as HTMLImageElement).src = Paths.gui + "/quickmenu/" + id + ".png"; this.componentElement.style["cursor"] = "url(" + Paths.sprites + "/cursor/highlight.png) 1 3, auto"; this.componentElement.draggable = false; + // listen for click events - this.componentElement.addEventListener("mousedown", (evt: MouseEvent) => { - evt.preventDefault(); - if (evt.button == 0) { - this.clickEngaged = true; - } - }); - this.componentElement.addEventListener("touchstart", (evt: TouchEvent) => { - evt.preventDefault(); - this.touchEngaged = evt.changedTouches.length; - }); - this.componentElement.addEventListener("mouseup", (evt: MouseEvent) => { - evt.preventDefault(); - if (this.clickEngaged && evt.button == 0) { - // FIXME: should veto if moved too much before release - this.onClick(evt); - } - this.clickEngaged = false; - }); - this.componentElement.addEventListener("touchend", (evt: TouchEvent) => { - evt.preventDefault(); - const target = stendhal.ui.html.extractTarget(evt, this.touchEngaged - 1); - if (this.touchEngaged == evt.changedTouches.length && target == this.componentElement) { - // FIXME: should veto if moved too much before release - this.onClick(evt); - } - this.touchEngaged = 0; - }); + // FIXME: do we need to store this value for potential cleanup? + new ElementClickHandler(this.componentElement).onClick = this.onClick; this.update(); } diff --git a/srcjs/stendhal/util/ElementClickHandler.ts b/srcjs/stendhal/util/ElementClickHandler.ts new file mode 100644 index 00000000000..43182d1565f --- /dev/null +++ b/srcjs/stendhal/util/ElementClickHandler.ts @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright © 2024 - Faiumoni e. V. * + *************************************************************************** + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation; either version 3 of the * + * License, or (at your option) any later version. * + * * + ***************************************************************************/ + +declare var stendhal: any; + + +/** + * Adds event listeners to handle clicks & multiple touches. + * + * TODO: add support long & double click/touch + */ +export class ElementClickHandler { + + /** Function executed when click is detected. */ + public onClick?: Function; + /** Property denoting button was pressed with mouse click. */ + private clickEngaged = false; + /** Property denoting button was pressed with tap/touch. */ + private touchEngaged = 0; + + + constructor(element: HTMLElement) { + // add supported listeners + element.addEventListener("mousedown", (evt: MouseEvent) => { + evt.preventDefault(); + if (evt.button == 0) { + this.clickEngaged = true; + } + }); + element.addEventListener("touchstart", (evt: TouchEvent) => { + evt.preventDefault(); + this.touchEngaged = evt.changedTouches.length; + }); + element.addEventListener("mouseup", (evt: MouseEvent) => { + evt.preventDefault(); + if (this.clickEngaged && evt.button == 0 && this.onClick) { + // FIXME: should veto if moved too much before release + this.onClick(evt); + } + this.clickEngaged = false; + }); + element.addEventListener("touchend", (evt: TouchEvent) => { + evt.preventDefault(); + const target = stendhal.ui.html.extractTarget(evt, this.touchEngaged - 1); + if (this.touchEngaged == evt.changedTouches.length && target == element && this.onClick) { + // FIXME: should veto if moved too much before release + this.onClick(evt); + } + this.touchEngaged = 0; + }); + } +}