Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/browser/ui/resizable/resizable.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 { Dimension } from '../../dom.js';
7
import { Orientation, OrthogonalEdge, Sash, SashState } from '../sash/sash.js';
8
import { Emitter, Event } from '../../../common/event.js';
9
import { DisposableStore } from '../../../common/lifecycle.js';
10
11
12
export interface IResizeEvent {
13
dimension: Dimension;
14
done: boolean;
15
north?: boolean;
16
east?: boolean;
17
south?: boolean;
18
west?: boolean;
19
}
20
21
export class ResizableHTMLElement {
22
23
readonly domNode: HTMLElement;
24
25
private readonly _onDidWillResize = new Emitter<void>();
26
get onDidWillResize() { return this._onDidWillResize.event; }
27
28
private readonly _onDidResize = new Emitter<IResizeEvent>();
29
get onDidResize() { return this._onDidResize.event; }
30
31
private readonly _northSash: Sash;
32
private readonly _eastSash: Sash;
33
private readonly _southSash: Sash;
34
private readonly _westSash: Sash;
35
private readonly _sashListener = new DisposableStore();
36
37
private _size = new Dimension(0, 0);
38
private _minSize = new Dimension(0, 0);
39
private _maxSize = new Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
40
private _preferredSize?: Dimension;
41
42
constructor() {
43
this.domNode = document.createElement('div');
44
this._eastSash = new Sash(this.domNode, { getVerticalSashLeft: () => this._size.width }, { orientation: Orientation.VERTICAL });
45
this._westSash = new Sash(this.domNode, { getVerticalSashLeft: () => 0 }, { orientation: Orientation.VERTICAL });
46
this._northSash = new Sash(this.domNode, { getHorizontalSashTop: () => 0 }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.North });
47
this._southSash = new Sash(this.domNode, { getHorizontalSashTop: () => this._size.height }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.South });
48
49
this._northSash.orthogonalStartSash = this._westSash;
50
this._northSash.orthogonalEndSash = this._eastSash;
51
this._southSash.orthogonalStartSash = this._westSash;
52
this._southSash.orthogonalEndSash = this._eastSash;
53
54
let currentSize: Dimension | undefined;
55
let deltaY = 0;
56
let deltaX = 0;
57
58
this._sashListener.add(Event.any(this._northSash.onDidStart, this._eastSash.onDidStart, this._southSash.onDidStart, this._westSash.onDidStart)(() => {
59
if (currentSize === undefined) {
60
this._onDidWillResize.fire();
61
currentSize = this._size;
62
deltaY = 0;
63
deltaX = 0;
64
}
65
}));
66
this._sashListener.add(Event.any(this._northSash.onDidEnd, this._eastSash.onDidEnd, this._southSash.onDidEnd, this._westSash.onDidEnd)(() => {
67
if (currentSize !== undefined) {
68
currentSize = undefined;
69
deltaY = 0;
70
deltaX = 0;
71
this._onDidResize.fire({ dimension: this._size, done: true });
72
}
73
}));
74
75
this._sashListener.add(this._eastSash.onDidChange(e => {
76
if (currentSize) {
77
deltaX = e.currentX - e.startX;
78
this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
79
this._onDidResize.fire({ dimension: this._size, done: false, east: true });
80
}
81
}));
82
this._sashListener.add(this._westSash.onDidChange(e => {
83
if (currentSize) {
84
deltaX = -(e.currentX - e.startX);
85
this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
86
this._onDidResize.fire({ dimension: this._size, done: false, west: true });
87
}
88
}));
89
this._sashListener.add(this._northSash.onDidChange(e => {
90
if (currentSize) {
91
deltaY = -(e.currentY - e.startY);
92
this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
93
this._onDidResize.fire({ dimension: this._size, done: false, north: true });
94
}
95
}));
96
this._sashListener.add(this._southSash.onDidChange(e => {
97
if (currentSize) {
98
deltaY = e.currentY - e.startY;
99
this.layout(currentSize.height + deltaY, currentSize.width + deltaX);
100
this._onDidResize.fire({ dimension: this._size, done: false, south: true });
101
}
102
}));
103
104
this._sashListener.add(Event.any(this._eastSash.onDidReset, this._westSash.onDidReset)(e => {
105
if (this._preferredSize) {
106
this.layout(this._size.height, this._preferredSize.width);
107
this._onDidResize.fire({ dimension: this._size, done: true });
108
}
109
}));
110
this._sashListener.add(Event.any(this._northSash.onDidReset, this._southSash.onDidReset)(e => {
111
if (this._preferredSize) {
112
this.layout(this._preferredSize.height, this._size.width);
113
this._onDidResize.fire({ dimension: this._size, done: true });
114
}
115
}));
116
}
117
118
dispose(): void {
119
this._northSash.dispose();
120
this._southSash.dispose();
121
this._eastSash.dispose();
122
this._westSash.dispose();
123
this._sashListener.dispose();
124
this._onDidResize.dispose();
125
this._onDidWillResize.dispose();
126
this.domNode.remove();
127
}
128
129
enableSashes(north: boolean, east: boolean, south: boolean, west: boolean): void {
130
this._northSash.state = north ? SashState.Enabled : SashState.Disabled;
131
this._eastSash.state = east ? SashState.Enabled : SashState.Disabled;
132
this._southSash.state = south ? SashState.Enabled : SashState.Disabled;
133
this._westSash.state = west ? SashState.Enabled : SashState.Disabled;
134
}
135
136
layout(height: number = this.size.height, width: number = this.size.width): void {
137
138
const { height: minHeight, width: minWidth } = this._minSize;
139
const { height: maxHeight, width: maxWidth } = this._maxSize;
140
141
height = Math.max(minHeight, Math.min(maxHeight, height));
142
width = Math.max(minWidth, Math.min(maxWidth, width));
143
144
const newSize = new Dimension(width, height);
145
if (!Dimension.equals(newSize, this._size)) {
146
this.domNode.style.height = height + 'px';
147
this.domNode.style.width = width + 'px';
148
this._size = newSize;
149
this._northSash.layout();
150
this._eastSash.layout();
151
this._southSash.layout();
152
this._westSash.layout();
153
}
154
}
155
156
clearSashHoverState(): void {
157
this._eastSash.clearSashHoverState();
158
this._westSash.clearSashHoverState();
159
this._northSash.clearSashHoverState();
160
this._southSash.clearSashHoverState();
161
}
162
163
get size() {
164
return this._size;
165
}
166
167
set maxSize(value: Dimension) {
168
this._maxSize = value;
169
}
170
171
get maxSize() {
172
return this._maxSize;
173
}
174
175
set minSize(value: Dimension) {
176
this._minSize = value;
177
}
178
179
get minSize() {
180
return this._minSize;
181
}
182
183
set preferredSize(value: Dimension | undefined) {
184
this._preferredSize = value;
185
}
186
187
get preferredSize() {
188
return this._preferredSize;
189
}
190
}
191
192