From 909c1538c2d6c7e08e0842d65f7c38e7e44fe287 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Fri, 17 Jan 2025 19:51:28 -0800 Subject: [PATCH] Respond to layout changes (#238189) * Respond to layout changes This seems to work fairly well. I think a follow up change I'll make is maybe redoing this to leverage CSS variables instead... like how it's done in the debugToolBar which looks cleaner, but that can come later. Fixes #237627 * use `onDidLayoutContainer` --- .../browser/quickInputController.ts | 96 +++++++++++-------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/src/vs/platform/quickinput/browser/quickInputController.ts b/src/vs/platform/quickinput/browser/quickInputController.ts index b9ff1f3ad472c..68c9a9cd8089a 100644 --- a/src/vs/platform/quickinput/browser/quickInputController.ts +++ b/src/vs/platform/quickinput/browser/quickInputController.ts @@ -908,6 +908,7 @@ class QuickInputDragAndDropController extends Disposable { @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(); + this._registerLayoutListener(); this.registerMouseListeners(); } @@ -936,9 +937,24 @@ class QuickInputDragAndDropController extends Disposable { } } + private _registerLayoutListener() { + this._layoutService.onDidLayoutContainer((e) => { + if (e.container !== this._container) { + return; + } + const state = this.dndViewState.get(); + const dragAreaRect = this._quickInputContainer.getBoundingClientRect(); + if (state?.top && state?.left) { + const a = Math.round(state.left * 1e2) / 1e2; + const b = e.dimension.width; + const c = dragAreaRect.width; + const d = a * b - c / 2; + this._layout(state.top * e.dimension.height, d); + } + }); + } + private registerMouseListeners(): void { - let top: number | undefined; - let left: number | undefined; const dragArea = this._quickInputContainer; // Double click @@ -953,10 +969,7 @@ class QuickInputDragAndDropController extends Disposable { return; } - top = undefined; - left = undefined; - - this.dndViewState.set({ top, left, done: true }, undefined); + this.dndViewState.set({ top: undefined, left: undefined, done: true }, undefined); })); // Mouse down @@ -974,13 +987,7 @@ class QuickInputDragAndDropController extends Disposable { const dragOffsetX = originEvent.browserEvent.clientX - dragAreaRect.left; const dragOffsetY = originEvent.browserEvent.clientY - dragAreaRect.top; - // Snap lines let isMovingQuickInput = false; - const snapCoordinateYTop = this._getTopSnapValue(); - const snapCoordinateY = this._getCenterYSnapValue(); - const snapCoordinateX = this._getCenterXSnapValue(); - - // Mouse move const mouseMoveListener = dom.addDisposableGenericMouseMoveListener(activeWindow, (e: MouseEvent) => { const mouseMoveEvent = new StandardMouseEvent(activeWindow, e); mouseMoveEvent.preventDefault(); @@ -989,36 +996,8 @@ class QuickInputDragAndDropController extends Disposable { isMovingQuickInput = true; } - let topCoordinate = e.clientY - dragOffsetY; - // Make sure the quick input is not moved outside the container - topCoordinate = Math.max(0, Math.min(topCoordinate, this._container.clientHeight - this._quickInputContainer.clientHeight)); - const snappingToTop = Math.abs(topCoordinate - snapCoordinateYTop) < this._snapThreshold; - topCoordinate = snappingToTop ? snapCoordinateYTop : topCoordinate; - const snappingToCenter = Math.abs(topCoordinate - snapCoordinateY) < this._snapThreshold; - topCoordinate = snappingToCenter ? snapCoordinateY : topCoordinate; - top = topCoordinate / this._container.clientHeight; - - let leftCoordinate = e.clientX - dragOffsetX; - // Make sure the quick input is not moved outside the container - leftCoordinate = Math.max(0, Math.min(leftCoordinate, this._container.clientWidth - this._quickInputContainer.clientWidth)); - const snappingToCenterX = Math.abs(leftCoordinate - snapCoordinateX) < this._snapThreshold; - leftCoordinate = snappingToCenterX ? snapCoordinateX : leftCoordinate; - left = (leftCoordinate + (this._quickInputContainer.clientWidth / 2)) / this._container.clientWidth; - - this.dndViewState.set({ top, left, done: false }, undefined); - if (snappingToCenterX) { - if (snappingToTop) { - this._quickInputAlignmentContext.set('top'); - return; - } else if (snappingToCenter) { - this._quickInputAlignmentContext.set('center'); - return; - } - } - this._quickInputAlignmentContext.set(undefined); + this._layout(e.clientY - dragOffsetY, e.clientX - dragOffsetX); }); - - // Mouse up const mouseUpListener = dom.addDisposableGenericMouseUpListener(activeWindow, (e: MouseEvent) => { if (isMovingQuickInput) { // Save position @@ -1033,6 +1012,41 @@ class QuickInputDragAndDropController extends Disposable { })); } + private _layout(topCoordinate: number, leftCoordinate: number) { + const snapCoordinateYTop = this._getTopSnapValue(); + const snapCoordinateY = this._getCenterYSnapValue(); + const snapCoordinateX = this._getCenterXSnapValue(); + // Make sure the quick input is not moved outside the container + topCoordinate = Math.max(0, Math.min(topCoordinate, this._container.clientHeight - this._quickInputContainer.clientHeight)); + const snappingToTop = Math.abs(topCoordinate - snapCoordinateYTop) < this._snapThreshold; + topCoordinate = snappingToTop ? snapCoordinateYTop : topCoordinate; + const snappingToCenter = Math.abs(topCoordinate - snapCoordinateY) < this._snapThreshold; + topCoordinate = snappingToCenter ? snapCoordinateY : topCoordinate; + const top = topCoordinate / this._container.clientHeight; + + // Make sure the quick input is not moved outside the container + leftCoordinate = Math.max(0, Math.min(leftCoordinate, this._container.clientWidth - this._quickInputContainer.clientWidth)); + const snappingToCenterX = Math.abs(leftCoordinate - snapCoordinateX) < this._snapThreshold; + leftCoordinate = snappingToCenterX ? snapCoordinateX : leftCoordinate; + + const b = this._container.clientWidth; + const c = this._quickInputContainer.clientWidth; + const d = leftCoordinate; + const left = (d + c / 2) / b; + + this.dndViewState.set({ top, left, done: false }, undefined); + if (snappingToCenterX) { + if (snappingToTop) { + this._quickInputAlignmentContext.set('top'); + return; + } else if (snappingToCenter) { + this._quickInputAlignmentContext.set('center'); + return; + } + } + this._quickInputAlignmentContext.set(undefined); + } + private _getTopSnapValue() { return this._layoutService.activeContainerOffset.quickPickTop; }