提交 0b3457a4 编写于 作者: B Benjamin Pasero

Merge branch 'master' into joao/grid-constraing-propagation

......@@ -197,10 +197,12 @@ export class Grid<T extends IView> implements IDisposable {
get maximumHeight(): number { return this.gridview.maximumHeight; }
get onDidChange(): Event<{ width: number; height: number; }> { return this.gridview.onDidChange; }
get element(): HTMLElement { return this.gridview.element; }
sashResetSizing: Sizing = Sizing.Distribute;
constructor(container: HTMLElement, view: T, options: IGridOptions = {}) {
this.gridview = new GridView(container, options);
constructor(view: T, options: IGridOptions = {}) {
this.gridview = new GridView(options);
this.disposables.push(this.gridview);
this.gridview.onDidSashReset(this.doResetViewSize, this, this.disposables);
......@@ -440,7 +442,7 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
return SerializableGrid.getFirstLeaf(node.children[0]);
}
static deserialize<T extends ISerializableView>(container: HTMLElement, json: ISerializedGrid, deserializer: IViewDeserializer<T>, options: IGridOptions = {}): SerializableGrid<T> {
static deserialize<T extends ISerializableView>(json: ISerializedGrid, deserializer: IViewDeserializer<T>, options: IGridOptions = {}): SerializableGrid<T> {
if (typeof json.orientation !== 'number') {
throw new Error('Invalid JSON: \'orientation\' property must be a number.');
} else if (typeof json.width !== 'number') {
......@@ -461,7 +463,7 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
throw new Error('Invalid serialized state, first leaf not found');
}
const result = new SerializableGrid<T>(container, firstLeaf.view, options);
const result = new SerializableGrid<T>(firstLeaf.view, options);
result.orientation = orientation;
result.restoreViews(firstLeaf.view, orientation, root);
result.initialLayoutContext = { width, height, root };
......@@ -619,4 +621,4 @@ export function createSerializedGrid(gridDescriptor: GridDescriptor): ISerialize
width: width || 1,
height: height || 1
};
}
\ No newline at end of file
}
......@@ -10,7 +10,7 @@ import { Event, anyEvent, Emitter, mapEvent, Relay } from 'vs/base/common/event'
import { Orientation, Sash } from 'vs/base/browser/ui/sash/sash';
import { SplitView, IView as ISplitView, Sizing, ISplitViewStyles } from 'vs/base/browser/ui/splitview/splitview';
import { empty as EmptyDisposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { $, append } from 'vs/base/browser/dom';
import { $ } from 'vs/base/browser/dom';
import { tail2 as tail } from 'vs/base/common/arrays';
import { Color } from 'vs/base/common/color';
......@@ -418,7 +418,7 @@ function flipNode<T extends Node>(node: T, size: number, orthogonalSize: number)
export class GridView implements IDisposable {
private element: HTMLElement;
readonly element: HTMLElement;
private styles: IGridViewStyles;
private _root: BranchNode;
......@@ -471,8 +471,8 @@ export class GridView implements IDisposable {
private _onDidChange = new Relay<{ width: number; height: number; }>();
readonly onDidChange = this._onDidChange.event;
constructor(container: HTMLElement, options: IGridViewOptions = {}) {
this.element = append(container, $('.monaco-grid-view'));
constructor(options: IGridViewOptions = {}) {
this.element = $('.monaco-grid-view');
this.styles = options.styles || defaultStyles;
this.root = new BranchNode(Orientation.VERTICAL, this.styles);
}
......@@ -745,7 +745,5 @@ export class GridView implements IDisposable {
if (this.element && this.element.parentElement) {
this.element.parentElement.removeChild(this.element);
}
this.element = null;
}
}
\ No newline at end of file
}
......@@ -30,6 +30,7 @@ export interface ISplitViewOptions {
styles?: ISplitViewStyles;
orthogonalStartSash?: Sash;
orthogonalEndSash?: Sash;
inverseAltBehavior?: boolean;
}
export interface IView {
......@@ -136,6 +137,7 @@ export class SplitView implements IDisposable {
private sashItems: ISashItem[] = [];
private sashDragState: ISashDragState;
private state: State = State.Idle;
private inverseAltBehavior: boolean;
private _onDidSashChange = new Emitter<number>();
readonly onDidSashChange = this._onDidSashChange.event;
......@@ -180,6 +182,7 @@ export class SplitView implements IDisposable {
constructor(container: HTMLElement, options: ISplitViewOptions = {}) {
this.orientation = types.isUndefined(options.orientation) ? Orientation.VERTICAL : options.orientation;
this.inverseAltBehavior = !!options.inverseAltBehavior;
this.el = document.createElement('div');
dom.addClass(this.el, 'monaco-split-view2');
......@@ -383,6 +386,9 @@ export class SplitView implements IDisposable {
// TODO@Joao rename these guys
let minDelta = Number.POSITIVE_INFINITY;
let maxDelta = Number.POSITIVE_INFINITY;
if (this.inverseAltBehavior) {
alt = !alt;
}
if (alt) {
// When we're using the last sash with Alt, we're resizing
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { Direction, Grid, getRelativeLocation, Orientation, SerializableGrid, ISerializableView, IViewDeserializer, GridNode, Sizing, isGridBranchNode, sanitizeGridNodeDescriptor, GridNodeDescriptor, createSerializedGrid } from 'vs/base/browser/ui/grid/grid';
import { Direction, getRelativeLocation, Orientation, SerializableGrid, ISerializableView, IViewDeserializer, GridNode, Sizing, isGridBranchNode, sanitizeGridNodeDescriptor, GridNodeDescriptor, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid';
import { TestView, nodesToArrays } from './util';
import { deepClone } from 'vs/base/common/objects';
......@@ -56,7 +56,8 @@ suite('Grid', function () {
test('empty', function () {
const view1 = new TestView(100, Number.MAX_VALUE, 100, Number.MAX_VALUE);
const gridview = new Grid(container, view1);
const gridview = new Grid(view1);
container.appendChild(gridview.element);
gridview.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -64,7 +65,8 @@ suite('Grid', function () {
test('two views vertically', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -76,7 +78,9 @@ suite('Grid', function () {
test('two views horizontally', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -88,7 +92,9 @@ suite('Grid', function () {
test('simple layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -121,7 +127,9 @@ suite('Grid', function () {
test('another simple layout with automatic size distribution', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -163,7 +171,9 @@ suite('Grid', function () {
test('another simple layout with split size distribution', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -205,7 +215,9 @@ suite('Grid', function () {
test('3/2 layout with split', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(view1.size, [800, 600]);
......@@ -238,7 +250,9 @@ suite('Grid', function () {
test('sizing should be correct after branch demotion #50564', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -262,7 +276,9 @@ suite('Grid', function () {
test('sizing should be correct after branch demotion #50675', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -286,7 +302,9 @@ suite('Grid', function () {
test('getNeighborViews should work on single view layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(grid.getNeighborViews(view1, Direction.Up), []);
......@@ -302,7 +320,9 @@ suite('Grid', function () {
test('getNeighborViews should work on simple layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -344,7 +364,9 @@ suite('Grid', function () {
test('getNeighborViews should work on a complex layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -383,7 +405,9 @@ suite('Grid', function () {
test('getNeighborViews should work on another simple layout', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -403,7 +427,9 @@ suite('Grid', function () {
test('getNeighborViews should only return immediate neighbors', function () {
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new Grid(container, view1);
const grid = new Grid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -460,6 +486,7 @@ function nodesToNames(node: GridNode<TestSerializableView>): any {
}
suite('SerializableGrid', function () {
let container: HTMLElement;
setup(function () {
......@@ -475,7 +502,8 @@ suite('SerializableGrid', function () {
test('serialize empty', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
assert.deepEqual(grid.serialize(), {
......@@ -500,7 +528,8 @@ suite('SerializableGrid', function () {
test('serialize simple layout', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -553,14 +582,15 @@ suite('SerializableGrid', function () {
test('deserialize empty', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const json = grid.serialize();
grid.dispose();
const deserializer = new TestViewDeserializer();
const grid2 = SerializableGrid.deserialize(container, json, deserializer);
const grid2 = SerializableGrid.deserialize(json, deserializer);
grid2.layout(800, 600);
assert.deepEqual(nodesToNames(grid2.getViews()), ['view1']);
......@@ -568,7 +598,9 @@ suite('SerializableGrid', function () {
test('deserialize simple layout', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -587,7 +619,7 @@ suite('SerializableGrid', function () {
grid.dispose();
const deserializer = new TestViewDeserializer();
const grid2 = SerializableGrid.deserialize(container, json, deserializer);
const grid2 = SerializableGrid.deserialize(json, deserializer);
const view1Copy = deserializer.getView('view1');
const view2Copy = deserializer.getView('view2');
......@@ -614,7 +646,9 @@ suite('SerializableGrid', function () {
test('deserialize simple layout with scaling', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -633,7 +667,7 @@ suite('SerializableGrid', function () {
grid.dispose();
const deserializer = new TestViewDeserializer();
const grid2 = SerializableGrid.deserialize(container, json, deserializer);
const grid2 = SerializableGrid.deserialize(json, deserializer);
const view1Copy = deserializer.getView('view1');
const view2Copy = deserializer.getView('view2');
......@@ -651,7 +685,8 @@ suite('SerializableGrid', function () {
test('deserialize 4 view layout (ben issue #2)', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -667,7 +702,7 @@ suite('SerializableGrid', function () {
grid.dispose();
const deserializer = new TestViewDeserializer();
const grid2 = SerializableGrid.deserialize(container, json, deserializer);
const grid2 = SerializableGrid.deserialize(json, deserializer);
const view1Copy = deserializer.getView('view1');
const view2Copy = deserializer.getView('view2');
......@@ -684,7 +719,9 @@ suite('SerializableGrid', function () {
test('deserialize 2 view layout (ben issue #3)', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -694,7 +731,7 @@ suite('SerializableGrid', function () {
grid.dispose();
const deserializer = new TestViewDeserializer();
const grid2 = SerializableGrid.deserialize(container, json, deserializer);
const grid2 = SerializableGrid.deserialize(json, deserializer);
const view1Copy = deserializer.getView('view1');
const view2Copy = deserializer.getView('view2');
......@@ -707,7 +744,9 @@ suite('SerializableGrid', function () {
test('deserialize simple view layout #50609', function () {
const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
const grid = new SerializableGrid(container, view1);
const grid = new SerializableGrid(view1);
container.appendChild(grid.element);
grid.layout(800, 600);
const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
......@@ -722,7 +761,7 @@ suite('SerializableGrid', function () {
grid.dispose();
const deserializer = new TestViewDeserializer();
const grid2 = SerializableGrid.deserialize(container, json, deserializer);
const grid2 = SerializableGrid.deserialize(json, deserializer);
const view2Copy = deserializer.getView('view2');
const view3Copy = deserializer.getView('view3');
......@@ -763,4 +802,4 @@ suite('SerializableGrid', function () {
height: 1
});
});
});
\ No newline at end of file
});
......@@ -4,31 +4,33 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { $ } from 'vs/base/browser/dom';
import { GridView, IView, Sizing } from 'vs/base/browser/ui/grid/gridview';
import { nodesToArrays, TestView } from './util';
suite('Gridview', function () {
let container: HTMLElement;
let gridview: GridView;
setup(function () {
container = document.createElement('div');
gridview = new GridView();
const container = $('.container');
container.style.position = 'absolute';
container.style.width = `${200}px`;
container.style.height = `${200}px`;
container.appendChild(gridview.element);
});
teardown(function () {
container = null;
gridview = null;
});
test('empty gridview is empty', function () {
const gridview = new GridView(container);
assert.deepEqual(nodesToArrays(gridview.getViews()), []);
gridview.dispose();
});
test('gridview addView', function () {
const gridview = new GridView(container);
const view = new TestView(20, 20, 20, 20);
assert.throws(() => gridview.addView(view, 200, []), 'empty location');
......@@ -51,7 +53,6 @@ suite('Gridview', function () {
});
test('gridview addView nested', function () {
const gridview = new GridView(container);
const views = [
new TestView(20, 20, 20, 20),
......@@ -71,7 +72,6 @@ suite('Gridview', function () {
});
test('gridview addView deep nested', function () {
const gridview = new GridView(container);
const view1 = new TestView(20, 20, 20, 20);
gridview.addView(view1 as IView, 200, [0]);
......@@ -109,84 +109,82 @@ suite('Gridview', function () {
});
test('simple layout', function () {
const grid = new GridView(container);
grid.layout(800, 600);
gridview.layout(800, 600);
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view1, 200, [0]);
gridview.addView(view1, 200, [0]);
assert.deepEqual(view1.size, [800, 600]);
assert.deepEqual(grid.getViewSize([0]), { width: 800, height: 600 });
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 600 });
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view2, 200, [0]);
gridview.addView(view2, 200, [0]);
assert.deepEqual(view1.size, [800, 400]);
assert.deepEqual(grid.getViewSize([1]), { width: 800, height: 400 });
assert.deepEqual(gridview.getViewSize([1]), { width: 800, height: 400 });
assert.deepEqual(view2.size, [800, 200]);
assert.deepEqual(grid.getViewSize([0]), { width: 800, height: 200 });
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 200 });
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view3, 200, [1, 1]);
gridview.addView(view3, 200, [1, 1]);
assert.deepEqual(view1.size, [600, 400]);
assert.deepEqual(grid.getViewSize([1, 0]), { width: 600, height: 400 });
assert.deepEqual(gridview.getViewSize([1, 0]), { width: 600, height: 400 });
assert.deepEqual(view2.size, [800, 200]);
assert.deepEqual(grid.getViewSize([0]), { width: 800, height: 200 });
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 200 });
assert.deepEqual(view3.size, [200, 400]);
assert.deepEqual(grid.getViewSize([1, 1]), { width: 200, height: 400 });
assert.deepEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view4, 200, [0, 0]);
gridview.addView(view4, 200, [0, 0]);
assert.deepEqual(view1.size, [600, 400]);
assert.deepEqual(grid.getViewSize([1, 0]), { width: 600, height: 400 });
assert.deepEqual(gridview.getViewSize([1, 0]), { width: 600, height: 400 });
assert.deepEqual(view2.size, [600, 200]);
assert.deepEqual(grid.getViewSize([0, 1]), { width: 600, height: 200 });
assert.deepEqual(gridview.getViewSize([0, 1]), { width: 600, height: 200 });
assert.deepEqual(view3.size, [200, 400]);
assert.deepEqual(grid.getViewSize([1, 1]), { width: 200, height: 400 });
assert.deepEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
assert.deepEqual(view4.size, [200, 200]);
assert.deepEqual(grid.getViewSize([0, 0]), { width: 200, height: 200 });
assert.deepEqual(gridview.getViewSize([0, 0]), { width: 200, height: 200 });
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view5, 100, [1, 0, 1]);
gridview.addView(view5, 100, [1, 0, 1]);
assert.deepEqual(view1.size, [600, 300]);
assert.deepEqual(grid.getViewSize([1, 0, 0]), { width: 600, height: 300 });
assert.deepEqual(gridview.getViewSize([1, 0, 0]), { width: 600, height: 300 });
assert.deepEqual(view2.size, [600, 200]);
assert.deepEqual(grid.getViewSize([0, 1]), { width: 600, height: 200 });
assert.deepEqual(gridview.getViewSize([0, 1]), { width: 600, height: 200 });
assert.deepEqual(view3.size, [200, 400]);
assert.deepEqual(grid.getViewSize([1, 1]), { width: 200, height: 400 });
assert.deepEqual(gridview.getViewSize([1, 1]), { width: 200, height: 400 });
assert.deepEqual(view4.size, [200, 200]);
assert.deepEqual(grid.getViewSize([0, 0]), { width: 200, height: 200 });
assert.deepEqual(gridview.getViewSize([0, 0]), { width: 200, height: 200 });
assert.deepEqual(view5.size, [600, 100]);
assert.deepEqual(grid.getViewSize([1, 0, 1]), { width: 600, height: 100 });
assert.deepEqual(gridview.getViewSize([1, 0, 1]), { width: 600, height: 100 });
});
test('simple layout with automatic size distribution', function () {
const grid = new GridView(container);
grid.layout(800, 600);
gridview.layout(800, 600);
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view1, Sizing.Distribute, [0]);
gridview.addView(view1, Sizing.Distribute, [0]);
assert.deepEqual(view1.size, [800, 600]);
assert.deepEqual(grid.getViewSize([0]), { width: 800, height: 600 });
assert.deepEqual(gridview.getViewSize([0]), { width: 800, height: 600 });
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view2, Sizing.Distribute, [0]);
gridview.addView(view2, Sizing.Distribute, [0]);
assert.deepEqual(view1.size, [800, 300]);
assert.deepEqual(view2.size, [800, 300]);
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view3, Sizing.Distribute, [1, 1]);
gridview.addView(view3, Sizing.Distribute, [1, 1]);
assert.deepEqual(view1.size, [400, 300]);
assert.deepEqual(view2.size, [800, 300]);
assert.deepEqual(view3.size, [400, 300]);
const view4 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view4, Sizing.Distribute, [0, 0]);
gridview.addView(view4, Sizing.Distribute, [0, 0]);
assert.deepEqual(view1.size, [400, 300]);
assert.deepEqual(view2.size, [400, 300]);
assert.deepEqual(view3.size, [400, 300]);
assert.deepEqual(view4.size, [400, 300]);
const view5 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view5, Sizing.Distribute, [1, 0, 1]);
gridview.addView(view5, Sizing.Distribute, [1, 0, 1]);
assert.deepEqual(view1.size, [400, 150]);
assert.deepEqual(view2.size, [400, 300]);
assert.deepEqual(view3.size, [400, 300]);
......@@ -195,18 +193,17 @@ suite('Gridview', function () {
});
test('addviews before layout call 1', function () {
const grid = new GridView(container);
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view1, 200, [0]);
gridview.addView(view1, 200, [0]);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view2, 200, [0]);
gridview.addView(view2, 200, [0]);
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view3, 200, [1, 1]);
gridview.addView(view3, 200, [1, 1]);
grid.layout(800, 600);
gridview.layout(800, 600);
assert.deepEqual(view1.size, [400, 300]);
assert.deepEqual(view2.size, [800, 300]);
......@@ -214,21 +211,20 @@ suite('Gridview', function () {
});
test('addviews before layout call 2', function () {
const grid = new GridView(container);
const view1 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view1, 200, [0]);
gridview.addView(view1, 200, [0]);
const view2 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view2, 200, [0]);
gridview.addView(view2, 200, [0]);
const view3 = new TestView(50, Number.MAX_VALUE, 50, Number.MAX_VALUE);
grid.addView(view3, 200, [0, 0]);
gridview.addView(view3, 200, [0, 0]);
grid.layout(800, 600);
gridview.layout(800, 600);
assert.deepEqual(view1.size, [800, 300]);
assert.deepEqual(view2.size, [400, 300]);
assert.deepEqual(view3.size, [400, 300]);
});
});
\ No newline at end of file
});
......@@ -146,6 +146,9 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
input.onDidAccept(() => {
this._proxy.$onDidAccept(sessionId);
});
input.onDidTriggerButton(button => {
this._proxy.$onDidTriggerButton(sessionId, (button as TransferQuickInputButton).handle);
});
input.onDidChangeValue(value => {
this._proxy.$onDidChangeValue(sessionId, value);
});
......
......@@ -88,7 +88,6 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
private groupViews: Map<GroupIdentifier, IEditorGroupView> = new Map<GroupIdentifier, IEditorGroupView>();
private mostRecentActiveGroups: GroupIdentifier[] = [];
private container: HTMLElement;
private gridWidget: SerializableGrid<IEditorGroupView>;
private _whenRestored: TPromise<void>;
......@@ -327,7 +326,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
}
applyLayout(layout: EditorGroupLayout): void {
const gridHasFocus = isAncestor(document.activeElement, this.container);
const gridHasFocus = isAncestor(document.activeElement, this.gridWidget.element);
// Determine how many groups we need overall
let layoutGroupsCount = 0;
......@@ -364,7 +363,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
});
// Recreate gridwidget with descriptor
this.doCreateGridControlWithState(this.container, gridDescriptor, activeGroup.id, currentGroupViews);
this.doCreateGridControlWithState(gridDescriptor, activeGroup.id, currentGroupViews);
// Layout
this.doLayout(this.dimension);
......@@ -549,7 +548,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
}
private doRemoveEmptyGroup(groupView: IEditorGroupView): void {
const gridHasFocus = isAncestor(document.activeElement, this.container);
const gridHasFocus = isAncestor(document.activeElement, this.gridWidget.element);
// Activate next group if the removed one was active
if (this._activeGroup === groupView) {
......@@ -697,38 +696,38 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
}
protected updateStyles(): void {
this.container.style.backgroundColor = this.getColor(editorBackground);
this.gridWidget.element.style.backgroundColor = this.getColor(editorBackground);
this.gridWidget.style({ separatorBorder: this.gridSeparatorBorder });
}
createContentArea(parent: HTMLElement): HTMLElement {
// Grid control
this.doCreateGridControl();
// Container
this.container = document.createElement('div');
addClass(this.container, 'content');
parent.appendChild(this.container);
addClass(this.gridWidget.element, 'content');
parent.appendChild(this.gridWidget.element);
// Grid control
this.doCreateGridControl(this.container);
// Drop support
this._register(this.instantiationService.createInstance(EditorDropTarget, this, this.container));
this._register(this.instantiationService.createInstance(EditorDropTarget, this, this.gridWidget.element));
return this.container;
return this.gridWidget.element;
}
private doCreateGridControl(container: HTMLElement): void {
private doCreateGridControl(): void {
// Grid Widget (with previous UI state)
if (this.restorePreviousState) {
this.doCreateGridControlWithPreviousState(container);
this.doCreateGridControlWithPreviousState();
}
// Grid Widget (no previous UI state or failed to restore)
if (!this.gridWidget) {
const initialGroup = this.doCreateGroupView();
this.setGridWidget(new SerializableGrid(container, initialGroup));
this.setGridWidget(new SerializableGrid(initialGroup));
// Ensure a group is active
this.doSetGroupActive(initialGroup);
......@@ -741,7 +740,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
this.updateContainer();
}
private doCreateGridControlWithPreviousState(container: HTMLElement): void {
private doCreateGridControlWithPreviousState(): void {
const uiState = this.doGetPreviousState();
if (uiState && uiState.serializedGrid) {
try {
......@@ -751,17 +750,17 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
this.mostRecentActiveGroups = uiState.mostRecentActiveGroups;
// Grid Widget
this.doCreateGridControlWithState(container, uiState.serializedGrid, uiState.activeGroup);
this.doCreateGridControlWithState(uiState.serializedGrid, uiState.activeGroup);
// Ensure last active group has focus
this._activeGroup.focus();
} catch (error) {
if (this.gridWidget) {
clearNode(this.gridWidget.element);
this.gridWidget.dispose();
this.setGridWidget();
}
clearNode(container);
this.groupViews.forEach(group => group.dispose());
this.groupViews.clear();
this._activeGroup = void 0;
......@@ -772,7 +771,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
}
}
private doCreateGridControlWithState(container: HTMLElement, serializedGrid: ISerializedGrid, activeGroupId: GroupIdentifier, editorGroupViewsToReuse?: IEditorGroupView[]): void {
private doCreateGridControlWithState(serializedGrid: ISerializedGrid, activeGroupId: GroupIdentifier, editorGroupViewsToReuse?: IEditorGroupView[]): void {
// Dispose old
if (this.gridWidget) {
......@@ -788,7 +787,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
}
// Create new
this.setGridWidget(SerializableGrid.deserialize(container, serializedGrid, {
this.setGridWidget(SerializableGrid.deserialize(serializedGrid, {
fromJSON: (serializedEditorGroup: ISerializedEditorGroup) => {
let groupView: IEditorGroupView;
if (reuseGroupViews.length > 0) {
......@@ -934,7 +933,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
}
private updateContainer(): void {
toggleClass(this.container, 'empty', this.isEmpty());
toggleClass(this.gridWidget.element, 'empty', this.isEmpty());
}
private isEmpty(): boolean {
......
......@@ -36,7 +36,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ICommandAndKeybindingRule, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { inQuickOpenContext } from 'vs/workbench/browser/parts/quickopen/quickopen';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionBar, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
import URI from 'vs/base/common/uri';
import { IdGenerator } from 'vs/base/common/idGenerator';
......@@ -56,6 +56,7 @@ interface QuickInputUI {
ignoreFocusOut: boolean;
show(controller: QuickInput): void;
setVisibilities(visibilities: Visibilities): void;
setEnabled(enabled: boolean): void;
hide(): void;
}
......@@ -96,7 +97,7 @@ class QuickInput implements IQuickInput {
set enabled(enabled: boolean) {
this._enabled = enabled;
this.update(); // TODO
this.update();
}
get busy() {
......@@ -177,6 +178,7 @@ class QuickInput implements IQuickInput {
return action;
}), { icon: true, label: false });
}
this.ui.setEnabled(this.enabled);
}
public dispose(): void {
......@@ -574,7 +576,9 @@ export class QuickInputService extends Component implements IQuickInputService {
private filterContainer: HTMLElement;
private countContainer: HTMLElement;
private okContainer: HTMLElement;
private ok: Button;
private ui: QuickInputUI;
private enabled = true;
private inQuickOpenWidgets: Record<string, boolean> = {};
private inQuickOpenContext: IContextKey<boolean>;
private onDidAcceptEmitter = new Emitter<void>();
......@@ -651,11 +655,11 @@ export class QuickInputService extends Component implements IQuickInputService {
this.toUnbind.push(attachBadgeStyler(count, this.themeService));
this.okContainer = dom.append(headerContainer, $('.quick-input-action'));
const ok = new Button(this.okContainer);
attachButtonStyler(ok, this.themeService);
ok.label = localize('ok', "OK");
this.toUnbind.push(ok.onDidClick(e => {
this.onDidAcceptEmitter.fire(); // TODO: make single-select QuickPick exclusively use Accept?
this.ok = new Button(this.okContainer);
attachButtonStyler(this.ok, this.themeService);
this.ok.label = localize('ok', "OK");
this.toUnbind.push(this.ok.onDidClick(e => {
this.onDidAcceptEmitter.fire();
}));
const actionBar = new ActionBar(headerContainer);
......@@ -740,7 +744,8 @@ export class QuickInputService extends Component implements IQuickInputService {
ignoreFocusOut: false,
show: controller => this.show(controller),
hide: () => this.hide(),
setVisibilities: visibilities => this.setVisibilities(visibilities)
setVisibilities: visibilities => this.setVisibilities(visibilities),
setEnabled: enabled => this.setEnabled(enabled),
};
this.updateStyles();
}
......@@ -877,6 +882,7 @@ export class QuickInputService extends Component implements IQuickInputService {
oldController.didHide();
}
this.setEnabled(true);
this.ui.checkAll.checked = false;
// this.ui.inputBox.value = ''; Avoid triggering an event.
this.ui.inputBox.placeholder = '';
......@@ -909,6 +915,19 @@ export class QuickInputService extends Component implements IQuickInputService {
this.updateLayout(); // TODO
}
private setEnabled(enabled: boolean) {
if (enabled !== this.enabled) {
this.enabled = enabled;
this.ui.checkAll.disabled = !enabled;
this.ui.inputBox.enabled = enabled;
for (const item of this.ui.actionBar.items) {
(item as ActionItem).getAction().enabled = enabled;
}
this.ok.enabled = enabled;
this.ui.list.enabled = enabled;
}
}
private hide(focusLost?: boolean) {
const controller = this.controller;
if (controller) {
......
......@@ -83,6 +83,10 @@ export class QuickInputBox {
this.inputBox.inputElement.type = password ? 'password' : 'text';
}
set enabled(enabled: boolean) {
this.inputBox.setEnabled(enabled);
}
showDecoration(decoration: Severity): void {
if (decoration === Severity.Ignore) {
this.inputBox.hideMessage();
......
......@@ -291,6 +291,10 @@ export class QuickInputList {
.map(e => e.item);
}
set enabled(value: boolean) {
this.list.getHTMLElement().style.pointerEvents = value ? null : 'none';
}
focus(what: 'First' | 'Last' | 'Next' | 'Previous' | 'NextPage' | 'PreviousPage'): void {
if (!this.list.length) {
return;
......
......@@ -1042,9 +1042,11 @@ export class DebugService implements debug.IDebugService {
}
// run a task before starting a debug session
return this.taskService.getTask(root, taskId).then(task => {
const taskDisplayName = typeof taskId === 'string' ? `'${taskId}'` : nls.localize('specified', "specified");
if (!task) {
return TPromise.wrapError(errors.create(nls.localize('DebugTaskNotFound', "Could not find the task {0}.", taskDisplayName)));
const errorMessage = typeof taskId === 'string'
? nls.localize('DebugTaskNotFoundWithTaskId', "Could not find the task '{0}'.", taskId)
: nls.localize('DebugTaskNotFound', "Could not find the specified task.");
return TPromise.wrapError(errors.create(errorMessage));
}
function once(kind: TaskEventKind, event: Event<TaskEvent>): Event<TaskEvent> {
......@@ -1088,7 +1090,10 @@ export class DebugService implements debug.IDebugService {
setTimeout(() => {
if (!taskStarted) {
e({ severity: severity.Error, message: nls.localize('taskNotTracked', "The task {0} cannot be tracked.", taskDisplayName) });
const errorMessage = typeof taskId === 'string'
? nls.localize('taskNotTrackedWithTaskId', "The specified task cannot be tracked.")
: nls.localize('taskNotTracked', "The task '{0}' cannot be tracked.", taskId);
e({ severity: severity.Error, message: errorMessage });
}
}, 10000);
});
......
......@@ -256,7 +256,7 @@ export class FeedbackDropdown extends Dropdown {
this.$sendButton.addClass('send');
this.toDispose.push(attachButtonStyler(this.sendButton, this.themeService));
this.invoke(this.$sendButton, () => {
this.sendButton.onDidClick(() => {
if (this.isSendingFeedback) {
return;
}
......
......@@ -160,6 +160,7 @@ export class OpenEditorsView extends ViewletPanel {
}
}
}));
this.disposables.push(groupDisposables.get(group.id));
};
this.editorGroupService.groups.forEach(g => addGroupListener(g));
......
......@@ -16,6 +16,7 @@ import { isFalsyOrEmpty, binarySearch } from 'vs/base/common/arrays';
import { commonPrefixLength } from 'vs/base/common/strings';
import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { LRUCache } from 'vs/base/common/map';
export abstract class TreeElement {
abstract id: string;
......@@ -192,7 +193,33 @@ export class OutlineGroup extends TreeElement {
export class OutlineModel extends TreeElement {
static create(textModel: ITextModel): TPromise<OutlineModel> {
private static readonly _requests = new LRUCache<string, { count: number, promise: TPromise<OutlineModel> }>(9, .75);
static create(textModel: ITextModel, forceFresh?: boolean): TPromise<OutlineModel> {
let key = `${textModel.id}/${textModel.getVersionId()}/${DocumentSymbolProviderRegistry.all(textModel).length}`;
let data = OutlineModel._requests.get(key);
if (!data || forceFresh) {
data = { promise: OutlineModel._create(textModel), count: 0 };
OutlineModel._requests.set(key, data);
}
// increase usage counter
data.count += 1;
return new TPromise((resolve, reject) => {
data.promise.then(resolve, reject);
}, () => {
if (--data.count === 0) {
// last -> cancel provider request
data.promise.cancel();
}
});
}
static _create(textModel: ITextModel): TPromise<OutlineModel> {
let result = new OutlineModel(textModel);
let promises = DocumentSymbolProviderRegistry.ordered(textModel).map((provider, index) => {
......
......@@ -51,7 +51,7 @@ import { CollapseAction } from 'vs/workbench/browser/viewlet';
import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
import { OutlineConfigKeys, OutlineViewFiltered, OutlineViewFocused, OutlineViewId } from './outline';
import { OutlineElement, OutlineModel, TreeElement } from './outlineModel';
import { OutlineElement, OutlineModel, TreeElement } from '../common/outlineModel';
import { OutlineController, OutlineDataSource, OutlineItemComparator, OutlineItemCompareType, OutlineItemFilter, OutlineRenderer, OutlineTreeState } from './outlineTree';
import { IViewsService } from 'vs/workbench/common/views';
......@@ -434,9 +434,11 @@ export class OutlinePanel extends ViewletPanel {
dispose(this._editorDisposables);
this._editorDisposables = new Array();
this._input.disable();
this._input.value = '';
this._progressBar.infinite().show(150);
this._input.disable();
if (!event) {
this._input.value = '';
}
if (!editor || !DocumentSymbolProviderRegistry.has(editor.getModel())) {
return this._showMessage(localize('no-editor', "There are no editors open that can provide outline information."));
......@@ -510,7 +512,7 @@ export class OutlinePanel extends ViewletPanel {
// on first type -> capture tree state
// on erase -> restore captured tree state
let beforePatternState: OutlineTreeState;
this._editorDisposables.push(this._input.onDidChange(async pattern => {
let onInputValueChanged = async pattern => {
this._contextKeyFiltered.set(pattern.length > 0);
......@@ -530,7 +532,9 @@ export class OutlinePanel extends ViewletPanel {
await OutlineTreeState.restore(this._tree, beforePatternState);
beforePatternState = undefined;
}
}));
};
onInputValueChanged(this._input.value);
this._editorDisposables.push(this._input.onDidChange(onInputValueChanged));
this._editorDisposables.push({
dispose: () => this._contextKeyFiltered.reset()
......
......@@ -16,7 +16,7 @@ import 'vs/css!./media/symbol-icons';
import { Range } from 'vs/editor/common/core/range';
import { symbolKindToCssClass, SymbolKind } from 'vs/editor/common/modes';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from './outlineModel';
import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from '../common/outlineModel';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { localize } from 'vs/nls';
......
......@@ -6,7 +6,7 @@
'use strict';
import * as assert from 'assert';
import { OutlineElement, OutlineGroup } from 'vs/workbench/parts/outline/electron-browser/outlineModel';
import { OutlineElement, OutlineGroup } from 'vs/workbench/parts/outline/common/outlineModel';
import { SymbolKind, DocumentSymbol } from 'vs/editor/common/modes';
import { Range } from 'vs/editor/common/core/range';
import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册