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

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

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