mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-11 05:30:03 -05:00
sash: use linked sashes as arrays
This commit is contained in:
@@ -72,6 +72,10 @@ export interface IGridViewOptions {
|
||||
styles?: IGridViewStyles;
|
||||
}
|
||||
|
||||
function arrayIdentity<T>(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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<void>();
|
||||
readonly onDidEnd: Event<void> = 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 (sash) {
|
||||
sash.onDidEnablementChange(this.onOrthogonalEndSashEnablementChange, this, this.orthogonalEndSashDisposables);
|
||||
this.onOrthogonalEndSashEnablementChange(sash.state);
|
||||
if (sashes) {
|
||||
mapEvent(anyEvent(...sashes.map(s => s.onDidEnablementChange)), () => sashes.map(s => s.state))
|
||||
(this.onLinkedEndSashEnablementChange, this, this.linkedEndSashDisposables);
|
||||
|
||||
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);
|
||||
|
||||
@@ -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 })
|
||||
|
||||
Reference in New Issue
Block a user