Merge from vscode 91e99652cd5fcfc072387c64e151b435e39e8dcf (#6962)

This commit is contained in:
Anthony Dresser
2019-08-26 15:58:42 -07:00
committed by GitHub
parent edf470c8fa
commit 507bae90b7
103 changed files with 1743 additions and 1543 deletions

View File

@@ -34,6 +34,36 @@ export interface IView {
setVisible?(visible: boolean): void;
}
export interface ISerializableView extends IView {
toJSON(): object;
}
export interface IViewDeserializer<T extends ISerializableView> {
fromJSON(json: any): T;
}
export interface ISerializedLeafNode {
type: 'leaf';
data: any;
size: number;
visible?: boolean;
}
export interface ISerializedBranchNode {
type: 'branch';
data: ISerializedNode[];
size: number;
}
export type ISerializedNode = ISerializedLeafNode | ISerializedBranchNode;
export interface ISerializedGridView {
root: ISerializedNode;
orientation: Orientation;
width: number;
height: number;
}
export function orthogonal(orientation: Orientation): Orientation {
return orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL;
}
@@ -179,18 +209,49 @@ class BranchNode implements ISplitView, IDisposable {
styles: IGridViewStyles,
readonly proportionalLayout: boolean,
size: number = 0,
orthogonalSize: number = 0
orthogonalSize: number = 0,
childDescriptors?: INodeDescriptor[]
) {
this._styles = styles;
this._size = size;
this._orthogonalSize = orthogonalSize;
this.element = $('.monaco-grid-branch-node');
this.splitview = new SplitView(this.element, { orientation, styles, proportionalLayout });
this.splitview.layout(size, orthogonalSize);
if (!childDescriptors) {
// Normal behavior, we have no children yet, just set up the splitview
this.splitview = new SplitView(this.element, { orientation, styles, proportionalLayout });
this.splitview.layout(size, orthogonalSize);
} else {
// Reconstruction behavior, we want to reconstruct a splitview
const descriptor = {
views: childDescriptors.map(childDescriptor => {
return {
view: childDescriptor.node,
size: childDescriptor.node.size,
visible: childDescriptor.node instanceof LeafNode && childDescriptor.visible !== undefined ? childDescriptor.visible : true
};
}),
size: this.orthogonalSize
};
const options = { proportionalLayout, orientation, styles };
this.children = childDescriptors.map(c => c.node);
this.splitview = new SplitView(this.element, { ...options, descriptor });
this.children.forEach((node, index) => {
// Set up orthogonal sashes for children
node.orthogonalStartSash = this.splitview.sashes[index - 1];
node.orthogonalEndSash = this.splitview.sashes[index];
});
}
const onDidSashReset = Event.map(this.splitview.onDidSashReset, i => [i]);
this.splitviewSashResetDisposable = onDidSashReset(this._onDidSashReset.fire, this._onDidSashReset);
const onDidChildrenSashReset = Event.any(...this.children.map((c, i) => Event.map(c.onDidSashReset, location => [i, ...location])));
this.childrenSashResetDisposable = onDidChildrenSashReset(this._onDidSashReset.fire, this._onDidSashReset);
}
style(styles: IGridViewStyles): void {
@@ -226,7 +287,7 @@ class BranchNode implements ISplitView, IDisposable {
}
}
addChild(node: Node, size: number | Sizing, index: number): void {
addChild(node: Node, size: number | Sizing, index: number, skipLayout?: boolean): void {
if (index < 0 || index > this.children.length) {
throw new Error('Invalid index');
}
@@ -484,9 +545,11 @@ class LeafNode implements ISplitView, IDisposable {
readonly view: IView,
readonly orientation: Orientation,
readonly layoutController: ILayoutController,
orthogonalSize: number
orthogonalSize: number,
size: number = 0
) {
this._orthogonalSize = orthogonalSize;
this._size = size;
this._onDidViewChange = Event.map(this.view.onDidChange, e => e && (this.orientation === Orientation.VERTICAL ? e.width : e.height));
this.onDidChange = Event.any(this._onDidViewChange, this._onDidSetLinkedNode.event, this._onDidLinkedWidthNodeChange.event, this._onDidLinkedHeightNodeChange.event);
@@ -577,6 +640,11 @@ class LeafNode implements ISplitView, IDisposable {
type Node = BranchNode | LeafNode;
export interface INodeDescriptor {
node: Node;
visible?: boolean;
}
function flipNode<T extends Node>(node: T, size: number, orthogonalSize: number): T {
if (node instanceof BranchNode) {
const result = new BranchNode(orthogonal(node.orientation), node.layoutController, node.styles, node.proportionalLayout, size, orthogonalSize);
@@ -680,6 +748,18 @@ export class GridView implements IDisposable {
this.root = new BranchNode(Orientation.VERTICAL, this.layoutController, this.styles, this.proportionalLayout);
}
getViewMap(map: Map<IView, HTMLElement>, node?: Node): void {
if (!node) {
node = this.root;
}
if (node instanceof BranchNode) {
node.children.forEach(child => this.getViewMap(map, child));
} else {
map.set(node.view, node.element);
}
}
style(styles: IGridViewStyles): void {
this.styles = styles;
this.root.style(styles);
@@ -953,6 +1033,47 @@ export class GridView implements IDisposable {
return this._getViews(node, this.orientation, { top: 0, left: 0, width: this.width, height: this.height });
}
static deserialize<T extends ISerializableView>(json: ISerializedGridView, deserializer: IViewDeserializer<T>, options: IGridViewOptions = {}): GridView {
if (typeof json.orientation !== 'number') {
throw new Error('Invalid JSON: \'orientation\' property must be a number.');
} else if (typeof json.width !== 'number') {
throw new Error('Invalid JSON: \'width\' property must be a number.');
} else if (typeof json.height !== 'number') {
throw new Error('Invalid JSON: \'height\' property must be a number.');
}
const orientation = json.orientation;
const height = json.height;
const result = new GridView(options);
result._deserialize(json.root as ISerializedBranchNode, orientation, deserializer, height);
return result;
}
private _deserialize(root: ISerializedBranchNode, orientation: Orientation, deserializer: IViewDeserializer<ISerializableView>, orthogonalSize: number): void {
this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize) as BranchNode;
}
private _deserializeNode(node: ISerializedNode, orientation: Orientation, deserializer: IViewDeserializer<ISerializableView>, orthogonalSize: number): Node {
let result: Node;
if (node.type === 'branch') {
const serializedChildren = node.data as ISerializedNode[];
const children = serializedChildren.map(serializedChild => {
return {
node: this._deserializeNode(serializedChild, orthogonal(orientation), deserializer, node.size),
visible: (serializedChild as { visible?: boolean }).visible
} as INodeDescriptor;
});
result = new BranchNode(orientation, this.layoutController, this.styles, this.proportionalLayout, node.size, orthogonalSize, children);
} else {
result = new LeafNode(deserializer.fromJSON(node.data), orientation, this.layoutController, orthogonalSize, node.size);
}
return result;
}
private _getViews(node: Node, orientation: Orientation, box: Box, cachedVisibleSize?: number): GridNode {
if (node instanceof LeafNode) {
return { view: node.view, box, cachedVisibleSize };