From e07ae76bd2b710ef0e113463d8ffff50831711ac Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 1 Jul 2021 16:14:13 +0200 Subject: [PATCH 1/2] Expose editor scrollbar options and react to them being updated --- .../browser/ui/scrollbar/abstractScrollbar.ts | 2 +- .../ui/scrollbar/horizontalScrollbar.ts | 7 ++ .../browser/ui/scrollbar/scrollableElement.ts | 20 ++++-- .../ui/scrollbar/scrollableElementOptions.ts | 4 ++ .../browser/ui/scrollbar/scrollbarState.ts | 8 ++- .../scrollbarVisibilityController.ts | 22 ++++-- .../browser/ui/scrollbar/verticalScrollbar.ts | 9 +++ .../editorScrollbar/editorScrollbar.ts | 5 ++ src/vs/editor/common/config/editorOptions.ts | 67 +++++++++++++++---- 9 files changed, 119 insertions(+), 25 deletions(-) diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index f6e5e7d31a9..926fb0ca103 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -48,7 +48,7 @@ export abstract class AbstractScrollbar extends Widget { protected _scrollByPage: boolean; private _lazyRender: boolean; protected _scrollbarState: ScrollbarState; - private _visibilityController: ScrollbarVisibilityController; + protected _visibilityController: ScrollbarVisibilityController; private _mouseMoveMonitor: GlobalMouseMoveMonitor; public domNode: FastDomNode; diff --git a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts index 7246630ee75..553d5f8a7c2 100644 --- a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts @@ -107,4 +107,11 @@ export class HorizontalScrollbar extends AbstractScrollbar { public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void { target.scrollLeft = scrollPosition; } + + public updateOptions(options: ScrollableElementResolvedOptions): void { + this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.Hidden ? 0 : options.horizontalScrollbarSize); + this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); + this._visibilityController.setVisibility(options.horizontal); + this._scrollByPage = options.scrollByPage; + } } diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index bb4476f11b3..217f13fb01e 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -288,8 +288,6 @@ export abstract class AbstractScrollableElement extends Widget { /** * Update configuration options for the scrollbar. - * Really this is Editor.IEditorScrollbarOptions, but base shouldn't - * depend on Editor. */ public updateOptions(newOptions: ScrollableElementChangeOptions): void { if (typeof newOptions.handleMouseWheel !== 'undefined') { @@ -305,9 +303,23 @@ export abstract class AbstractScrollableElement extends Widget { if (typeof newOptions.scrollPredominantAxis !== 'undefined') { this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis; } - if (typeof newOptions.horizontalScrollbarSize !== 'undefined') { - this._horizontalScrollbar.updateScrollbarSize(newOptions.horizontalScrollbarSize); + if (typeof newOptions.horizontal !== 'undefined') { + this._options.horizontal = newOptions.horizontal; } + if (typeof newOptions.vertical !== 'undefined') { + this._options.vertical = newOptions.vertical; + } + if (typeof newOptions.horizontalScrollbarSize !== 'undefined') { + this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize; + } + if (typeof newOptions.verticalScrollbarSize !== 'undefined') { + this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize; + } + if (typeof newOptions.scrollByPage !== 'undefined') { + this._options.scrollByPage = newOptions.scrollByPage; + } + this._horizontalScrollbar.updateOptions(this._options); + this._verticalScrollbar.updateOptions(this._options); if (!this._options.lazyRender) { this._render(); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts b/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts index 22387bdad33..8e75751fff3 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts @@ -131,7 +131,11 @@ export interface ScrollableElementChangeOptions { mouseWheelScrollSensitivity?: number; fastScrollSensitivity?: number; scrollPredominantAxis?: boolean; + horizontal?: ScrollbarVisibility; horizontalScrollbarSize?: number; + vertical?: ScrollbarVisibility; + verticalScrollbarSize?: number; + scrollByPage?: boolean; } export interface ScrollableElementResolvedOptions { diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts index 51590286822..9a4f4e2cbbd 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts @@ -20,7 +20,7 @@ export class ScrollbarState { * For the vertical scrollbar: the height of the pair horizontal scrollbar. * For the horizontal scrollbar: the width of the pair vertical scrollbar. */ - private readonly _oppositeScrollbarSize: number; + private _oppositeScrollbarSize: number; /** * For the vertical scrollbar: the height of the scrollbar's arrows. @@ -115,7 +115,11 @@ export class ScrollbarState { } public setScrollbarSize(scrollbarSize: number): void { - this._scrollbarSize = scrollbarSize; + this._scrollbarSize = Math.round(scrollbarSize); + } + + public setOppositeScrollbarSize(oppositeScrollbarSize: number): void { + this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize); } private static _computeValues(oppositeScrollbarSize: number, arrowSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) { diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts index 35d82adbdeb..3c4a40b824f 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts @@ -13,6 +13,7 @@ export class ScrollbarVisibilityController extends Disposable { private _visibleClassName: string; private _invisibleClassName: string; private _domNode: FastDomNode | null; + private _rawShouldBeVisible: boolean; private _shouldBeVisible: boolean; private _isNeeded: boolean; private _isVisible: boolean; @@ -26,24 +27,37 @@ export class ScrollbarVisibilityController extends Disposable { this._domNode = null; this._isVisible = false; this._isNeeded = false; + this._rawShouldBeVisible = false; this._shouldBeVisible = false; this._revealTimer = this._register(new TimeoutTimer()); } + public setVisibility(visibility: ScrollbarVisibility): void { + if (this._visibility !== visibility) { + this._visibility = visibility; + this._updateShouldBeVisible(); + } + } + // ----------------- Hide / Reveal - private applyVisibilitySetting(shouldBeVisible: boolean): boolean { + public setShouldBeVisible(rawShouldBeVisible: boolean): void { + this._rawShouldBeVisible = rawShouldBeVisible; + this._updateShouldBeVisible(); + } + + private _applyVisibilitySetting(): boolean { if (this._visibility === ScrollbarVisibility.Hidden) { return false; } if (this._visibility === ScrollbarVisibility.Visible) { return true; } - return shouldBeVisible; + return this._rawShouldBeVisible; } - public setShouldBeVisible(rawShouldBeVisible: boolean): void { - const shouldBeVisible = this.applyVisibilitySetting(rawShouldBeVisible); + private _updateShouldBeVisible(): void { + const shouldBeVisible = this._applyVisibilitySetting(); if (this._shouldBeVisible !== shouldBeVisible) { this._shouldBeVisible = shouldBeVisible; diff --git a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts index 6088d2169db..1ccaaf9a78c 100644 --- a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts @@ -107,4 +107,13 @@ export class VerticalScrollbar extends AbstractScrollbar { public writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void { target.scrollTop = scrollPosition; } + + public updateOptions(options: ScrollableElementResolvedOptions): void { + this.updateScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); + // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom + this._scrollbarState.setOppositeScrollbarSize(0); + this._visibilityController.setVisibility(options.vertical); + this._scrollByPage = options.scrollByPage; + } + } diff --git a/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts b/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts index ff87634259f..b7025539667 100644 --- a/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts +++ b/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts @@ -145,6 +145,11 @@ export class EditorScrollbar extends ViewPart { const fastScrollSensitivity = options.get(EditorOption.fastScrollSensitivity); const scrollPredominantAxis = options.get(EditorOption.scrollPredominantAxis); const newOpts: ScrollableElementChangeOptions = { + vertical: scrollbar.vertical, + horizontal: scrollbar.horizontal, + verticalScrollbarSize: scrollbar.verticalScrollbarSize, + horizontalScrollbarSize: scrollbar.horizontalScrollbarSize, + scrollByPage: scrollbar.scrollByPage, handleMouseWheel: scrollbar.handleMouseWheel, mouseWheelScrollSensitivity: mouseWheelScrollSensitivity, fastScrollSensitivity: fastScrollSensitivity, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 687064cdd2e..04969e86467 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -3101,22 +3101,61 @@ function _scrollbarVisibilityFromString(visibility: string | undefined, defaultV class EditorScrollbar extends BaseEditorOption { constructor() { + const defaults: InternalEditorScrollbarOptions = { + vertical: ScrollbarVisibility.Auto, + horizontal: ScrollbarVisibility.Auto, + arrowSize: 11, + useShadows: true, + verticalHasArrows: false, + horizontalHasArrows: false, + horizontalScrollbarSize: 12, + horizontalSliderSize: 12, + verticalScrollbarSize: 14, + verticalSliderSize: 14, + handleMouseWheel: true, + alwaysConsumeMouseWheel: true, + scrollByPage: false + }; super( - EditorOption.scrollbar, 'scrollbar', + EditorOption.scrollbar, 'scrollbar', defaults, { - vertical: ScrollbarVisibility.Auto, - horizontal: ScrollbarVisibility.Auto, - arrowSize: 11, - useShadows: true, - verticalHasArrows: false, - horizontalHasArrows: false, - horizontalScrollbarSize: 12, - horizontalSliderSize: 12, - verticalScrollbarSize: 14, - verticalSliderSize: 14, - handleMouseWheel: true, - alwaysConsumeMouseWheel: true, - scrollByPage: false + 'editor.scrollbar.vertical': { + type: 'string', + enum: ['auto', 'visible', 'hidden'], + enumDescriptions: [ + nls.localize('scrollbar.vertical.auto', "The vertical scrollbar will be visible only when necessary."), + nls.localize('scrollbar.vertical.visible', "The vertical scrollbar will always be visible."), + nls.localize('scrollbar.vertical.fit', "The vertical scrollbar will always be hidden."), + ], + default: 'auto', + description: nls.localize('scrollbar.vertical', "Controls the visibility of the vertical scrollbar.") + }, + 'editor.scrollbar.horizontal': { + type: 'string', + enum: ['auto', 'visible', 'hidden'], + enumDescriptions: [ + nls.localize('scrollbar.horizontal.auto', "The horizontal scrollbar will be visible only when necessary."), + nls.localize('scrollbar.horizontal.visible', "The horizontal scrollbar will always be visible."), + nls.localize('scrollbar.horizontal.fit', "The horizontal scrollbar will always be hidden."), + ], + default: 'auto', + description: nls.localize('scrollbar.horizontal', "Controls the visibility of the horizontal scrollbar.") + }, + 'editor.scrollbar.verticalScrollbarSize': { + type: 'number', + default: defaults.verticalScrollbarSize, + description: nls.localize('scrollbar.verticalScrollbarSize', "The width of the vertical scrollbar.") + }, + 'editor.scrollbar.horizontalScrollbarSize': { + type: 'number', + default: defaults.horizontalScrollbarSize, + description: nls.localize('scrollbar.horizontalScrollbarSize', "The height of the horizontal scrollbar.") + }, + 'editor.scrollbar.scrollByPage': { + type: 'boolean', + default: defaults.scrollByPage, + description: nls.localize('scrollbar.scrollByPage', "Controls whether clicks scroll by page or jump to click position.") + } } ); } From 790d8a8d11d9582217b4cfe118458d0012dd5047 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 1 Jul 2021 16:28:43 +0200 Subject: [PATCH 2/2] Clarify which scrollbar options cannot be updated --- src/vs/editor/common/config/editorOptions.ts | 7 +++++++ src/vs/monaco.d.ts | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 04969e86467..744be53a75a 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -3007,6 +3007,7 @@ export interface IEditorScrollbarOptions { /** * The size of arrows (if displayed). * Defaults to 11. + * **NOTE**: This option cannot be updated using `updateOptions()` */ arrowSize?: number; /** @@ -3022,16 +3023,19 @@ export interface IEditorScrollbarOptions { /** * Cast horizontal and vertical shadows when the content is scrolled. * Defaults to true. + * **NOTE**: This option cannot be updated using `updateOptions()` */ useShadows?: boolean; /** * Render arrows at the top and bottom of the vertical scrollbar. * Defaults to false. + * **NOTE**: This option cannot be updated using `updateOptions()` */ verticalHasArrows?: boolean; /** * Render arrows at the left and right of the horizontal scrollbar. * Defaults to false. + * **NOTE**: This option cannot be updated using `updateOptions()` */ horizontalHasArrows?: boolean; /** @@ -3042,6 +3046,7 @@ export interface IEditorScrollbarOptions { /** * Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events). * Defaults to true. + * **NOTE**: This option cannot be updated using `updateOptions()` */ alwaysConsumeMouseWheel?: boolean; /** @@ -3057,11 +3062,13 @@ export interface IEditorScrollbarOptions { /** * Width in pixels for the vertical slider. * Defaults to `verticalScrollbarSize`. + * **NOTE**: This option cannot be updated using `updateOptions()` */ verticalSliderSize?: number; /** * Height in pixels for the horizontal slider. * Defaults to `horizontalScrollbarSize`. + * **NOTE**: This option cannot be updated using `updateOptions()` */ horizontalSliderSize?: number; /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 8d9f8bd0dd5..8f4f5fb594b 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3756,6 +3756,7 @@ declare namespace monaco.editor { /** * The size of arrows (if displayed). * Defaults to 11. + * **NOTE**: This option cannot be updated using `updateOptions()` */ arrowSize?: number; /** @@ -3771,16 +3772,19 @@ declare namespace monaco.editor { /** * Cast horizontal and vertical shadows when the content is scrolled. * Defaults to true. + * **NOTE**: This option cannot be updated using `updateOptions()` */ useShadows?: boolean; /** * Render arrows at the top and bottom of the vertical scrollbar. * Defaults to false. + * **NOTE**: This option cannot be updated using `updateOptions()` */ verticalHasArrows?: boolean; /** * Render arrows at the left and right of the horizontal scrollbar. * Defaults to false. + * **NOTE**: This option cannot be updated using `updateOptions()` */ horizontalHasArrows?: boolean; /** @@ -3791,6 +3795,7 @@ declare namespace monaco.editor { /** * Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events). * Defaults to true. + * **NOTE**: This option cannot be updated using `updateOptions()` */ alwaysConsumeMouseWheel?: boolean; /** @@ -3806,11 +3811,13 @@ declare namespace monaco.editor { /** * Width in pixels for the vertical slider. * Defaults to `verticalScrollbarSize`. + * **NOTE**: This option cannot be updated using `updateOptions()` */ verticalSliderSize?: number; /** * Height in pixels for the horizontal slider. * Defaults to `horizontalScrollbarSize`. + * **NOTE**: This option cannot be updated using `updateOptions()` */ horizontalSliderSize?: number; /**