提交 6a00c49f 编写于 作者: J Joao Moreno

list, tree: base renderers

上级 dda1aaa9
......@@ -5,6 +5,8 @@
import { GestureEvent } from 'vs/base/browser/touch';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
export interface IListVirtualDelegate<T> {
getHeight(element: T): number;
......@@ -58,4 +60,54 @@ export interface IIdentityProvider<T> {
export interface ITypeLabelProvider<T> {
getTypeLabel(element: T): { toString(): string; };
mightProducePrintableCharacter?(event: IKeyboardEvent): boolean;
}
/**
* Use this renderer when you want to re-render elements on account of
* an event firing.
*/
export abstract class AbstractListRenderer<T, TTemplateData> implements IListRenderer<T, TTemplateData> {
private renderedElements = new Map<T, TTemplateData>();
private listener: IDisposable;
constructor(onDidChange: Event<T | T[] | undefined>) {
this.listener = onDidChange(this.onDidChange, this);
}
renderElement(element: T, index: number, templateData: TTemplateData): void {
this.renderedElements.set(element, templateData);
}
disposeElement(element: T, index: number, templateData: TTemplateData): void {
this.renderedElements.delete(element);
}
private onDidChange(e: T | T[] | undefined) {
if (typeof e === 'undefined') {
this.renderedElements.forEach((templateData, element) => this.renderElement(element, -1 /* TODO@joao */, templateData));
} else if (Array.isArray(e)) {
for (const element of e) {
this.rerender(element);
}
} else {
this.rerender(e);
}
}
private rerender(element: T): void {
const templateData = this.renderedElements.get(element);
if (templateData) {
this.renderElement(element, -1 /* TODO@Joao */, templateData);
}
}
dispose(): void {
this.listener.dispose();
}
abstract readonly templateId: string;
abstract renderTemplate(container: HTMLElement): TTemplateData;
abstract disposeTemplate(templateData: TTemplateData): void;
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
import { Event } from 'vs/base/common/event';
import { Iterator } from 'vs/base/common/iterator';
import { IListRenderer } from 'vs/base/browser/ui/list/list';
import { IListRenderer, AbstractListRenderer } from 'vs/base/browser/ui/list/list';
export const enum TreeVisibility {
......@@ -127,3 +127,36 @@ export interface ITreeContextMenuEvent<T> {
element: T | null;
anchor: HTMLElement | { x: number; y: number; } | undefined;
}
/**
* Use this renderer when you want to re-render elements on account of
* an event firing.
*/
export abstract class AbstractTreeRenderer<T, TFilterData = void, TTemplateData = void>
extends AbstractListRenderer<ITreeNode<T, TFilterData>, TTemplateData>
implements ITreeRenderer<T, TFilterData, TTemplateData> {
private elementsToNodes = new Map<T, ITreeNode<T, TFilterData>>();
constructor(onDidChange: Event<T | T[] | undefined>) {
super(Event.map(onDidChange, e => {
if (typeof e === 'undefined') {
return undefined;
} else if (Array.isArray(e)) {
return e.map(e => this.elementsToNodes.get(e) || null).filter(e => e !== null);
} else {
return this.elementsToNodes.get(e) || null;
}
}));
}
renderElement(node: ITreeNode<T, TFilterData>, index: number, templateData: TTemplateData): void {
super.renderElement(node, index, templateData);
this.elementsToNodes.set(node.element, node);
}
disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: TTemplateData): void {
this.elementsToNodes.set(node.element, node);
super.disposeElement(node, index, templateData);
}
}
\ No newline at end of file
......@@ -8,7 +8,7 @@ import { IExpression, IDebugService } from 'vs/workbench/parts/debug/common/debu
import { Expression, Variable } from 'vs/workbench/parts/debug/common/debugModel';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IInputValidationOptions, InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
import { ITreeRenderer, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { ITreeRenderer, ITreeNode, AbstractTreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
......@@ -124,24 +124,16 @@ export interface IExpressionTemplateData {
toDispose: IDisposable[];
}
export abstract class AbstractExpressionsRenderer implements ITreeRenderer<IExpression, void, IExpressionTemplateData>, IDisposable {
protected renderedExpressions = new Map<IExpression, IExpressionTemplateData>();
private toDispose: IDisposable[];
export abstract class AbstractExpressionsRenderer
extends AbstractTreeRenderer<IExpression, void, IExpressionTemplateData>
implements ITreeRenderer<IExpression, void, IExpressionTemplateData>, IDisposable {
constructor(
@IDebugService protected debugService: IDebugService,
@IContextViewService private contextViewService: IContextViewService,
@IThemeService private themeService: IThemeService
) {
this.toDispose = [];
this.toDispose.push(this.debugService.getViewModel().onDidSelectExpression(expression => {
const template = this.renderedExpressions.get(expression);
if (template) {
template.enableInputBox(expression, this.getInputBoxOptions(expression));
}
}));
super(debugService.getViewModel().onDidSelectExpression);
}
abstract get templateId(): string;
......@@ -203,8 +195,10 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer<IExpr
return data;
}
renderElement({ element }: ITreeNode<IExpression>, index: number, data: IExpressionTemplateData): void {
this.renderedExpressions.set(element, data);
renderElement(node: ITreeNode<IExpression>, index: number, data: IExpressionTemplateData): void {
super.renderElement(node, index, data);
const { element } = node;
if (element === this.debugService.getViewModel().getSelectedExpression()) {
data.enableInputBox(element, this.getInputBoxOptions(element));
} else {
......@@ -218,13 +212,4 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer<IExpr
disposeTemplate(templateData: IExpressionTemplateData): void {
dispose(templateData.toDispose);
}
disposeElement(element: ITreeNode<Expression, void>): void {
this.renderedExpressions.delete(element.element);
}
dispose(): void {
this.renderedExpressions = undefined;
dispose(this.toDispose);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册