Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/vs/base/parts/tree/browser/treeModel.ts')
-rw-r--r--src/vs/base/parts/tree/browser/treeModel.ts249
1 files changed, 195 insertions, 54 deletions
diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts
index bc6c1e823a2..80db46b1a79 100644
--- a/src/vs/base/parts/tree/browser/treeModel.ts
+++ b/src/vs/base/parts/tree/browser/treeModel.ts
@@ -9,31 +9,34 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import arrays = require('vs/base/common/arrays');
import { INavigator } from 'vs/base/common/iterator';
-import Events = require('vs/base/common/eventEmitter');
import WinJS = require('vs/base/common/winjs.base');
import _ = require('./tree');
+import Event, { Emitter, once, EventMultiplexer, Relay } from 'vs/base/common/event';
interface IMap<T> { [id: string]: T; }
interface IItemMap extends IMap<Item> { }
interface ITraitMap extends IMap<IItemMap> { }
-export class LockData extends Events.EventEmitter {
+export class LockData {
private _item: Item;
+ private _onDispose = new Emitter<void>();
+ readonly onDispose: Event<void> = this._onDispose.event;
constructor(item: Item) {
- super();
-
this._item = item;
}
- public get item(): Item {
+ get item(): Item {
return this._item;
}
- public dispose(): void {
- this.emit('unlock');
- super.dispose();
+ dispose(): void {
+ if (this._onDispose) {
+ this._onDispose.fire();
+ this._onDispose.dispose();
+ this._onDispose = null;
+ }
}
}
@@ -84,7 +87,7 @@ export class Lock {
var unbindListener: IDisposable;
return new WinJS.TPromise((c, e) => {
- unbindListener = lock.addOneTimeListener('unlock', () => {
+ unbindListener = once(lock.onDispose)(() => {
return this.run(item, fn).then(c, e);
});
}, () => { unbindListener.dispose(); });
@@ -126,19 +129,55 @@ export class Lock {
}
}
-export class ItemRegistry extends Events.EventEmitter {
+export class ItemRegistry {
private _isDisposed = false;
private items: IMap<{ item: Item; disposable: IDisposable; }>;
+ private _onDidRevealItem = new EventMultiplexer<IItemRevealEvent>();
+ readonly onDidRevealItem: Event<IItemRevealEvent> = this._onDidRevealItem.event;
+ private _onExpandItem = new EventMultiplexer<IItemExpandEvent>();
+ readonly onExpandItem: Event<IItemExpandEvent> = this._onExpandItem.event;
+ private _onDidExpandItem = new EventMultiplexer<IItemExpandEvent>();
+ readonly onDidExpandItem: Event<IItemExpandEvent> = this._onDidExpandItem.event;
+ private _onCollapseItem = new EventMultiplexer<IItemCollapseEvent>();
+ readonly onCollapseItem: Event<IItemCollapseEvent> = this._onCollapseItem.event;
+ private _onDidCollapseItem = new EventMultiplexer<IItemCollapseEvent>();
+ readonly onDidCollapseItem: Event<IItemCollapseEvent> = this._onDidCollapseItem.event;
+ private _onDidAddTraitItem = new EventMultiplexer<IItemTraitEvent>();
+ readonly onDidAddTraitItem: Event<IItemTraitEvent> = this._onDidAddTraitItem.event;
+ private _onDidRemoveTraitItem = new EventMultiplexer<IItemCollapseEvent>();
+ readonly onDidRemoveTraitItem: Event<IItemCollapseEvent> = this._onDidRemoveTraitItem.event;
+ private _onDidRefreshItem = new EventMultiplexer<Item>();
+ readonly onDidRefreshItem: Event<Item> = this._onDidRefreshItem.event;
+ private _onRefreshItemChildren = new EventMultiplexer<IItemChildrenRefreshEvent>();
+ readonly onRefreshItemChildren: Event<IItemChildrenRefreshEvent> = this._onRefreshItemChildren.event;
+ private _onDidRefreshItemChildren = new EventMultiplexer<IItemChildrenRefreshEvent>();
+ readonly onDidRefreshItemChildren: Event<IItemChildrenRefreshEvent> = this._onDidRefreshItemChildren.event;
+ private _onDidDisposeItem = new EventMultiplexer<Item>();
+ readonly onDidDisposeItem: Event<Item> = this._onDidDisposeItem.event;
+
constructor() {
- super();
this.items = {};
}
public register(item: Item): void {
Assert.ok(!this.isRegistered(item.id), 'item already registered: ' + item.id);
- this.items[item.id] = { item, disposable: this.addEmitter(item) };
+
+ const disposable = combinedDisposable([
+ this._onDidRevealItem.add(item.onDidReveal),
+ this._onExpandItem.add(item.onExpand),
+ this._onDidExpandItem.add(item.onDidExpand),
+ this._onCollapseItem.add(item.onCollapse),
+ this._onDidCollapseItem.add(item.onDidCollapse),
+ this._onDidAddTraitItem.add(item.onDidAddTrait),
+ this._onDidRemoveTraitItem.add(item.onDidRemoveTrait),
+ this._onDidRefreshItem.add(item.onDidRefresh),
+ this._onRefreshItemChildren.add(item.onRefreshChildren),
+ this._onDidRefreshItemChildren.add(item.onDidRefreshChildren),
+ ]);
+
+ this.items[item.id] = { item, disposable };
}
public deregister(item: Item): void {
@@ -157,8 +196,19 @@ export class ItemRegistry extends Events.EventEmitter {
}
public dispose(): void {
- super.dispose();
this.items = null;
+
+ this._onDidRevealItem.dispose();
+ this._onExpandItem.dispose();
+ this._onDidExpandItem.dispose();
+ this._onCollapseItem.dispose();
+ this._onDidCollapseItem.dispose();
+ this._onDidAddTraitItem.dispose();
+ this._onDidRemoveTraitItem.dispose();
+ this._onDidRefreshItem.dispose();
+ this._onRefreshItemChildren.dispose();
+ this._onDidRefreshItemChildren.dispose();
+
this._isDisposed = true;
}
@@ -174,7 +224,6 @@ export interface IBaseItemEvent {
export interface IItemRefreshEvent extends IBaseItemEvent { }
export interface IItemExpandEvent extends IBaseItemEvent { }
export interface IItemCollapseEvent extends IBaseItemEvent { }
-export interface IItemDisposeEvent extends IBaseItemEvent { }
export interface IItemTraitEvent extends IBaseItemEvent {
trait: string;
@@ -188,7 +237,7 @@ export interface IItemChildrenRefreshEvent extends IBaseItemEvent {
isNested: boolean;
}
-export class Item extends Events.EventEmitter {
+export class Item {
private registry: ItemRegistry;
private context: _.ITreeContext;
@@ -214,11 +263,34 @@ export class Item extends Events.EventEmitter {
private traits: { [trait: string]: boolean; };
+ private _onDidCreate = new Emitter<Item>();
+ readonly onDidCreate: Event<Item> = this._onDidCreate.event;
+ private _onDidReveal = new Emitter<IItemRevealEvent>();
+ readonly onDidReveal: Event<IItemRevealEvent> = this._onDidReveal.event;
+ private _onExpand = new Emitter<IItemExpandEvent>();
+ readonly onExpand: Event<IItemExpandEvent> = this._onExpand.event;
+ private _onDidExpand = new Emitter<IItemExpandEvent>();
+ readonly onDidExpand: Event<IItemExpandEvent> = this._onDidExpand.event;
+ private _onCollapse = new Emitter<IItemCollapseEvent>();
+ readonly onCollapse: Event<IItemCollapseEvent> = this._onCollapse.event;
+ private _onDidCollapse = new Emitter<IItemCollapseEvent>();
+ readonly onDidCollapse: Event<IItemCollapseEvent> = this._onDidCollapse.event;
+ private _onDidAddTrait = new Emitter<IItemTraitEvent>();
+ readonly onDidAddTrait: Event<IItemTraitEvent> = this._onDidAddTrait.event;
+ private _onDidRemoveTrait = new Emitter<IItemCollapseEvent>();
+ readonly onDidRemoveTrait: Event<IItemCollapseEvent> = this._onDidRemoveTrait.event;
+ private _onDidRefresh = new Emitter<Item>();
+ readonly onDidRefresh: Event<Item> = this._onDidRefresh.event;
+ private _onRefreshChildren = new Emitter<IItemChildrenRefreshEvent>();
+ readonly onRefreshChildren: Event<IItemChildrenRefreshEvent> = this._onRefreshChildren.event;
+ private _onDidRefreshChildren = new Emitter<IItemChildrenRefreshEvent>();
+ readonly onDidRefreshChildren: Event<IItemChildrenRefreshEvent> = this._onDidRefreshChildren.event;
+ private _onDidDispose = new Emitter<Item>();
+ readonly onDidDispose: Event<Item> = this._onDidDispose.event;
+
private _isDisposed: boolean;
constructor(id: string, registry: ItemRegistry, context: _.ITreeContext, lock: Lock, element: any) {
- super();
-
this.registry = registry;
this.context = context;
this.lock = lock;
@@ -240,7 +312,7 @@ export class Item extends Events.EventEmitter {
this.depth = 0;
this.expanded = this.context.dataSource.shouldAutoexpand && this.context.dataSource.shouldAutoexpand(this.context.tree, element);
- this.emit('item:create', { item: this });
+ this._onDidCreate.fire(this);
this.visible = this._isVisible();
this.height = this._getHeight();
@@ -278,7 +350,7 @@ export class Item extends Events.EventEmitter {
public reveal(relativeTop: number = null): void {
var eventData: IItemRevealEvent = { item: this, relativeTop: relativeTop };
- this.emit('item:reveal', eventData);
+ this._onDidReveal.fire(eventData);
}
public expand(): WinJS.Promise {
@@ -289,7 +361,7 @@ export class Item extends Events.EventEmitter {
var result = this.lock.run(this, () => {
var eventData: IItemExpandEvent = { item: this };
var result: WinJS.Promise;
- this.emit('item:expanding', eventData);
+ this._onExpand.fire(eventData);
if (this.needsChildrenRefresh) {
result = this.refreshChildren(false, true, true);
@@ -299,7 +371,7 @@ export class Item extends Events.EventEmitter {
return result.then(() => {
this._setExpanded(true);
- this.emit('item:expanded', eventData);
+ this._onDidExpand.fire(eventData);
return true;
});
});
@@ -334,9 +406,9 @@ export class Item extends Events.EventEmitter {
return this.lock.run(this, () => {
var eventData: IItemCollapseEvent = { item: this };
- this.emit('item:collapsing', eventData);
+ this._onCollapse.fire(eventData);
this._setExpanded(false);
- this.emit('item:collapsed', eventData);
+ this._onDidCollapse.fire(eventData);
return WinJS.TPromise.as(true);
});
@@ -346,13 +418,13 @@ export class Item extends Events.EventEmitter {
public addTrait(trait: string): void {
var eventData: IItemTraitEvent = { item: this, trait: trait };
this.traits[trait] = true;
- this.emit('item:addTrait', eventData);
+ this._onDidAddTrait.fire(eventData);
}
public removeTrait(trait: string): void {
var eventData: IItemTraitEvent = { item: this, trait: trait };
delete this.traits[trait];
- this.emit('item:removeTrait', eventData);
+ this._onDidRemoveTrait.fire(eventData);
}
public hasTrait(trait: string): boolean {
@@ -384,7 +456,7 @@ export class Item extends Events.EventEmitter {
var doRefresh = () => {
var eventData: IItemChildrenRefreshEvent = { item: this, isNested: safe };
- this.emit('item:childrenRefreshing', eventData);
+ this._onRefreshChildren.fire(eventData);
var childrenPromise: WinJS.Promise;
if (this.doesHaveChildren) {
@@ -440,20 +512,18 @@ export class Item extends Events.EventEmitter {
return result
.then(null, onUnexpectedError)
- .then(() => this.emit('item:childrenRefreshed', eventData));
+ .then(() => this._onDidRefreshChildren.fire(eventData));
};
return safe ? doRefresh() : this.lock.run(this, doRefresh);
}
private doRefresh(recursive: boolean, safe: boolean = false): WinJS.Promise {
- var eventData: IItemRefreshEvent = { item: this };
-
this.doesHaveChildren = this.context.dataSource.hasChildren(this.context.tree, this.element);
this.height = this._getHeight();
this.setVisible(this._isVisible());
- this.emit('item:refresh', eventData);
+ this._onDidRefresh.fire(this);
return this.refreshChildren(recursive, safe);
}
@@ -602,11 +672,22 @@ export class Item extends Events.EventEmitter {
this.firstChild = null;
this.lastChild = null;
- var eventData: IItemDisposeEvent = { item: this };
- this.emit('item:dispose', eventData);
+ this._onDidDispose.fire(this);
this.registry.deregister(this);
- super.dispose();
+
+ this._onDidCreate.dispose();
+ this._onDidReveal.dispose();
+ this._onExpand.dispose();
+ this._onDidExpand.dispose();
+ this._onCollapse.dispose();
+ this._onDidCollapse.dispose();
+ this._onDidAddTrait.dispose();
+ this._onDidRemoveTrait.dispose();
+ this._onDidRefresh.dispose();
+ this._onRefreshChildren.dispose();
+ this._onDidRefreshChildren.dispose();
+ this._onDidDispose.dispose();
this._isDisposed = true;
}
@@ -788,7 +869,7 @@ export interface IRefreshEvent extends IBaseEvent {
recursive: boolean;
}
-export class TreeModel extends Events.EventEmitter {
+export class TreeModel {
private context: _.ITreeContext;
private lock: Lock;
@@ -797,9 +878,45 @@ export class TreeModel extends Events.EventEmitter {
private registryDisposable: IDisposable;
private traitsToItems: ITraitMap;
- constructor(context: _.ITreeContext) {
- super();
+ private _onSetInput = new Emitter<IInputEvent>();
+ readonly onSetInput: Event<IInputEvent> = this._onSetInput.event;
+ private _onDidSetInput = new Emitter<IInputEvent>();
+ readonly onDidSetInput: Event<IInputEvent> = this._onDidSetInput.event;
+ private _onRefresh = new Emitter<IRefreshEvent>();
+ readonly onRefresh: Event<IRefreshEvent> = this._onRefresh.event;
+ private _onDidRefresh = new Emitter<IRefreshEvent>();
+ readonly onDidRefresh: Event<IRefreshEvent> = this._onDidRefresh.event;
+ private _onDidHighlight = new Emitter<_.IHighlightEvent>();
+ readonly onDidHighlight: Event<_.IHighlightEvent> = this._onDidHighlight.event;
+ private _onDidSelect = new Emitter<_.ISelectionEvent>();
+ readonly onDidSelect: Event<_.ISelectionEvent> = this._onDidSelect.event;
+ private _onDidFocus = new Emitter<_.IFocusEvent>();
+ readonly onDidFocus: Event<_.IFocusEvent> = this._onDidFocus.event;
+
+ private _onDidRevealItem = new Relay<IItemRevealEvent>();
+ readonly onDidRevealItem: Event<IItemRevealEvent> = this._onDidRevealItem.event;
+ private _onExpandItem = new Relay<IItemExpandEvent>();
+ readonly onExpandItem: Event<IItemExpandEvent> = this._onExpandItem.event;
+ private _onDidExpandItem = new Relay<IItemExpandEvent>();
+ readonly onDidExpandItem: Event<IItemExpandEvent> = this._onDidExpandItem.event;
+ private _onCollapseItem = new Relay<IItemCollapseEvent>();
+ readonly onCollapseItem: Event<IItemCollapseEvent> = this._onCollapseItem.event;
+ private _onDidCollapseItem = new Relay<IItemCollapseEvent>();
+ readonly onDidCollapseItem: Event<IItemCollapseEvent> = this._onDidCollapseItem.event;
+ private _onDidAddTraitItem = new Relay<IItemTraitEvent>();
+ readonly onDidAddTraitItem: Event<IItemTraitEvent> = this._onDidAddTraitItem.event;
+ private _onDidRemoveTraitItem = new Relay<IItemCollapseEvent>();
+ readonly onDidRemoveTraitItem: Event<IItemCollapseEvent> = this._onDidRemoveTraitItem.event;
+ private _onDidRefreshItem = new Relay<Item>();
+ readonly onDidRefreshItem: Event<Item> = this._onDidRefreshItem.event;
+ private _onRefreshItemChildren = new Relay<IItemChildrenRefreshEvent>();
+ readonly onRefreshItemChildren: Event<IItemChildrenRefreshEvent> = this._onRefreshItemChildren.event;
+ private _onDidRefreshItemChildren = new Relay<IItemChildrenRefreshEvent>();
+ readonly onDidRefreshItemChildren: Event<IItemChildrenRefreshEvent> = this._onDidRefreshItemChildren.event;
+ private _onDidDisposeItem = new Relay<Item>();
+ readonly onDidDisposeItem: Event<Item> = this._onDidDisposeItem.event;
+ constructor(context: _.ITreeContext) {
this.context = context;
this.input = null;
this.traitsToItems = {};
@@ -807,7 +924,7 @@ export class TreeModel extends Events.EventEmitter {
public setInput(element: any): WinJS.Promise {
var eventData: IInputEvent = { item: this.input };
- this.emit('clearingInput', eventData);
+ this._onSetInput.fire(eventData);
this.setSelection([]);
this.setFocus();
@@ -826,18 +943,25 @@ export class TreeModel extends Events.EventEmitter {
this.registry = new ItemRegistry();
- this.registryDisposable = combinedDisposable([
- this.addEmitter(this.registry),
- this.registry.addListener('item:dispose', (event: IItemDisposeEvent) => {
- event.item.getAllTraits()
- .forEach(trait => delete this.traitsToItems[trait][event.item.id]);
- })
- ]);
+ this._onDidRevealItem.input = this.registry.onDidRevealItem;
+ this._onExpandItem.input = this.registry.onExpandItem;
+ this._onDidExpandItem.input = this.registry.onDidExpandItem;
+ this._onCollapseItem.input = this.registry.onCollapseItem;
+ this._onDidCollapseItem.input = this.registry.onDidCollapseItem;
+ this._onDidAddTraitItem.input = this.registry.onDidAddTraitItem;
+ this._onDidRemoveTraitItem.input = this.registry.onDidRemoveTraitItem;
+ this._onDidRefreshItem.input = this.registry.onDidRefreshItem;
+ this._onRefreshItemChildren.input = this.registry.onRefreshItemChildren;
+ this._onDidRefreshItemChildren.input = this.registry.onDidRefreshItemChildren;
+ this._onDidDisposeItem.input = this.registry.onDidDisposeItem;
+
+ this.registryDisposable = this.registry
+ .onDidDisposeItem(item => item.getAllTraits().forEach(trait => delete this.traitsToItems[trait][item.id]));
var id = this.context.dataSource.getId(this.context.tree, element);
this.input = new RootItem(id, this.registry, this.context, this.lock, element);
eventData = { item: this.input };
- this.emit('setInput', eventData);
+ this._onDidSetInput.fire(eventData);
return this.refresh(this.input);
}
@@ -853,9 +977,9 @@ export class TreeModel extends Events.EventEmitter {
}
var eventData: IRefreshEvent = { item: item, recursive: recursive };
- this.emit('refreshing', eventData);
+ this._onRefresh.fire(eventData);
return item.refresh(recursive).then(() => {
- this.emit('refreshed', eventData);
+ this._onDidRefresh.fire(eventData);
});
}
@@ -1001,7 +1125,7 @@ export class TreeModel extends Events.EventEmitter {
public setHighlight(element?: any, eventPayload?: any): void {
this.setTraits('highlighted', element ? [element] : []);
var eventData: _.IHighlightEvent = { highlight: this.getHighlight(), payload: eventPayload };
- this.emit('highlight', eventData);
+ this._onDidHighlight.fire(eventData);
}
public getHighlight(includeHidden?: boolean): any {
@@ -1048,7 +1172,7 @@ export class TreeModel extends Events.EventEmitter {
public selectAll(elements: any[], eventPayload?: any): void {
this.addTraits('selected', elements);
var eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
- this.emit('selection', eventData);
+ this._onDidSelect.fire(eventData);
}
public deselect(element: any, eventPayload?: any): void {
@@ -1058,19 +1182,19 @@ export class TreeModel extends Events.EventEmitter {
public deselectAll(elements: any[], eventPayload?: any): void {
this.removeTraits('selected', elements);
var eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
- this.emit('selection', eventData);
+ this._onDidSelect.fire(eventData);
}
public setSelection(elements: any[], eventPayload?: any): void {
this.setTraits('selected', elements);
var eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
- this.emit('selection', eventData);
+ this._onDidSelect.fire(eventData);
}
public toggleSelection(element: any, eventPayload?: any): void {
this.toggleTrait('selected', element);
var eventData: _.ISelectionEvent = { selection: this.getSelection(), payload: eventPayload };
- this.emit('selection', eventData);
+ this._onDidSelect.fire(eventData);
}
public isSelected(element: any): boolean {
@@ -1160,7 +1284,7 @@ export class TreeModel extends Events.EventEmitter {
public setFocus(element?: any, eventPayload?: any): void {
this.setTraits('focused', element ? [element] : []);
var eventData: _.IFocusEvent = { focus: this.getFocus(), payload: eventPayload };
- this.emit('focus', eventData);
+ this._onDidFocus.fire(eventData);
}
public isFocused(element: any): boolean {
@@ -1415,6 +1539,23 @@ export class TreeModel extends Events.EventEmitter {
this.registry = null;
}
- super.dispose();
+ this._onSetInput.dispose();
+ this._onDidSetInput.dispose();
+ this._onRefresh.dispose();
+ this._onDidRefresh.dispose();
+ this._onDidHighlight.dispose();
+ this._onDidSelect.dispose();
+ this._onDidFocus.dispose();
+ this._onDidRevealItem.dispose();
+ this._onExpandItem.dispose();
+ this._onDidExpandItem.dispose();
+ this._onCollapseItem.dispose();
+ this._onDidCollapseItem.dispose();
+ this._onDidAddTraitItem.dispose();
+ this._onDidRemoveTraitItem.dispose();
+ this._onDidRefreshItem.dispose();
+ this._onRefreshItemChildren.dispose();
+ this._onDidRefreshItemChildren.dispose();
+ this._onDidDisposeItem.dispose();
}
}