From 4f5c928f759bb71db803bc45b0d48c44e8bcf136 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 8 Jun 2018 16:08:26 +0200 Subject: [PATCH] sash: use linked sashes as arrays --- src/vs/base/browser/ui/grid/gridview.ts | 37 ++++---- src/vs/base/browser/ui/sash/sash.css | 16 ++-- src/vs/base/browser/ui/sash/sash.ts | 90 ++++++++++--------- src/vs/base/browser/ui/splitview/splitview.ts | 28 +++--- 4 files changed, 89 insertions(+), 82 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 1eca8960ca1..50e6e14a0f9 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -72,6 +72,10 @@ export interface IGridViewOptions { styles?: IGridViewStyles; } +function arrayIdentity(el: T): T[] { + return el ? [el] : []; +} + class BranchNode implements ISplitView, IDisposable { readonly element: HTMLElement; @@ -136,10 +140,10 @@ class BranchNode implements ISplitView, IDisposable { private splitviewSashResetDisposable: IDisposable = EmptyDisposable; private childrenSashResetDisposable: IDisposable = EmptyDisposable; - get orthogonalStartSash(): Sash | undefined { return this.splitview.orthogonalStartSash; } - set orthogonalStartSash(sash: Sash | undefined) { this.splitview.orthogonalStartSash = sash; } - get orthogonalEndSash(): Sash | undefined { return this.splitview.orthogonalEndSash; } - set orthogonalEndSash(sash: Sash | undefined) { this.splitview.orthogonalEndSash = sash; } + get linkedStartSashes(): Sash[] { return this.splitview.linkedStartSashes; } + set linkedStartSashes(sashes: Sash[]) { this.splitview.linkedStartSashes = sashes; } + get linkedEndSashes(): Sash[] { return this.splitview.linkedEndSashes; } + set linkedEndSashes(sashes: Sash[]) { this.splitview.linkedEndSashes = sashes; } constructor( readonly orientation: Orientation, @@ -195,15 +199,15 @@ class BranchNode implements ISplitView, IDisposable { const last = index === this.splitview.length; this.splitview.addView(node, size, index); this.children.splice(index, 0, node); - node.orthogonalStartSash = this.splitview.sashes[index - 1]; - node.orthogonalEndSash = this.splitview.sashes[index]; + node.linkedStartSashes = arrayIdentity(this.splitview.sashes[index - 1]); + node.linkedEndSashes = arrayIdentity(this.splitview.sashes[index]); if (!first) { - this.children[index - 1].orthogonalEndSash = this.splitview.sashes[index - 1]; + this.children[index - 1].linkedEndSashes = arrayIdentity(this.splitview.sashes[index - 1]); } if (!last) { - this.children[index + 1].orthogonalStartSash = this.splitview.sashes[index]; + this.children[index + 1].linkedStartSashes = arrayIdentity(this.splitview.sashes[index]); } this.onDidChildrenChange(); @@ -220,11 +224,11 @@ class BranchNode implements ISplitView, IDisposable { this.children.splice(index, 1); if (!first) { - this.children[index - 1].orthogonalEndSash = this.splitview.sashes[index - 1]; + this.children[index - 1].linkedEndSashes = arrayIdentity(this.splitview.sashes[index - 1]); } if (!last) { // [0,1,2,3] (2) => [0,1,3] - this.children[index].orthogonalStartSash = this.splitview.sashes[Math.max(index - 1, 0)]; + this.children[index].linkedStartSashes = arrayIdentity(this.splitview.sashes[Math.max(index - 1, 0)]); } this.onDidChildrenChange(); @@ -244,7 +248,7 @@ class BranchNode implements ISplitView, IDisposable { } this.splitview.swapViews(from, to); - [this.children[from].orthogonalStartSash, this.children[from].orthogonalEndSash, this.children[to].orthogonalStartSash, this.children[to].orthogonalEndSash] = [this.children[to].orthogonalStartSash, this.children[to].orthogonalEndSash, this.children[from].orthogonalStartSash, this.children[from].orthogonalEndSash]; + [this.children[from].linkedStartSashes, this.children[from].linkedEndSashes, this.children[to].linkedStartSashes, this.children[to].linkedEndSashes] = [this.children[to].linkedStartSashes, this.children[to].linkedEndSashes, this.children[from].linkedStartSashes, this.children[from].linkedEndSashes]; [this.children[from], this.children[to]] = [this.children[to], this.children[from]]; } @@ -342,13 +346,10 @@ class LeafNode implements ISplitView, IDisposable { return mapEvent(this.view.onDidChange, this.orientation === Orientation.HORIZONTAL ? ({ width }) => width : ({ height }) => height); } - set orthogonalStartSash(sash: Sash) { - // noop - } - - set orthogonalEndSash(sash: Sash) { - // noop - } + get linkedStartSashes(): Sash[] { return []; } + set linkedStartSashes(sashes: Sash[]) { } + get linkedEndSashes(): Sash[] { return []; } + set linkedEndSashes(sashes: Sash[]) { } layout(size: number): void { this._size = size; diff --git a/src/vs/base/browser/ui/sash/sash.css b/src/vs/base/browser/ui/sash/sash.css index 94ea3182c95..e7481be79e7 100644 --- a/src/vs/base/browser/ui/sash/sash.css +++ b/src/vs/base/browser/ui/sash/sash.css @@ -51,8 +51,8 @@ cursor: n-resize; } -.monaco-sash:not(.disabled).orthogonal-start::before, -.monaco-sash:not(.disabled).orthogonal-end::after { +.monaco-sash:not(.disabled).linked-start::before, +.monaco-sash:not(.disabled).linked-end::after { content: ' '; height: 8px; width: 8px; @@ -62,22 +62,22 @@ position: absolute; } -.monaco-sash.orthogonal-start.vertical::before { +.monaco-sash.linked-start.vertical::before { left: -2px; top: -4px; } -.monaco-sash.orthogonal-end.vertical::after { +.monaco-sash.linked-end.vertical::after { left: -2px; bottom: -4px; } -.monaco-sash.orthogonal-start.horizontal::before { +.monaco-sash.linked-start.horizontal::before { top: -2px; left: -4px; } -.monaco-sash.orthogonal-end.horizontal::after { +.monaco-sash.linked-end.horizontal::after { top: -2px; right: -4px; } @@ -102,7 +102,7 @@ background: cyan; } -.monaco-sash.debug:not(.disabled).orthogonal-start::before, -.monaco-sash.debug:not(.disabled).orthogonal-end::after { +.monaco-sash.debug:not(.disabled).linked-start::before, +.monaco-sash.debug:not(.disabled).linked-end::after { background: red; } \ No newline at end of file diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index dff485ab393..b6d6fbcc3cf 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -12,11 +12,11 @@ import { isMacintosh } from 'vs/base/common/platform'; import * as types from 'vs/base/common/types'; import { EventType, GestureEvent, Gesture } from 'vs/base/browser/touch'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Event, Emitter, anyEvent, mapEvent } from 'vs/base/common/event'; import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, Dimension, append, $, addClass, removeClass, toggleClass } from 'vs/base/browser/dom'; import { domEvent } from 'vs/base/browser/event'; -const DEBUG = false; +const DEBUG = true; export interface ISashLayoutProvider { } @@ -42,8 +42,8 @@ export interface ISashEvent { export interface ISashOptions { orientation?: Orientation; - orthogonalStartSash?: Sash; - orthogonalEndSash?: Sash; + linkedStartSashes?: Sash[]; + linkedEndSashes?: Sash[]; } export enum Orientation { @@ -96,36 +96,40 @@ export class Sash { private readonly _onDidEnd = new Emitter(); readonly onDidEnd: Event = this._onDidEnd.event; - private orthogonalStartSashDisposables: IDisposable[] = []; - private _orthogonalStartSash: Sash | undefined; - get orthogonalStartSash(): Sash | undefined { return this._orthogonalStartSash; } - set orthogonalStartSash(sash: Sash | undefined) { - this.orthogonalStartSashDisposables = dispose(this.orthogonalStartSashDisposables); + private linkedStartSashesDisposables: IDisposable[] = []; + private _linkedStartSashes: Sash[] = []; + get linkedStartSashes(): Sash[] { return this._linkedStartSashes; } + set linkedStartSashes(sashes: Sash[]) { + this.linkedStartSashesDisposables = dispose(this.linkedStartSashesDisposables); - if (sash) { - sash.onDidEnablementChange(this.onOrthogonalStartSashEnablementChange, this, this.orthogonalStartSashDisposables); - this.onOrthogonalStartSashEnablementChange(sash.state); + if (sashes.length > 0) { + mapEvent(anyEvent(...sashes.map(s => s.onDidEnablementChange)), () => sashes.map(s => s.state)) + (this.onLinkedStartSashEnablementChange, this, this.linkedStartSashesDisposables); + + this.onLinkedStartSashEnablementChange(sashes.map(s => s.state)); } else { - this.onOrthogonalStartSashEnablementChange(SashState.Disabled); + this.onLinkedStartSashEnablementChange([]); } - this._orthogonalStartSash = sash; + this._linkedStartSashes = sashes; } - private orthogonalEndSashDisposables: IDisposable[] = []; - private _orthogonalEndSash: Sash | undefined; - get orthogonalEndSash(): Sash | undefined { return this._orthogonalEndSash; } - set orthogonalEndSash(sash: Sash | undefined) { - this.orthogonalEndSashDisposables = dispose(this.orthogonalEndSashDisposables); + private linkedEndSashDisposables: IDisposable[] = []; + private _linkedEndSash: Sash[] = []; + get linkedEndSash(): Sash[] { return this._linkedEndSash; } + set linkedEndSash(sashes: Sash[]) { + this.linkedEndSashDisposables = dispose(this.linkedEndSashDisposables); + + if (sashes) { + mapEvent(anyEvent(...sashes.map(s => s.onDidEnablementChange)), () => sashes.map(s => s.state)) + (this.onLinkedEndSashEnablementChange, this, this.linkedEndSashDisposables); - if (sash) { - sash.onDidEnablementChange(this.onOrthogonalEndSashEnablementChange, this, this.orthogonalEndSashDisposables); - this.onOrthogonalEndSashEnablementChange(sash.state); + this.onLinkedEndSashEnablementChange(sashes.map(s => s.state)); } else { - this.onOrthogonalEndSashEnablementChange(SashState.Disabled); + this.onLinkedEndSashEnablementChange([]); } - this._orthogonalEndSash = sash; + this._linkedEndSash = sashes; } constructor(container: HTMLElement, layoutProvider: ISashLayoutProvider, options: ISashOptions = {}) { @@ -151,8 +155,8 @@ export class Sash { this.hidden = false; this.layoutProvider = layoutProvider; - this.orthogonalStartSash = options.orthogonalStartSash; - this.orthogonalEndSash = options.orthogonalEndSash; + this.linkedStartSashes = options.linkedStartSashes || []; + this.linkedEndSash = options.linkedEndSashes || []; toggleClass(this.el, 'debug', DEBUG); } @@ -178,27 +182,29 @@ export class Sash { let isMultisashResize = false; - if (!(e as any).__orthogonalSashEvent) { - let orthogonalSash: Sash | undefined; + if (!(e as any).__linkedSashEvent) { + let linkedSashes: Sash[] = []; if (this.orientation === Orientation.VERTICAL) { if (e.offsetY <= 4) { - orthogonalSash = this.orthogonalStartSash; + linkedSashes = this.linkedStartSashes; } else if (e.offsetY >= this.el.clientHeight - 4) { - orthogonalSash = this.orthogonalEndSash; + linkedSashes = this.linkedEndSash; } } else { if (e.offsetX <= 4) { - orthogonalSash = this.orthogonalStartSash; + linkedSashes = this.linkedStartSashes; } else if (e.offsetX >= this.el.clientWidth - 4) { - orthogonalSash = this.orthogonalEndSash; + linkedSashes = this.linkedEndSash; } } - if (orthogonalSash) { - isMultisashResize = true; - (e as any).__orthogonalSashEvent = true; - orthogonalSash.onMouseDown(e); + if (linkedSashes.length > 0) { + for (const sash of linkedSashes) { + isMultisashResize = true; + (e as any).__linkedSashEvent = true; + sash.onMouseDown(e); + } } } @@ -368,17 +374,17 @@ export class Sash { return this.hidden; } - private onOrthogonalStartSashEnablementChange(state: SashState): void { - toggleClass(this.el, 'orthogonal-start', state !== SashState.Disabled); + private onLinkedStartSashEnablementChange(states: SashState[]): void { + toggleClass(this.el, 'linked-start', states.some(state => state !== SashState.Disabled)); } - private onOrthogonalEndSashEnablementChange(state: SashState): void { - toggleClass(this.el, 'orthogonal-end', state !== SashState.Disabled); + private onLinkedEndSashEnablementChange(states: SashState[]): void { + toggleClass(this.el, 'linked-end', states.some(state => state !== SashState.Disabled)); } dispose(): void { - this.orthogonalStartSashDisposables = dispose(this.orthogonalStartSashDisposables); - this.orthogonalEndSashDisposables = dispose(this.orthogonalEndSashDisposables); + this.linkedStartSashesDisposables = dispose(this.linkedStartSashesDisposables); + this.linkedEndSashDisposables = dispose(this.linkedEndSashDisposables); if (this.el && this.el.parentElement) { this.el.parentElement.removeChild(this.el); diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 17de29c0a7d..757999209c2 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -27,8 +27,8 @@ const defaultStyles: ISplitViewStyles = { export interface ISplitViewOptions { orientation?: Orientation; // default Orientation.VERTICAL styles?: ISplitViewStyles; - orthogonalStartSash?: Sash; - orthogonalEndSash?: Sash; + linkedStartSash?: Sash; + linkedEndSash?: Sash; } export interface IView { @@ -139,24 +139,24 @@ export class SplitView implements IDisposable { return this.viewItems.length; } - private _orthogonalStartSash: Sash | undefined; - get orthogonalStartSash(): Sash | undefined { return this._orthogonalStartSash; } - set orthogonalStartSash(sash: Sash | undefined) { + private _linkedStartSashes: Sash[] = []; + get linkedStartSashes(): Sash[] { return this._linkedStartSashes; } + set linkedStartSashes(sashes: Sash[]) { for (const sashItem of this.sashItems) { - sashItem.sash.orthogonalStartSash = sash; + sashItem.sash.linkedStartSashes = sashes; } - this._orthogonalStartSash = sash; + this._linkedStartSashes = sashes; } - private _orthogonalEndSash: Sash | undefined; - get orthogonalEndSash(): Sash | undefined { return this._orthogonalEndSash; } - set orthogonalEndSash(sash: Sash | undefined) { + private _linkedEndSashes: Sash[] = []; + get linkedEndSashes(): Sash[] { return this._linkedEndSashes; } + set linkedEndSashes(sashes: Sash[]) { for (const sashItem of this.sashItems) { - sashItem.sash.orthogonalEndSash = sash; + sashItem.sash.linkedEndSash = sashes; } - this._orthogonalEndSash = sash; + this._linkedEndSashes = sashes; } get sashes(): Sash[] { @@ -235,8 +235,8 @@ export class SplitView implements IDisposable { const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: sash => this.getSashPosition(sash) } : { getVerticalSashLeft: sash => this.getSashPosition(sash) }; const sash = new Sash(this.sashContainer, layoutProvider, { orientation, - orthogonalStartSash: this.orthogonalStartSash, - orthogonalEndSash: this.orthogonalEndSash + linkedStartSashes: this.linkedStartSashes, + linkedEndSashes: this.linkedEndSashes }); const sashEventMapper = this.orientation === Orientation.VERTICAL ? (e: IBaseSashEvent) => ({ sash, start: e.startY, current: e.currentY }) -- GitLab