mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 02:02:35 -05:00
Merge from vscode 91e99652cd5fcfc072387c64e151b435e39e8dcf (#6962)
This commit is contained in:
@@ -29,7 +29,8 @@ export interface ISplitViewOptions {
|
||||
readonly orthogonalStartSash?: Sash;
|
||||
readonly orthogonalEndSash?: Sash;
|
||||
readonly inverseAltBehavior?: boolean;
|
||||
readonly proportionalLayout?: boolean; // default true
|
||||
readonly proportionalLayout?: boolean; // default true,
|
||||
readonly descriptor?: ISplitViewDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,6 +198,15 @@ export namespace Sizing {
|
||||
export function Invisible(cachedVisibleSize: number): InvisibleSizing { return { type: 'invisible', cachedVisibleSize }; }
|
||||
}
|
||||
|
||||
export interface ISplitViewDescriptor {
|
||||
size: number;
|
||||
views: {
|
||||
visible?: boolean;
|
||||
size: number;
|
||||
view: IView;
|
||||
}[];
|
||||
}
|
||||
|
||||
export class SplitView extends Disposable {
|
||||
|
||||
readonly orientation: Orientation;
|
||||
@@ -272,6 +282,21 @@ export class SplitView extends Disposable {
|
||||
this.viewContainer = dom.append(this.el, dom.$('.split-view-container'));
|
||||
|
||||
this.style(options.styles || defaultStyles);
|
||||
|
||||
// We have an existing set of view, add them now
|
||||
if (options.descriptor) {
|
||||
this.size = options.descriptor.size;
|
||||
options.descriptor.views.forEach((viewDescriptor, index) => {
|
||||
const sizing = types.isUndefined(viewDescriptor.visible) || viewDescriptor.visible ? viewDescriptor.size : { type: 'invisible', cachedVisibleSize: viewDescriptor.size } as InvisibleSizing;
|
||||
|
||||
const view = viewDescriptor.view;
|
||||
this.doAddView(view, sizing, index, true);
|
||||
});
|
||||
|
||||
// Initialize content size and proportions for first layout
|
||||
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
this.saveProportions();
|
||||
}
|
||||
}
|
||||
|
||||
style(styles: ISplitViewStyles): void {
|
||||
@@ -285,102 +310,7 @@ export class SplitView extends Disposable {
|
||||
}
|
||||
|
||||
addView(view: IView, size: number | Sizing, index = this.viewItems.length): void {
|
||||
if (this.state !== State.Idle) {
|
||||
throw new Error('Cant modify splitview');
|
||||
}
|
||||
|
||||
this.state = State.Busy;
|
||||
|
||||
// Add view
|
||||
const container = dom.$('.split-view-view');
|
||||
|
||||
if (index === this.viewItems.length) {
|
||||
this.viewContainer.appendChild(container);
|
||||
} else {
|
||||
this.viewContainer.insertBefore(container, this.viewContainer.children.item(index));
|
||||
}
|
||||
|
||||
const onChangeDisposable = view.onDidChange(size => this.onViewChange(item, size));
|
||||
const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container));
|
||||
const disposable = combinedDisposable(onChangeDisposable, containerDisposable);
|
||||
|
||||
let viewSize: ViewItemSize;
|
||||
|
||||
if (typeof size === 'number') {
|
||||
viewSize = size;
|
||||
} else if (size.type === 'split') {
|
||||
viewSize = this.getViewSize(size.index) / 2;
|
||||
} else if (size.type === 'invisible') {
|
||||
viewSize = { cachedVisibleSize: size.cachedVisibleSize };
|
||||
} else {
|
||||
viewSize = view.minimumSize;
|
||||
}
|
||||
|
||||
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
|
||||
if (this.viewItems.length > 1) {
|
||||
const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL;
|
||||
const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: (sash: Sash) => this.getSashPosition(sash) } : { getVerticalSashLeft: (sash: Sash) => this.getSashPosition(sash) };
|
||||
const sash = new Sash(this.sashContainer, layoutProvider, {
|
||||
orientation,
|
||||
orthogonalStartSash: this.orthogonalStartSash,
|
||||
orthogonalEndSash: this.orthogonalEndSash
|
||||
});
|
||||
|
||||
const sashEventMapper = this.orientation === Orientation.VERTICAL
|
||||
? (e: IBaseSashEvent) => ({ sash, start: e.startY, current: e.currentY, alt: e.altKey })
|
||||
: (e: IBaseSashEvent) => ({ sash, start: e.startX, current: e.currentX, alt: e.altKey });
|
||||
|
||||
const onStart = Event.map(sash.onDidStart, sashEventMapper);
|
||||
const onStartDisposable = onStart(this.onSashStart, this);
|
||||
const onChange = Event.map(sash.onDidChange, sashEventMapper);
|
||||
const onChangeDisposable = onChange(this.onSashChange, this);
|
||||
const onEnd = Event.map(sash.onDidEnd, () => firstIndex(this.sashItems, item => item.sash === sash));
|
||||
const onEndDisposable = onEnd(this.onSashEnd, this);
|
||||
|
||||
const onDidResetDisposable = sash.onDidReset(() => {
|
||||
const index = firstIndex(this.sashItems, item => item.sash === sash);
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidSashReset.fire(index);
|
||||
});
|
||||
|
||||
const disposable = combinedDisposable(onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash);
|
||||
const sashItem: ISashItem = { sash, disposable };
|
||||
|
||||
this.sashItems.splice(index - 1, 0, sashItem);
|
||||
}
|
||||
|
||||
container.appendChild(view.element);
|
||||
|
||||
let highPriorityIndexes: number[] | undefined;
|
||||
|
||||
if (typeof size !== 'number' && size.type === 'split') {
|
||||
highPriorityIndexes = [size.index];
|
||||
}
|
||||
|
||||
this.relayout([index], highPriorityIndexes);
|
||||
this.state = State.Idle;
|
||||
|
||||
if (typeof size !== 'number' && size.type === 'distribute') {
|
||||
this.distributeViewSizes();
|
||||
}
|
||||
this.doAddView(view, size, index, false);
|
||||
}
|
||||
|
||||
removeView(index: number, sizing?: Sizing): IView {
|
||||
@@ -689,6 +619,108 @@ export class SplitView extends Disposable {
|
||||
return this.viewItems[index].size;
|
||||
}
|
||||
|
||||
private doAddView(view: IView, size: number | Sizing, index = this.viewItems.length, skipLayout?: boolean): void {
|
||||
if (this.state !== State.Idle) {
|
||||
throw new Error('Cant modify splitview');
|
||||
}
|
||||
|
||||
this.state = State.Busy;
|
||||
|
||||
// Add view
|
||||
const container = dom.$('.split-view-view');
|
||||
|
||||
if (index === this.viewItems.length) {
|
||||
this.viewContainer.appendChild(container);
|
||||
} else {
|
||||
this.viewContainer.insertBefore(container, this.viewContainer.children.item(index));
|
||||
}
|
||||
|
||||
const onChangeDisposable = view.onDidChange(size => this.onViewChange(item, size));
|
||||
const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container));
|
||||
const disposable = combinedDisposable(onChangeDisposable, containerDisposable);
|
||||
|
||||
let viewSize: ViewItemSize;
|
||||
|
||||
if (typeof size === 'number') {
|
||||
viewSize = size;
|
||||
} else if (size.type === 'split') {
|
||||
viewSize = this.getViewSize(size.index) / 2;
|
||||
} else if (size.type === 'invisible') {
|
||||
viewSize = { cachedVisibleSize: size.cachedVisibleSize };
|
||||
} else {
|
||||
viewSize = view.minimumSize;
|
||||
}
|
||||
|
||||
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
|
||||
if (this.viewItems.length > 1) {
|
||||
const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL;
|
||||
const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: (sash: Sash) => this.getSashPosition(sash) } : { getVerticalSashLeft: (sash: Sash) => this.getSashPosition(sash) };
|
||||
const sash = new Sash(this.sashContainer, layoutProvider, {
|
||||
orientation,
|
||||
orthogonalStartSash: this.orthogonalStartSash,
|
||||
orthogonalEndSash: this.orthogonalEndSash
|
||||
});
|
||||
|
||||
const sashEventMapper = this.orientation === Orientation.VERTICAL
|
||||
? (e: IBaseSashEvent) => ({ sash, start: e.startY, current: e.currentY, alt: e.altKey })
|
||||
: (e: IBaseSashEvent) => ({ sash, start: e.startX, current: e.currentX, alt: e.altKey });
|
||||
|
||||
const onStart = Event.map(sash.onDidStart, sashEventMapper);
|
||||
const onStartDisposable = onStart(this.onSashStart, this);
|
||||
const onChange = Event.map(sash.onDidChange, sashEventMapper);
|
||||
const onChangeDisposable = onChange(this.onSashChange, this);
|
||||
const onEnd = Event.map(sash.onDidEnd, () => firstIndex(this.sashItems, item => item.sash === sash));
|
||||
const onEndDisposable = onEnd(this.onSashEnd, this);
|
||||
|
||||
const onDidResetDisposable = sash.onDidReset(() => {
|
||||
const index = firstIndex(this.sashItems, item => item.sash === sash);
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidSashReset.fire(index);
|
||||
});
|
||||
|
||||
const disposable = combinedDisposable(onStartDisposable, onChangeDisposable, onEndDisposable, onDidResetDisposable, sash);
|
||||
const sashItem: ISashItem = { sash, disposable };
|
||||
|
||||
this.sashItems.splice(index - 1, 0, sashItem);
|
||||
}
|
||||
|
||||
container.appendChild(view.element);
|
||||
|
||||
let highPriorityIndexes: number[] | undefined;
|
||||
|
||||
if (typeof size !== 'number' && size.type === 'split') {
|
||||
highPriorityIndexes = [size.index];
|
||||
}
|
||||
|
||||
if (!skipLayout) {
|
||||
this.relayout([index], highPriorityIndexes);
|
||||
}
|
||||
|
||||
this.state = State.Idle;
|
||||
|
||||
if (!skipLayout && typeof size !== 'number' && size.type === 'distribute') {
|
||||
this.distributeViewSizes();
|
||||
}
|
||||
}
|
||||
|
||||
private relayout(lowPriorityIndexes?: number[], highPriorityIndexes?: number[]): void {
|
||||
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
|
||||
@@ -850,9 +882,12 @@ export class SplitView extends Disposable {
|
||||
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
|
||||
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
|
||||
|
||||
if (typeof snapBeforeIndex === 'number' && !this.viewItems[snapBeforeIndex].visible) {
|
||||
const snappedBefore = typeof snapBeforeIndex === 'number' && !this.viewItems[snapBeforeIndex].visible;
|
||||
const snappedAfter = typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible;
|
||||
|
||||
if (snappedBefore && collapsesUp[index]) {
|
||||
sash.state = SashState.Minimum;
|
||||
} else if (typeof snapAfterIndex === 'number' && !this.viewItems[snapAfterIndex].visible) {
|
||||
} else if (snappedAfter && collapsesDown[index]) {
|
||||
sash.state = SashState.Maximum;
|
||||
} else {
|
||||
sash.state = SashState.Disabled;
|
||||
|
||||
Reference in New Issue
Block a user