From 05f58f4ca18053b126d896be0006daf809404ed2 Mon Sep 17 00:00:00 2001 From: Chase <60807752+Chase-Percy@users.noreply.github.com> Date: Fri, 12 May 2023 13:55:03 +0800 Subject: [PATCH] Allow right clicking in text fields (#1207) * Allow right clicking in text edit * Cleanup --------- Co-authored-by: Keavon Chambers --- .../src/components/panels/Document.svelte | 1 + frontend/src/io-managers/input.ts | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/panels/Document.svelte b/frontend/src/components/panels/Document.svelte index dc80f8eb..dbac9e5b 100644 --- a/frontend/src/components/panels/Document.svelte +++ b/frontend/src/components/panels/Document.svelte @@ -276,6 +276,7 @@ textInput.focus(); textInput.click(); + // Sends the text input element used for interactively editing with the text tool in a custom event window.dispatchEvent(new CustomEvent("modifyinputfield", { detail: textInput })); } diff --git a/frontend/src/io-managers/input.ts b/frontend/src/io-managers/input.ts index 49baba30..53c26519 100644 --- a/frontend/src/io-managers/input.ts +++ b/frontend/src/io-managers/input.ts @@ -21,13 +21,9 @@ export function createInputManager(editor: Editor, dialog: DialogState, document app?.focus(); let viewportPointerInteractionOngoing = false; - let textInput = undefined as undefined | HTMLDivElement; + let textToolInteractiveInputElement = undefined as undefined | HTMLDivElement; let canvasFocused = true; - function blurApp(): void { - canvasFocused = false; - } - // Event listeners // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -43,7 +39,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document { target: window, eventName: "wheel", action: (e: WheelEvent) => onWheelScroll(e), options: { passive: false } }, { target: window, eventName: "modifyinputfield", action: (e: CustomEvent) => onModifyInputField(e) }, { target: window, eventName: "focusout", action: () => (canvasFocused = false) }, - { target: window.document, eventName: "contextmenu", action: (e: MouseEvent) => e.preventDefault() }, + { target: window.document, eventName: "contextmenu", action: (e: MouseEvent) => onContextMenu(e) }, { target: window.document, eventName: "fullscreenchange", action: () => fullscreen.fullscreenModeChanged() }, { target: window.document.body, eventName: "paste", action: (e: ClipboardEvent) => onPaste(e) }, ]; @@ -154,7 +150,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document const { target } = e; const isTargetingCanvas = target instanceof Element && target.closest("[data-canvas]"); const inDialog = target instanceof Element && target.closest("[data-dialog-modal] [data-floating-menu-content]"); - const inTextInput = target === textInput; + const inTextInput = target === textToolInteractiveInputElement; if (get(dialog).visible && !inDialog) { dialog.dismissDialog(); @@ -163,7 +159,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document } if (!inTextInput) { - if (textInput) editor.instance.onChangeText(textInputCleanup(textInput.innerText)); + if (textToolInteractiveInputElement) editor.instance.onChangeText(textInputCleanup(textToolInteractiveInputElement.innerText)); else viewportPointerInteractionOngoing = isTargetingCanvas instanceof Element; } @@ -179,7 +175,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document function onPointerUp(e: PointerEvent): void { if (!e.buttons) viewportPointerInteractionOngoing = false; - if (!textInput) { + if (!textToolInteractiveInputElement) { const modifiers = makeKeyboardModifiersBitfield(e); editor.instance.onMouseUp(e.clientX, e.clientY, e.buttons, modifiers); } @@ -188,7 +184,7 @@ export function createInputManager(editor: Editor, dialog: DialogState, document function onDoubleClick(e: PointerEvent): void { if (!e.buttons) viewportPointerInteractionOngoing = false; - if (!textInput) { + if (!textToolInteractiveInputElement) { const modifiers = makeKeyboardModifiersBitfield(e); editor.instance.onDoubleClick(e.clientX, e.clientY, e.buttons, modifiers); } @@ -215,8 +211,16 @@ export function createInputManager(editor: Editor, dialog: DialogState, document } } + function onContextMenu(e: MouseEvent): void { + if (!targetIsTextField(e.target || undefined) && e.target !== textToolInteractiveInputElement) { + e.preventDefault(); + } + } + + // Receives a custom event dispatched when the user begins interactively editing with the text tool. + // We keep a copy of the text input element to check against when it's active for text entry. function onModifyInputField(e: CustomEvent): void { - textInput = e.detail; + textToolInteractiveInputElement = e.detail; } // Window events