mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-09 09:42:34 -05:00
Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)
* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 * disable strict null check
This commit is contained in:
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user