Path: blob/main/src/vs/base/browser/ui/resizable/resizable.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 { Dimension } from '../../dom.js';6import { Orientation, OrthogonalEdge, Sash, SashState } from '../sash/sash.js';7import { Emitter, Event } from '../../../common/event.js';8import { DisposableStore } from '../../../common/lifecycle.js';91011export interface IResizeEvent {12dimension: Dimension;13done: boolean;14north?: boolean;15east?: boolean;16south?: boolean;17west?: boolean;18}1920export class ResizableHTMLElement {2122readonly domNode: HTMLElement;2324private readonly _onDidWillResize = new Emitter<void>();25get onDidWillResize() { return this._onDidWillResize.event; }2627private readonly _onDidResize = new Emitter<IResizeEvent>();28get onDidResize() { return this._onDidResize.event; }2930private readonly _northSash: Sash;31private readonly _eastSash: Sash;32private readonly _southSash: Sash;33private readonly _westSash: Sash;34private readonly _sashListener = new DisposableStore();3536private _size = new Dimension(0, 0);37private _minSize = new Dimension(0, 0);38private _maxSize = new Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);39private _preferredSize?: Dimension;4041constructor() {42this.domNode = document.createElement('div');43this._eastSash = new Sash(this.domNode, { getVerticalSashLeft: () => this._size.width }, { orientation: Orientation.VERTICAL });44this._westSash = new Sash(this.domNode, { getVerticalSashLeft: () => 0 }, { orientation: Orientation.VERTICAL });45this._northSash = new Sash(this.domNode, { getHorizontalSashTop: () => 0 }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.North });46this._southSash = new Sash(this.domNode, { getHorizontalSashTop: () => this._size.height }, { orientation: Orientation.HORIZONTAL, orthogonalEdge: OrthogonalEdge.South });4748this._northSash.orthogonalStartSash = this._westSash;49this._northSash.orthogonalEndSash = this._eastSash;50this._southSash.orthogonalStartSash = this._westSash;51this._southSash.orthogonalEndSash = this._eastSash;5253let currentSize: Dimension | undefined;54let deltaY = 0;55let deltaX = 0;5657this._sashListener.add(Event.any(this._northSash.onDidStart, this._eastSash.onDidStart, this._southSash.onDidStart, this._westSash.onDidStart)(() => {58if (currentSize === undefined) {59this._onDidWillResize.fire();60currentSize = this._size;61deltaY = 0;62deltaX = 0;63}64}));65this._sashListener.add(Event.any(this._northSash.onDidEnd, this._eastSash.onDidEnd, this._southSash.onDidEnd, this._westSash.onDidEnd)(() => {66if (currentSize !== undefined) {67currentSize = undefined;68deltaY = 0;69deltaX = 0;70this._onDidResize.fire({ dimension: this._size, done: true });71}72}));7374this._sashListener.add(this._eastSash.onDidChange(e => {75if (currentSize) {76deltaX = e.currentX - e.startX;77this.layout(currentSize.height + deltaY, currentSize.width + deltaX);78this._onDidResize.fire({ dimension: this._size, done: false, east: true });79}80}));81this._sashListener.add(this._westSash.onDidChange(e => {82if (currentSize) {83deltaX = -(e.currentX - e.startX);84this.layout(currentSize.height + deltaY, currentSize.width + deltaX);85this._onDidResize.fire({ dimension: this._size, done: false, west: true });86}87}));88this._sashListener.add(this._northSash.onDidChange(e => {89if (currentSize) {90deltaY = -(e.currentY - e.startY);91this.layout(currentSize.height + deltaY, currentSize.width + deltaX);92this._onDidResize.fire({ dimension: this._size, done: false, north: true });93}94}));95this._sashListener.add(this._southSash.onDidChange(e => {96if (currentSize) {97deltaY = e.currentY - e.startY;98this.layout(currentSize.height + deltaY, currentSize.width + deltaX);99this._onDidResize.fire({ dimension: this._size, done: false, south: true });100}101}));102103this._sashListener.add(Event.any(this._eastSash.onDidReset, this._westSash.onDidReset)(e => {104if (this._preferredSize) {105this.layout(this._size.height, this._preferredSize.width);106this._onDidResize.fire({ dimension: this._size, done: true });107}108}));109this._sashListener.add(Event.any(this._northSash.onDidReset, this._southSash.onDidReset)(e => {110if (this._preferredSize) {111this.layout(this._preferredSize.height, this._size.width);112this._onDidResize.fire({ dimension: this._size, done: true });113}114}));115}116117dispose(): void {118this._northSash.dispose();119this._southSash.dispose();120this._eastSash.dispose();121this._westSash.dispose();122this._sashListener.dispose();123this._onDidResize.dispose();124this._onDidWillResize.dispose();125this.domNode.remove();126}127128enableSashes(north: boolean, east: boolean, south: boolean, west: boolean): void {129this._northSash.state = north ? SashState.Enabled : SashState.Disabled;130this._eastSash.state = east ? SashState.Enabled : SashState.Disabled;131this._southSash.state = south ? SashState.Enabled : SashState.Disabled;132this._westSash.state = west ? SashState.Enabled : SashState.Disabled;133}134135layout(height: number = this.size.height, width: number = this.size.width): void {136137const { height: minHeight, width: minWidth } = this._minSize;138const { height: maxHeight, width: maxWidth } = this._maxSize;139140height = Math.max(minHeight, Math.min(maxHeight, height));141width = Math.max(minWidth, Math.min(maxWidth, width));142143const newSize = new Dimension(width, height);144if (!Dimension.equals(newSize, this._size)) {145this.domNode.style.height = height + 'px';146this.domNode.style.width = width + 'px';147this._size = newSize;148this._northSash.layout();149this._eastSash.layout();150this._southSash.layout();151this._westSash.layout();152}153}154155clearSashHoverState(): void {156this._eastSash.clearSashHoverState();157this._westSash.clearSashHoverState();158this._northSash.clearSashHoverState();159this._southSash.clearSashHoverState();160}161162get size() {163return this._size;164}165166set maxSize(value: Dimension) {167this._maxSize = value;168}169170get maxSize() {171return this._maxSize;172}173174set minSize(value: Dimension) {175this._minSize = value;176}177178get minSize() {179return this._minSize;180}181182set preferredSize(value: Dimension | undefined) {183this._preferredSize = value;184}185186get preferredSize() {187return this._preferredSize;188}189}190191192