mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
199 lines
6.9 KiB
TypeScript
199 lines
6.9 KiB
TypeScript
import { DomEvent, LeafletMouseEvent, Point } from "leaflet";
|
|
import { Map } from "./map";
|
|
|
|
enum MapMouseHandlerState {
|
|
IDLE = "IDLE",
|
|
LEFT_MOUSE_DOWN = "Left mouse down",
|
|
MOUSE_WHEEL_DOWN = "Mouse wheel down",
|
|
RIGHT_MOUSE_DOWN = "Right mouse down",
|
|
DEBOUNCING = "Debouncing",
|
|
}
|
|
|
|
export class MapMouseHandler {
|
|
#map: Map;
|
|
#state: string = MapMouseHandlerState.IDLE;
|
|
#leftMouseDownEpoch: number = 0;
|
|
#rightMouseDownEpoch: number = 0;
|
|
#mouseWheelDownEpoch: number = 0;
|
|
#leftMouseDownTimeout: number | null = null;
|
|
#rightMouseDownTimeout: number | null = null;
|
|
#mouseWheelDownTimeout: number | null = null;
|
|
|
|
#debounceTimeout: number | null = null;
|
|
|
|
leftMousePressed: (event: LeafletMouseEvent) => void = () => {};
|
|
leftMouseReleased: (event: LeafletMouseEvent) => void = () => {};
|
|
rightMousePressed: (event: LeafletMouseEvent) => void = () => {};
|
|
rightMouseReleased: (event: LeafletMouseEvent) => void = () => {};
|
|
mouseWheelPressed: (event: LeafletMouseEvent) => void = () => {};
|
|
mouseWheelReleased: (event: LeafletMouseEvent) => void = () => {};
|
|
|
|
leftMouseDoubleClick: (event: LeafletMouseEvent) => void = () => {};
|
|
|
|
leftMouseShortClick: (event: LeafletMouseEvent) => void = () => {};
|
|
rightMouseShortClick: (event: LeafletMouseEvent) => void = () => {};
|
|
mouseWheelShortClick: (event: LeafletMouseEvent) => void = () => {};
|
|
leftMouseLongClick: (event: LeafletMouseEvent) => void = () => {};
|
|
rightMouseLongClick: (event: LeafletMouseEvent) => void = () => {};
|
|
mouseWheelLongClick: (event: LeafletMouseEvent) => void = () => {};
|
|
|
|
mouseMove: (event: LeafletMouseEvent) => void = () => {};
|
|
|
|
mouseWheel: (event: LeafletMouseEvent) => void = () => {};
|
|
|
|
constructor(map) {
|
|
this.#map = map;
|
|
|
|
/* Events for touchscreen and mouse */
|
|
if ("ontouchstart" in window) {
|
|
DomEvent.on(this.#map.getContainer(), "touchstart", (e: any) => this.#onTouchDown(e), this);
|
|
DomEvent.on(this.#map.getContainer(), "touchend", (e: any) => this.#onTouchUp(e), this);
|
|
DomEvent.on(this.#map.getContainer(), "touchmove", (e: any) => this.#onTouchMove(e), this);
|
|
} else {
|
|
this.#map.on("mouseup", (e: any) => this.#onMouseUp(e));
|
|
this.#map.on("mousedown", (e: any) => this.#onMouseDown(e));
|
|
this.#map.on("mousemove", (e: any) => this.#onMouseMove(e));
|
|
}
|
|
this.#map.on("dblclick", (e: any) => this.#onDoubleClick(e));
|
|
|
|
/* Disable unwanted events */
|
|
this.#map.on("click", (e: any) => e.originalEvent.preventDefault());
|
|
this.#map.on("contextmenu", (e: any) => e.originalEvent.preventDefault());
|
|
|
|
/* Mouse wheel event */
|
|
DomEvent.on(this.#map.getContainer(), "wheel", (e: any) => this.#onMouseWheel(e), this);
|
|
}
|
|
|
|
setState(state: string) {
|
|
console.log("MouseHandler switching state from", this.#state, "to", state);
|
|
this.#state = state;
|
|
}
|
|
|
|
#onMouseDown = (e: LeafletMouseEvent) => {
|
|
if (e.originalEvent.button === 0) {
|
|
this.leftMousePressed(e);
|
|
this.setState(MapMouseHandlerState.LEFT_MOUSE_DOWN);
|
|
this.#leftMouseDownEpoch = Date.now();
|
|
this.#leftMouseDownTimeout = window.setTimeout(() => {
|
|
this.leftMouseLongClick(e);
|
|
this.#leftMouseDownTimeout = null;
|
|
}, 300);
|
|
} else if (e.originalEvent.button === 1) {
|
|
this.mouseWheelPressed(e);
|
|
this.setState(MapMouseHandlerState.MOUSE_WHEEL_DOWN);
|
|
this.#mouseWheelDownEpoch = Date.now();
|
|
this.#mouseWheelDownTimeout = window.setTimeout(() => {
|
|
this.mouseWheelLongClick(e);
|
|
this.#mouseWheelDownTimeout = null;
|
|
}, 300);
|
|
} else if (e.originalEvent.button === 2) {
|
|
this.rightMousePressed(e);
|
|
this.setState(MapMouseHandlerState.RIGHT_MOUSE_DOWN);
|
|
this.#rightMouseDownEpoch = Date.now();
|
|
this.#rightMouseDownTimeout = window.setTimeout(() => {
|
|
this.rightMouseLongClick(e);
|
|
this.#rightMouseDownTimeout = null;
|
|
}, 300);
|
|
}
|
|
};
|
|
|
|
#onMouseUp = (e: LeafletMouseEvent) => {
|
|
if (this.#leftMouseDownTimeout) {
|
|
clearTimeout(this.#leftMouseDownTimeout);
|
|
this.#leftMouseDownTimeout = null;
|
|
}
|
|
if (this.#rightMouseDownTimeout) {
|
|
clearTimeout(this.#rightMouseDownTimeout);
|
|
this.#rightMouseDownTimeout = null;
|
|
}
|
|
if (this.#rightMouseDownTimeout) {
|
|
clearTimeout(this.#rightMouseDownTimeout);
|
|
this.#rightMouseDownTimeout = null;
|
|
}
|
|
|
|
if (this.#state === MapMouseHandlerState.LEFT_MOUSE_DOWN) {
|
|
this.leftMouseReleased(e);
|
|
if (Date.now() - this.#leftMouseDownEpoch < 300) {
|
|
this.setState(MapMouseHandlerState.DEBOUNCING);
|
|
this.#debounceTimeout = window.setTimeout(() => {
|
|
this.leftMouseShortClick(e);
|
|
}, 300);
|
|
}
|
|
} else if (this.#state === MapMouseHandlerState.MOUSE_WHEEL_DOWN) {
|
|
this.mouseWheelReleased(e);
|
|
if (Date.now() - this.#mouseWheelDownEpoch < 300) {
|
|
this.mouseWheelShortClick(e);
|
|
}
|
|
} else if (this.#state === MapMouseHandlerState.RIGHT_MOUSE_DOWN) {
|
|
this.rightMouseReleased(e);
|
|
if (Date.now() - this.#rightMouseDownEpoch < 300) {
|
|
this.rightMouseShortClick(e);
|
|
}
|
|
}
|
|
|
|
this.setState(MapMouseHandlerState.IDLE);
|
|
};
|
|
|
|
#onDoubleClick = (e: LeafletMouseEvent) => {
|
|
this.leftMouseDoubleClick(e);
|
|
if (this.#debounceTimeout) {
|
|
clearTimeout(this.#debounceTimeout);
|
|
}
|
|
};
|
|
|
|
#onMouseWheel = (e: LeafletMouseEvent) => {
|
|
this.mouseWheel(e);
|
|
};
|
|
|
|
#onTouchDown = (e: TouchEvent) => {
|
|
let newEvent = {
|
|
latlng: this.#map.containerPointToLatLng(this.#map.mouseEventToContainerPoint(e.changedTouches[0] as unknown as MouseEvent)),
|
|
originalEvent: e,
|
|
} as unknown as LeafletMouseEvent;
|
|
|
|
this.leftMousePressed(newEvent);
|
|
this.setState(MapMouseHandlerState.LEFT_MOUSE_DOWN);
|
|
this.#leftMouseDownEpoch = Date.now();
|
|
this.#leftMouseDownTimeout = window.setTimeout(() => {
|
|
this.leftMouseLongClick(newEvent);
|
|
this.#leftMouseDownTimeout = null;
|
|
}, 300);
|
|
};
|
|
|
|
#onTouchUp = (e: TouchEvent) => {
|
|
let newEvent = {
|
|
latlng: this.#map.containerPointToLatLng(this.#map.mouseEventToContainerPoint(e.changedTouches[0] as unknown as MouseEvent)),
|
|
originalEvent: e,
|
|
} as unknown as LeafletMouseEvent;
|
|
|
|
if (this.#leftMouseDownTimeout) {
|
|
clearTimeout(this.#leftMouseDownTimeout);
|
|
this.#leftMouseDownTimeout = null;
|
|
}
|
|
|
|
if (this.#state === MapMouseHandlerState.LEFT_MOUSE_DOWN) {
|
|
this.leftMouseReleased(newEvent);
|
|
if (Date.now() - this.#leftMouseDownEpoch < 300) {
|
|
this.#debounceTimeout = window.setTimeout(() => {
|
|
this.leftMouseShortClick(newEvent);
|
|
}, 300);
|
|
}
|
|
}
|
|
|
|
this.setState(MapMouseHandlerState.IDLE);
|
|
};
|
|
|
|
#onMouseMove = (e: LeafletMouseEvent) => {
|
|
this.mouseMove(e);
|
|
};
|
|
|
|
#onTouchMove = (e: TouchEvent) => {
|
|
let newEvent = {
|
|
latlng: this.#map.containerPointToLatLng(this.#map.mouseEventToContainerPoint(e.changedTouches[0] as unknown as MouseEvent)),
|
|
originalEvent: e,
|
|
} as unknown as LeafletMouseEvent;
|
|
|
|
this.mouseMove(newEvent);
|
|
};
|
|
}
|