From ec8e55c1c1bb0ae42e8216f5070efcf82baf86b8 Mon Sep 17 00:00:00 2001 From: filtered <176114999+webfiltered@users.noreply.github.com> Date: Sun, 13 Apr 2025 03:13:00 +1000 Subject: [PATCH] Allow zooming inside multi-line string widgets (#3422) Co-authored-by: github-actions --- src/composables/widgets/useStringWidget.ts | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/composables/widgets/useStringWidget.ts b/src/composables/widgets/useStringWidget.ts index f3bf67bac..d5298338e 100644 --- a/src/composables/widgets/useStringWidget.ts +++ b/src/composables/widgets/useStringWidget.ts @@ -35,6 +35,7 @@ function addMultilineWidget( widget.callback?.(widget.value) }) + // Allow middle mouse button panning inputEl.addEventListener('pointerdown', (event: PointerEvent) => { if (event.button === 1) { app.canvas.processMouseDown(event) @@ -53,6 +54,40 @@ function addMultilineWidget( } }) + /** Timer reference. `null` when the timer completes. */ + let ignoreEventsTimer: ReturnType | null = null + /** Total number of events ignored since the timer started. */ + let ignoredEvents = 0 + + // Pass wheel events to the canvas when appropriate + inputEl.addEventListener('wheel', (event: WheelEvent) => { + if (!Object.is(event.deltaX, -0)) return + + // If the textarea has focus, require more effort to activate pass-through + const multiplier = document.activeElement === inputEl ? 2 : 1 + const maxScrollHeight = inputEl.scrollHeight - inputEl.clientHeight + + if ( + (event.deltaY < 0 && inputEl.scrollTop === 0) || + (event.deltaY > 0 && inputEl.scrollTop === maxScrollHeight) + ) { + // Attempting to scroll past the end of the textarea + if (!ignoreEventsTimer || ignoredEvents > 25 * multiplier) { + app.canvas.processMouseWheel(event) + } else { + ignoredEvents++ + } + } else if (event.deltaY !== 0) { + // Start timer whenever a successful scroll occurs + ignoredEvents = 0 + if (ignoreEventsTimer) clearTimeout(ignoreEventsTimer) + + ignoreEventsTimer = setTimeout(() => { + ignoreEventsTimer = null + }, 800 * multiplier) + } + }) + return widget }