Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { FastDomNode } from '../../fastDomNode.js';
7
import { TimeoutTimer } from '../../../common/async.js';
8
import { Disposable } from '../../../common/lifecycle.js';
9
import { ScrollbarVisibility } from '../../../common/scrollable.js';
10
11
export class ScrollbarVisibilityController extends Disposable {
12
private _visibility: ScrollbarVisibility;
13
private _visibleClassName: string;
14
private _invisibleClassName: string;
15
private _domNode: FastDomNode<HTMLElement> | null;
16
private _rawShouldBeVisible: boolean;
17
private _shouldBeVisible: boolean;
18
private _isNeeded: boolean;
19
private _isVisible: boolean;
20
private _revealTimer: TimeoutTimer;
21
22
constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {
23
super();
24
this._visibility = visibility;
25
this._visibleClassName = visibleClassName;
26
this._invisibleClassName = invisibleClassName;
27
this._domNode = null;
28
this._isVisible = false;
29
this._isNeeded = false;
30
this._rawShouldBeVisible = false;
31
this._shouldBeVisible = false;
32
this._revealTimer = this._register(new TimeoutTimer());
33
}
34
35
public setVisibility(visibility: ScrollbarVisibility): void {
36
if (this._visibility !== visibility) {
37
this._visibility = visibility;
38
this._updateShouldBeVisible();
39
}
40
}
41
42
// ----------------- Hide / Reveal
43
44
public setShouldBeVisible(rawShouldBeVisible: boolean): void {
45
this._rawShouldBeVisible = rawShouldBeVisible;
46
this._updateShouldBeVisible();
47
}
48
49
private _applyVisibilitySetting(): boolean {
50
if (this._visibility === ScrollbarVisibility.Hidden) {
51
return false;
52
}
53
if (this._visibility === ScrollbarVisibility.Visible) {
54
return true;
55
}
56
return this._rawShouldBeVisible;
57
}
58
59
private _updateShouldBeVisible(): void {
60
const shouldBeVisible = this._applyVisibilitySetting();
61
62
if (this._shouldBeVisible !== shouldBeVisible) {
63
this._shouldBeVisible = shouldBeVisible;
64
this.ensureVisibility();
65
}
66
}
67
68
public setIsNeeded(isNeeded: boolean): void {
69
if (this._isNeeded !== isNeeded) {
70
this._isNeeded = isNeeded;
71
this.ensureVisibility();
72
}
73
}
74
75
public setDomNode(domNode: FastDomNode<HTMLElement>): void {
76
this._domNode = domNode;
77
this._domNode.setClassName(this._invisibleClassName);
78
79
// Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration
80
this.setShouldBeVisible(false);
81
}
82
83
public ensureVisibility(): void {
84
85
if (!this._isNeeded) {
86
// Nothing to be rendered
87
this._hide(false);
88
return;
89
}
90
91
if (this._shouldBeVisible) {
92
this._reveal();
93
} else {
94
this._hide(true);
95
}
96
}
97
98
private _reveal(): void {
99
if (this._isVisible) {
100
return;
101
}
102
this._isVisible = true;
103
104
// The CSS animation doesn't play otherwise
105
this._revealTimer.setIfNotSet(() => {
106
this._domNode?.setClassName(this._visibleClassName);
107
}, 0);
108
}
109
110
private _hide(withFadeAway: boolean): void {
111
this._revealTimer.cancel();
112
if (!this._isVisible) {
113
return;
114
}
115
this._isVisible = false;
116
this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));
117
}
118
}
119
120