Path: blob/main/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { FastDomNode } from '../../fastDomNode.js';6import { TimeoutTimer } from '../../../common/async.js';7import { Disposable } from '../../../common/lifecycle.js';8import { ScrollbarVisibility } from '../../../common/scrollable.js';910export class ScrollbarVisibilityController extends Disposable {11private _visibility: ScrollbarVisibility;12private _visibleClassName: string;13private _invisibleClassName: string;14private _domNode: FastDomNode<HTMLElement> | null;15private _rawShouldBeVisible: boolean;16private _shouldBeVisible: boolean;17private _isNeeded: boolean;18private _isVisible: boolean;19private _revealTimer: TimeoutTimer;2021constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {22super();23this._visibility = visibility;24this._visibleClassName = visibleClassName;25this._invisibleClassName = invisibleClassName;26this._domNode = null;27this._isVisible = false;28this._isNeeded = false;29this._rawShouldBeVisible = false;30this._shouldBeVisible = false;31this._revealTimer = this._register(new TimeoutTimer());32}3334public setVisibility(visibility: ScrollbarVisibility): void {35if (this._visibility !== visibility) {36this._visibility = visibility;37this._updateShouldBeVisible();38}39}4041// ----------------- Hide / Reveal4243public setShouldBeVisible(rawShouldBeVisible: boolean): void {44this._rawShouldBeVisible = rawShouldBeVisible;45this._updateShouldBeVisible();46}4748private _applyVisibilitySetting(): boolean {49if (this._visibility === ScrollbarVisibility.Hidden) {50return false;51}52if (this._visibility === ScrollbarVisibility.Visible) {53return true;54}55return this._rawShouldBeVisible;56}5758private _updateShouldBeVisible(): void {59const shouldBeVisible = this._applyVisibilitySetting();6061if (this._shouldBeVisible !== shouldBeVisible) {62this._shouldBeVisible = shouldBeVisible;63this.ensureVisibility();64}65}6667public setIsNeeded(isNeeded: boolean): void {68if (this._isNeeded !== isNeeded) {69this._isNeeded = isNeeded;70this.ensureVisibility();71}72}7374public setDomNode(domNode: FastDomNode<HTMLElement>): void {75this._domNode = domNode;76this._domNode.setClassName(this._invisibleClassName);7778// Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration79this.setShouldBeVisible(false);80}8182public ensureVisibility(): void {8384if (!this._isNeeded) {85// Nothing to be rendered86this._hide(false);87return;88}8990if (this._shouldBeVisible) {91this._reveal();92} else {93this._hide(true);94}95}9697private _reveal(): void {98if (this._isVisible) {99return;100}101this._isVisible = true;102103// The CSS animation doesn't play otherwise104this._revealTimer.setIfNotSet(() => {105this._domNode?.setClassName(this._visibleClassName);106}, 0);107}108109private _hide(withFadeAway: boolean): void {110this._revealTimer.cancel();111if (!this._isVisible) {112return;113}114this._isVisible = false;115this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));116}117}118119120