mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-24 11:08:12 +08:00
Improve Frontend -> Backend user input system (#348)
Includes refactor that sends coordinates of the document viewports to the backend so input is sent relative to the application window Closes #124 Fixes #291 * Improve Frontend -> Backend user input system * Code review changes * More code review changes * Fix TS error
This commit is contained in:
@@ -3,7 +3,11 @@ import { dialogIsVisible, dismissDialog, submitDialog } from "@/utilities/dialog
|
||||
|
||||
const wasm = import("@/../wasm/pkg");
|
||||
|
||||
export function shouldRedirectKeyboardEventToBackend(e: KeyboardEvent): boolean {
|
||||
let viewportMouseInteractionOngoing = false;
|
||||
|
||||
// Keyboard events
|
||||
|
||||
function shouldRedirectKeyboardEventToBackend(e: KeyboardEvent): boolean {
|
||||
// Don't redirect user input from text entry into HTML elements
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.nodeName === "INPUT" || target.nodeName === "TEXTAREA" || target.isContentEditable) return false;
|
||||
@@ -31,10 +35,10 @@ export function shouldRedirectKeyboardEventToBackend(e: KeyboardEvent): boolean
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function handleKeyDown(e: KeyboardEvent) {
|
||||
export async function onKeyDown(e: KeyboardEvent) {
|
||||
if (shouldRedirectKeyboardEventToBackend(e)) {
|
||||
e.preventDefault();
|
||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||
const modifiers = makeModifiersBitfield(e);
|
||||
(await wasm).on_key_down(e.key, modifiers);
|
||||
return;
|
||||
}
|
||||
@@ -48,27 +52,77 @@ export async function handleKeyDown(e: KeyboardEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleKeyUp(e: KeyboardEvent) {
|
||||
export async function onKeyUp(e: KeyboardEvent) {
|
||||
if (shouldRedirectKeyboardEventToBackend(e)) {
|
||||
e.preventDefault();
|
||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||
const modifiers = makeModifiersBitfield(e);
|
||||
(await wasm).on_key_up(e.key, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleMouseDown(e: MouseEvent) {
|
||||
// Mouse events
|
||||
|
||||
export async function onMouseMove(e: MouseEvent) {
|
||||
if (!e.buttons) viewportMouseInteractionOngoing = false;
|
||||
|
||||
const modifiers = makeModifiersBitfield(e);
|
||||
(await wasm).on_mouse_move(e.clientX, e.clientY, e.buttons, modifiers);
|
||||
}
|
||||
|
||||
export async function onMouseDown(e: MouseEvent) {
|
||||
const target = e.target && (e.target as HTMLElement);
|
||||
const clickedInsideDialog = target && target.closest(".dialog-modal .floating-menu-content");
|
||||
const inCanvas = target && target.closest(".canvas");
|
||||
const inDialog = target && target.closest(".dialog-modal .floating-menu-content");
|
||||
|
||||
if (dialogIsVisible() && !clickedInsideDialog) {
|
||||
// Block middle mouse button auto-scroll mode
|
||||
if (e.button === 1) e.preventDefault();
|
||||
|
||||
if (dialogIsVisible() && !inDialog) {
|
||||
dismissDialog();
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
if (inCanvas) viewportMouseInteractionOngoing = true;
|
||||
|
||||
if (viewportMouseInteractionOngoing) {
|
||||
const modifiers = makeModifiersBitfield(e);
|
||||
(await wasm).on_mouse_down(e.clientX, e.clientY, e.buttons, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
export function makeModifiersBitfield(control: boolean, shift: boolean, alt: boolean): number {
|
||||
export async function onMouseUp(e: MouseEvent) {
|
||||
if (!e.buttons) viewportMouseInteractionOngoing = false;
|
||||
|
||||
const modifiers = makeModifiersBitfield(e);
|
||||
(await wasm).on_mouse_up(e.clientX, e.clientY, e.buttons, modifiers);
|
||||
}
|
||||
|
||||
export async function onMouseScroll(e: WheelEvent) {
|
||||
const target = e.target && (e.target as HTMLElement);
|
||||
const inCanvas = target && target.closest(".canvas");
|
||||
|
||||
if (inCanvas) {
|
||||
e.preventDefault();
|
||||
const modifiers = makeModifiersBitfield(e);
|
||||
(await wasm).on_mouse_scroll(e.clientX, e.clientY, e.buttons, e.deltaX, e.deltaY, e.deltaZ, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
export async function onWindowResize() {
|
||||
const viewports = Array.from(document.querySelectorAll(".canvas"));
|
||||
const boundsOfViewports = viewports.map((canvas) => {
|
||||
const bounds = canvas.getBoundingClientRect();
|
||||
return [bounds.left, bounds.top, bounds.right, bounds.bottom];
|
||||
});
|
||||
|
||||
const flattened = boundsOfViewports.flat();
|
||||
const data = Float64Array.from(flattened);
|
||||
|
||||
if (boundsOfViewports.length > 0) (await wasm).bounds_of_viewports(data);
|
||||
}
|
||||
|
||||
export function makeModifiersBitfield(e: MouseEvent | KeyboardEvent): number {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
return Number(control) | (Number(shift) << 1) | (Number(alt) << 2);
|
||||
return Number(e.ctrlKey) | (Number(e.shiftKey) << 1) | (Number(e.altKey) << 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user