Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e8e8e8" d="M6 4v8l4-4-4-4zm1 2.414l1.586 1.586-1.586 1.586v-3.172z"/></svg>

Before

Width:  |  Height:  |  Size: 151 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#646465" d="M6 4v8l4-4-4-4zm1 2.414l1.586 1.586-1.586 1.586v-3.172z"/></svg>

Before

Width:  |  Height:  |  Size: 151 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e8e8e8" d="M11 10.07h-5.656l5.656-5.656v5.656z"/></svg>

Before

Width:  |  Height:  |  Size: 131 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#646465" d="M11 10.07h-5.656l5.656-5.656v5.656z"/></svg>

Before

Width:  |  Height:  |  Size: 131 B

View File

@@ -27,23 +27,31 @@
}
.monaco-panel-view .panel > .panel-header {
background-image: url('arrow-collapse.svg');
background-image: url('tree-collapsed-light.svg');
background-position: 2px center;
background-repeat: no-repeat;
}
.monaco-panel-view .panel > .panel-header.expanded {
background-image: url('arrow-expand.svg');
background-image: url('tree-expanded-light.svg');
background-position: 2px center;
background-repeat: no-repeat;
}
.vs-dark .monaco-panel-view .panel > .panel-header {
background-image: url('arrow-collapse-dark.svg');
background-image: url('tree-collapsed-dark.svg');
}
.vs-dark .monaco-panel-view .panel > .panel-header.expanded {
background-image: url('arrow-expand-dark.svg');
background-image: url('tree-expanded-dark.svg');
}
.hc-black .monaco-panel-view .panel > .panel-header {
background-image: url('tree-collapsed-hc.svg');
}
.hc-black .monaco-panel-view .panel > .panel-header.expanded {
background-image: url('tree-expanded-hc.svg');
}
/* TODO: actions should be part of the panel, but they aren't yet */

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./panelview';
import { IDisposable, dispose, combinedDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
@@ -37,7 +37,7 @@ export interface IPanelStyles {
* Subclasses wouldn't be able to set own properties
* before the `render()` call, thus forbiding their use.
*/
export abstract class Panel implements IView {
export abstract class Panel extends Disposable implements IView {
private static readonly HEADER_SIZE = 22;
@@ -55,11 +55,9 @@ export abstract class Panel implements IView {
private styles: IPanelStyles = {};
private animationTimer: number | undefined = undefined;
private _onDidChange = new Emitter<number | undefined>();
private readonly _onDidChange = this._register(new Emitter<number | undefined>());
readonly onDidChange: Event<number | undefined> = this._onDidChange.event;
protected disposables: IDisposable[] = [];
get draggableElement(): HTMLElement {
return this.header;
}
@@ -114,6 +112,7 @@ export abstract class Panel implements IView {
width: number;
constructor(options: IPanelOptions = {}) {
super();
this._expanded = typeof options.expanded === 'undefined' ? true : !!options.expanded;
this.ariaHeaderLabel = options.ariaHeaderLabel || '';
this._minimumBodySize = typeof options.minimumBodySize === 'number' ? options.minimumBodySize : 120;
@@ -172,26 +171,26 @@ export abstract class Panel implements IView {
this.renderHeader(this.header);
const focusTracker = trackFocus(this.header);
this.disposables.push(focusTracker);
focusTracker.onDidFocus(() => addClass(this.header, 'focused'), null, this.disposables);
focusTracker.onDidBlur(() => removeClass(this.header, 'focused'), null, this.disposables);
this._register(focusTracker);
this._register(focusTracker.onDidFocus(() => addClass(this.header, 'focused'), null));
this._register(focusTracker.onDidBlur(() => removeClass(this.header, 'focused'), null));
this.updateHeader();
const onHeaderKeyDown = Event.chain(domEvent(this.header, 'keydown'))
.map(e => new StandardKeyboardEvent(e));
onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space)
.event(() => this.setExpanded(!this.isExpanded()), null, this.disposables);
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space)
.event(() => this.setExpanded(!this.isExpanded()), null));
onHeaderKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow)
.event(() => this.setExpanded(false), null, this.disposables);
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow)
.event(() => this.setExpanded(false), null));
onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow)
.event(() => this.setExpanded(true), null, this.disposables);
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow)
.event(() => this.setExpanded(true), null));
domEvent(this.header, 'click')
(() => this.setExpanded(!this.isExpanded()), null, this.disposables);
this._register(domEvent(this.header, 'click')
(() => this.setExpanded(!this.isExpanded()), null));
this.body = append(this.element, $('.panel-body'));
this.renderBody(this.body);
@@ -234,12 +233,6 @@ export abstract class Panel implements IView {
protected abstract renderHeader(container: HTMLElement): void;
protected abstract renderBody(container: HTMLElement): void;
protected abstract layoutBody(height: number, width: number): void;
dispose(): void {
this.disposables = dispose(this.disposables);
this._onDidChange.dispose();
}
}
interface IDndContext {
@@ -397,24 +390,24 @@ export class PanelView extends Disposable {
}
addPanel(panel: Panel, size: number, index = this.splitview.length): void {
const disposables: IDisposable[] = [];
const disposables = new DisposableStore();
// https://github.com/Microsoft/vscode/issues/59950
let shouldAnimate = false;
disposables.push(scheduleAtNextAnimationFrame(() => shouldAnimate = true));
disposables.add(scheduleAtNextAnimationFrame(() => shouldAnimate = true));
Event.filter(panel.onDidChange, () => shouldAnimate)
(this.setupAnimation, this, disposables);
disposables.add(Event.filter(panel.onDidChange, () => shouldAnimate)
(this.setupAnimation, this));
const panelItem = { panel, disposable: combinedDisposable(disposables) };
const panelItem = { panel, disposable: disposables };
this.panelItems.splice(index, 0, panelItem);
panel.width = this.width;
this.splitview.addView(panel, size, index);
if (this.dnd) {
const draggable = new PanelDraggable(panel, this.dnd, this.dndContext);
disposables.push(draggable);
draggable.onDidDrop(this._onDidDrop.fire, this._onDidDrop, disposables);
disposables.add(draggable);
disposables.add(draggable.onDidDrop(this._onDidDrop.fire, this._onDidDrop));
}
}

View File

@@ -41,6 +41,10 @@
position: relative;
}
.monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) {
display: none;
}
.monaco-split-view2.vertical > .split-view-container > .split-view-view {
width: 100%;
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./splitview';
import { IDisposable, combinedDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IDisposable, toDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import * as types from 'vs/base/common/types';
import * as dom from 'vs/base/browser/dom';
@@ -47,7 +47,9 @@ export interface IView {
readonly maximumSize: number;
readonly onDidChange: Event<number | undefined>;
readonly priority?: LayoutPriority;
readonly snap?: boolean;
layout(size: number, orientation: Orientation): void;
setVisible?(visible: boolean): void;
}
interface ISashEvent {
@@ -57,12 +59,81 @@ interface ISashEvent {
alt: boolean;
}
interface IViewItem {
view: IView;
size: number;
container: HTMLElement;
disposable: IDisposable;
layout(): void;
abstract class ViewItem {
set size(size: number) {
this._size = size;
}
get size(): number {
return this._size;
}
private cachedSize: number | undefined = undefined;
get visible(): boolean {
return typeof this.cachedSize === 'undefined';
}
set visible(visible: boolean) {
if (visible === this.visible) {
return;
}
if (visible) {
this.size = this.cachedSize!;
this.cachedSize = undefined;
} else {
this.cachedSize = this.size;
this.size = 0;
}
dom.toggleClass(this.container, 'visible', visible);
if (this.view.setVisible) {
this.view.setVisible(visible);
}
}
get minimumSize(): number { return this.visible ? this.view.minimumSize : 0; }
get viewMinimumSize(): number { return this.view.minimumSize; }
get maximumSize(): number { return this.visible ? this.view.maximumSize : 0; }
get viewMaximumSize(): number { return this.view.maximumSize; }
get priority(): LayoutPriority | undefined { return this.view.priority; }
get snap(): boolean { return !!this.view.snap; }
constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) {
dom.addClass(container, 'visible');
}
abstract layout(): void;
layoutView(orientation: Orientation): void {
this.view.layout(this.size, orientation);
}
dispose(): IView {
this.disposable.dispose();
return this.view;
}
}
class VerticalViewItem extends ViewItem {
layout(): void {
this.container.style.height = `${this.size}px`;
this.layoutView(Orientation.VERTICAL);
}
}
class HorizontalViewItem extends ViewItem {
layout(): void {
this.container.style.width = `${this.size}px`;
this.layoutView(Orientation.HORIZONTAL);
}
}
interface ISashItem {
@@ -70,6 +141,11 @@ interface ISashItem {
disposable: IDisposable;
}
interface ISashDragSnapState {
readonly index: number;
readonly limitDelta: number;
}
interface ISashDragState {
index: number;
start: number;
@@ -78,6 +154,8 @@ interface ISashDragState {
minDelta: number;
maxDelta: number;
alt: boolean;
snapBefore: ISashDragSnapState | undefined;
snapAfter: ISashDragSnapState | undefined;
disposable: IDisposable;
}
@@ -104,7 +182,7 @@ export class SplitView extends Disposable {
private size = 0;
private contentSize = 0;
private proportions: undefined | number[] = undefined;
private viewItems: IViewItem[] = [];
private viewItems: ViewItem[] = [];
private sashItems: ISashItem[] = [];
private sashDragState: ISashDragState;
private state: State = State.Idle;
@@ -122,11 +200,11 @@ export class SplitView extends Disposable {
}
get minimumSize(): number {
return this.viewItems.reduce((r, item) => r + item.view.minimumSize, 0);
return this.viewItems.reduce((r, item) => r + item.minimumSize, 0);
}
get maximumSize(): number {
return this.length === 0 ? Number.POSITIVE_INFINITY : this.viewItems.reduce((r, item) => r + item.view.maximumSize, 0);
return this.length === 0 ? Number.POSITIVE_INFINITY : this.viewItems.reduce((r, item) => r + item.maximumSize, 0);
}
private _orthogonalStartSash: Sash | undefined;
@@ -199,16 +277,7 @@ export class SplitView extends Disposable {
const onChangeDisposable = view.onDidChange(size => this.onViewChange(item, size));
const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container));
const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
const layoutContainer = this.orientation === Orientation.VERTICAL
? () => item.container.style.height = `${item.size}px`
: () => item.container.style.width = `${item.size}px`;
const layout = () => {
layoutContainer();
item.view.layout(item.size, this.orientation);
};
const disposable = combinedDisposable(onChangeDisposable, containerDisposable);
let viewSize: number;
@@ -220,7 +289,10 @@ export class SplitView extends Disposable {
viewSize = view.minimumSize;
}
const item: IViewItem = { view, container, size: viewSize, layout, disposable };
const item = this.orientation === Orientation.VERTICAL
? new VerticalViewItem(container, view, viewSize, disposable)
: new HorizontalViewItem(container, view, viewSize, disposable);
this.viewItems.splice(index, 0, item);
// Add sash
@@ -245,7 +317,7 @@ export class SplitView extends Disposable {
const onEndDisposable = onEnd(this.onSashEnd, this);
const onDidResetDisposable = sash.onDidReset(() => this._onDidSashReset.fire(firstIndex(this.sashItems, item => item.sash === sash)));
const disposable = combinedDisposable([onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash]);
const disposable = combinedDisposable(onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash);
const sashItem: ISashItem = { sash, disposable };
this.sashItems.splice(index - 1, 0, sashItem);
@@ -280,7 +352,7 @@ export class SplitView extends Disposable {
// Remove view
const viewItem = this.viewItems.splice(index, 1)[0];
viewItem.disposable.dispose();
const view = viewItem.dispose();
// Remove sash
if (this.viewItems.length >= 1) {
@@ -296,7 +368,7 @@ export class SplitView extends Disposable {
this.distributeViewSizes();
}
return viewItem.view;
return view;
}
moveView(from: number, to: number): void {
@@ -327,6 +399,27 @@ export class SplitView extends Disposable {
this.addView(fromView, toSize, to);
}
isViewVisible(index: number): boolean {
if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
const viewItem = this.viewItems[index];
return viewItem.visible;
}
setViewVisible(index: number, visible: boolean): void {
if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
const viewItem = this.viewItems[index];
viewItem.visible = visible;
this.distributeEmptySpace(index);
this.layoutViews();
}
private relayout(lowPriorityIndex?: number, highPriorityIndex?: number): void {
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
const lowPriorityIndexes = typeof lowPriorityIndex === 'number' ? [lowPriorityIndex] : undefined;
@@ -344,14 +437,14 @@ export class SplitView extends Disposable {
if (!this.proportions) {
const indexes = range(this.viewItems.length);
const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.Low);
const highPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.High);
const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.Low);
const highPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.High);
this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
} else {
for (let i = 0; i < this.viewItems.length; i++) {
const item = this.viewItems[i];
item.size = clamp(Math.round(this.proportions[i] * size), item.view.minimumSize, item.view.maximumSize);
item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize);
}
}
@@ -369,10 +462,10 @@ export class SplitView extends Disposable {
const index = firstIndex(this.sashItems, item => item.sash === sash);
// This way, we can press Alt while we resize a sash, macOS style!
const disposable = combinedDisposable([
const disposable = combinedDisposable(
domEvent(document.body, 'keydown')(e => resetSashDragState(this.sashDragState.current, e.altKey)),
domEvent(document.body, 'keyup')(() => resetSashDragState(this.sashDragState.current, false))
]);
);
const resetSashDragState = (start: number, alt: boolean) => {
const sizes = this.viewItems.map(i => i.size);
@@ -391,35 +484,71 @@ export class SplitView extends Disposable {
if (isLastSash) {
const viewItem = this.viewItems[index];
minDelta = (viewItem.view.minimumSize - viewItem.size) / 2;
maxDelta = (viewItem.view.maximumSize - viewItem.size) / 2;
minDelta = (viewItem.minimumSize - viewItem.size) / 2;
maxDelta = (viewItem.maximumSize - viewItem.size) / 2;
} else {
const viewItem = this.viewItems[index + 1];
minDelta = (viewItem.size - viewItem.view.maximumSize) / 2;
maxDelta = (viewItem.size - viewItem.view.minimumSize) / 2;
minDelta = (viewItem.size - viewItem.maximumSize) / 2;
maxDelta = (viewItem.size - viewItem.minimumSize) / 2;
}
}
this.sashDragState = { start, current: start, index, sizes, minDelta, maxDelta, alt, disposable };
let snapBefore: ISashDragSnapState | undefined;
let snapAfter: ISashDragSnapState | undefined;
if (!alt) {
const upIndexes = range(index, -1);
const downIndexes = range(index + 1, this.viewItems.length);
const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0);
const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].viewMaximumSize - sizes[i]), 0);
const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].minimumSize), 0);
const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].viewMaximumSize), 0);
const minDelta = Math.max(minDeltaUp, minDeltaDown);
const maxDelta = Math.min(maxDeltaDown, maxDeltaUp);
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
if (typeof snapBeforeIndex === 'number') {
const viewItem = this.viewItems[snapBeforeIndex];
const halfSize = Math.floor(viewItem.viewMinimumSize / 2);
snapBefore = {
index: snapBeforeIndex,
limitDelta: viewItem.visible ? minDelta - halfSize : minDelta + halfSize
};
}
if (typeof snapAfterIndex === 'number') {
const viewItem = this.viewItems[snapAfterIndex];
const halfSize = Math.floor(viewItem.viewMinimumSize / 2);
snapAfter = {
index: snapAfterIndex,
limitDelta: viewItem.visible ? maxDelta + halfSize : maxDelta - halfSize
};
}
}
this.sashDragState = { start, current: start, index, sizes, minDelta, maxDelta, alt, snapBefore, snapAfter, disposable };
};
resetSashDragState(start, alt);
}
private onSashChange({ current }: ISashEvent): void {
const { index, start, sizes, alt, minDelta, maxDelta } = this.sashDragState;
const { index, start, sizes, alt, minDelta, maxDelta, snapBefore, snapAfter } = this.sashDragState;
this.sashDragState.current = current;
const delta = current - start;
const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta);
const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
if (alt) {
const isLastSash = index === this.sashItems.length - 1;
const newSizes = this.viewItems.map(i => i.size);
const viewItemIndex = isLastSash ? index : index + 1;
const viewItem = this.viewItems[viewItemIndex];
const newMinDelta = viewItem.size - viewItem.view.maximumSize;
const newMaxDelta = viewItem.size - viewItem.view.minimumSize;
const newMinDelta = viewItem.size - viewItem.maximumSize;
const newMaxDelta = viewItem.size - viewItem.minimumSize;
const resizeIndex = isLastSash ? index - 1 : index + 1;
this.resize(resizeIndex, -newDelta, newSizes, undefined, undefined, newMinDelta, newMaxDelta);
@@ -435,7 +564,7 @@ export class SplitView extends Disposable {
this.saveProportions();
}
private onViewChange(item: IViewItem, size: number | undefined): void {
private onViewChange(item: ViewItem, size: number | undefined): void {
const index = this.viewItems.indexOf(item);
if (index < 0 || index >= this.viewItems.length) {
@@ -443,7 +572,7 @@ export class SplitView extends Disposable {
}
size = typeof size === 'number' ? size : item.size;
size = clamp(size, item.view.minimumSize, item.view.maximumSize);
size = clamp(size, item.minimumSize, item.maximumSize);
if (this.inverseAltBehavior && index > 0) {
// In this case, we want the view to grow or shrink both sides equally
@@ -470,13 +599,13 @@ export class SplitView extends Disposable {
const item = this.viewItems[index];
size = Math.round(size);
size = clamp(size, item.view.minimumSize, item.view.maximumSize);
size = clamp(size, item.minimumSize, item.maximumSize);
let delta = size - item.size;
if (delta !== 0 && index < this.viewItems.length - 1) {
const downIndexes = range(index + 1, this.viewItems.length);
const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].view.minimumSize), 0);
const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - this.viewItems[i].size), 0);
const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0);
const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0);
const deltaDown = clamp(delta, -expandDown, collapseDown);
this.resize(index, deltaDown);
@@ -485,8 +614,8 @@ export class SplitView extends Disposable {
if (delta !== 0 && index > 0) {
const upIndexes = range(index - 1, -1);
const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].view.minimumSize), 0);
const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - this.viewItems[i].size), 0);
const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0);
const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0);
const deltaUp = clamp(-delta, -collapseUp, expandUp);
this.resize(index - 1, deltaUp);
@@ -521,7 +650,9 @@ export class SplitView extends Disposable {
lowPriorityIndexes?: number[],
highPriorityIndexes?: number[],
overloadMinDelta: number = Number.NEGATIVE_INFINITY,
overloadMaxDelta: number = Number.POSITIVE_INFINITY
overloadMaxDelta: number = Number.POSITIVE_INFINITY,
snapBefore?: ISashDragSnapState,
snapAfter?: ISashDragSnapState
): number {
if (index < 0 || index >= this.viewItems.length) {
return 0;
@@ -550,18 +681,38 @@ export class SplitView extends Disposable {
const downItems = downIndexes.map(i => this.viewItems[i]);
const downSizes = downIndexes.map(i => sizes[i]);
const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.minimumSize - sizes[i]), 0);
const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - sizes[i]), 0);
const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.minimumSize), 0);
const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.maximumSize), 0);
const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0);
const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - sizes[i]), 0);
const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].minimumSize), 0);
const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].maximumSize), 0);
const minDelta = Math.max(minDeltaUp, minDeltaDown, overloadMinDelta);
const maxDelta = Math.min(maxDeltaDown, maxDeltaUp, overloadMaxDelta);
let snapped = false;
if (snapBefore) {
const snapView = this.viewItems[snapBefore.index];
const visible = delta >= snapBefore.limitDelta;
snapped = visible !== snapView.visible;
snapView.visible = visible;
}
if (!snapped && snapAfter) {
const snapView = this.viewItems[snapAfter.index];
const visible = delta < snapAfter.limitDelta;
snapped = visible !== snapView.visible;
snapView.visible = visible;
}
if (snapped) {
return this.resize(index, delta, sizes, lowPriorityIndexes, highPriorityIndexes, overloadMinDelta, overloadMaxDelta);
}
delta = clamp(delta, minDelta, maxDelta);
for (let i = 0, deltaUp = delta; i < upItems.length; i++) {
const item = upItems[i];
const size = clamp(upSizes[i] + deltaUp, item.view.minimumSize, item.view.maximumSize);
const size = clamp(upSizes[i] + deltaUp, item.minimumSize, item.maximumSize);
const viewDelta = size - upSizes[i];
deltaUp -= viewDelta;
@@ -570,7 +721,7 @@ export class SplitView extends Disposable {
for (let i = 0, deltaDown = delta; i < downItems.length; i++) {
const item = downItems[i];
const size = clamp(downSizes[i] - deltaDown, item.view.minimumSize, item.view.maximumSize);
const size = clamp(downSizes[i] - deltaDown, item.minimumSize, item.maximumSize);
const viewDelta = size - downSizes[i];
deltaDown += viewDelta;
@@ -580,13 +731,19 @@ export class SplitView extends Disposable {
return delta;
}
private distributeEmptySpace(): void {
let contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
private distributeEmptySpace(lowPriorityIndex?: number): void {
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
let emptyDelta = this.size - contentSize;
for (let i = this.viewItems.length - 1; emptyDelta !== 0 && i >= 0; i--) {
const item = this.viewItems[i];
const size = clamp(item.size + emptyDelta, item.view.minimumSize, item.view.maximumSize);
const indexes = range(this.viewItems.length - 1, -1);
if (typeof lowPriorityIndex === 'number') {
pushToEnd(indexes, lowPriorityIndex);
}
for (let i = 0; emptyDelta !== 0 && i < indexes.length; i++) {
const item = this.viewItems[indexes[i]];
const size = clamp(item.size + emptyDelta, item.minimumSize, item.maximumSize);
const viewDelta = size - item.size;
emptyDelta -= viewDelta;
@@ -606,31 +763,43 @@ export class SplitView extends Disposable {
// Update sashes enablement
let previous = false;
const collapsesDown = this.viewItems.map(i => previous = (i.size - i.view.minimumSize > 0) || previous);
const collapsesDown = this.viewItems.map(i => previous = (i.size - i.minimumSize > 0) || previous);
previous = false;
const expandsDown = this.viewItems.map(i => previous = (i.view.maximumSize - i.size > 0) || previous);
const expandsDown = this.viewItems.map(i => previous = (i.maximumSize - i.size > 0) || previous);
const reverseViews = [...this.viewItems].reverse();
previous = false;
const collapsesUp = reverseViews.map(i => previous = (i.size - i.view.minimumSize > 0) || previous).reverse();
const collapsesUp = reverseViews.map(i => previous = (i.size - i.minimumSize > 0) || previous).reverse();
previous = false;
const expandsUp = reverseViews.map(i => previous = (i.view.maximumSize - i.size > 0) || previous).reverse();
const expandsUp = reverseViews.map(i => previous = (i.maximumSize - i.size > 0) || previous).reverse();
this.sashItems.forEach((s, i) => {
const min = !(collapsesDown[i] && expandsUp[i + 1]);
const max = !(expandsDown[i] && collapsesUp[i + 1]);
this.sashItems.forEach(({ sash }, index) => {
const min = !(collapsesDown[index] && expandsUp[index + 1]);
const max = !(expandsDown[index] && collapsesUp[index + 1]);
if (min && max) {
s.sash.state = SashState.Disabled;
const upIndexes = range(index, -1);
const downIndexes = range(index + 1, this.viewItems.length);
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
if (typeof snapBeforeIndex === 'number' && !this.viewItems[snapBeforeIndex].visible) {
sash.state = SashState.Minimum;
} else if (typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible) {
sash.state = SashState.Maximum;
} else {
sash.state = SashState.Disabled;
}
} else if (min && !max) {
s.sash.state = SashState.Minimum;
sash.state = SashState.Minimum;
} else if (!min && max) {
s.sash.state = SashState.Maximum;
sash.state = SashState.Maximum;
} else {
s.sash.state = SashState.Enabled;
sash.state = SashState.Enabled;
}
// }
});
}
@@ -648,10 +817,32 @@ export class SplitView extends Disposable {
return 0;
}
private findFirstSnapIndex(indexes: number[]): number | undefined {
// visible views first
for (const index of indexes) {
if (!this.viewItems[index].visible) {
continue;
}
if (this.viewItems[index].snap) {
return index;
}
}
// then, hidden views
for (const index of indexes) {
if (!this.viewItems[index].visible && this.viewItems[index].snap) {
return index;
}
}
return undefined;
}
dispose(): void {
super.dispose();
this.viewItems.forEach(i => i.disposable.dispose());
this.viewItems.forEach(i => i.dispose());
this.viewItems = [];
this.sashItems.forEach(i => i.disposable.dispose());

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0719 7.99999L5.71461 12.3573L6.33333 12.976L11 8.30935V7.69064L6.33333 3.02397L5.71461 3.64269L10.0719 7.99999Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0719 7.99999L5.71461 12.3573L6.33333 12.976L11 8.30935V7.69063L6.33333 3.02396L5.71461 3.64268L10.0719 7.99999Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 284 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0719 7.99999L5.71461 12.3573L6.33333 12.976L11 8.30935V7.69063L6.33333 3.02396L5.71461 3.64268L10.0719 7.99999Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 286 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.97603 10.0719L12.3333 5.71461L12.9521 6.33333L8.28539 11L7.66667 11L3 6.33333L3.61872 5.71461L7.97603 10.0719Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 284 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.97603 10.0719L12.3333 5.71461L12.9521 6.33333L8.28539 11L7.66667 11L3 6.33333L3.61872 5.71461L7.97603 10.0719Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.97603 10.0719L12.3333 5.71461L12.9521 6.33333L8.28539 11L7.66667 11L3 6.33333L3.61872 5.71461L7.97603 10.0719Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 284 B