tree: more wrapping code around list

This commit is contained in:
Joao Moreno
2018-06-23 23:53:07 +02:00
parent bddf469315
commit 44e89a0d64

View File

@@ -4,18 +4,89 @@
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import { IListOptions, List } from 'vs/base/browser/ui/list/listWidget';
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController } from 'vs/base/browser/ui/list/listWidget';
import { TreeModel, ITreeListElement, ITreeElement } from 'vs/base/browser/ui/tree/treeModel';
import { IIterator, empty } from 'vs/base/common/iterator';
import { IDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
import { append, $ } from 'vs/base/browser/dom';
export interface ITreeOptions<T> extends IListOptions<T> { }
function toTreeListOptions<T>(options?: IListOptions<T>): IListOptions<ITreeListElement<T>> {
if (!options) {
return undefined;
}
const DefaultOptions: ITreeOptions<any> = {
keyboardSupport: true,
mouseSupport: true,
multipleSelectionSupport: true
};
let identityProvider: IIdentityProvider<ITreeListElement<T>> | undefined = undefined;
let multipleSelectionController: IMultipleSelectionController<ITreeListElement<T>> | undefined = undefined;
if (options.identityProvider) {
identityProvider = el => options.identityProvider(el.element);
}
if (options.multipleSelectionController) {
multipleSelectionController = {
isSelectionSingleChangeEvent(e) {
return options.multipleSelectionController.isSelectionSingleChangeEvent({ ...e, element: e.element } as any);
},
isSelectionRangeChangeEvent(e) {
return options.multipleSelectionController.isSelectionRangeChangeEvent({ ...e, element: e.element } as any);
}
};
}
return {
...options,
identityProvider,
multipleSelectionController
};
}
class TreeDelegate<T> implements IDelegate<ITreeListElement<T>> {
constructor(private delegate: IDelegate<T>) { }
getHeight(element: ITreeListElement<T>): number {
return this.delegate.getHeight(element.element);
}
getTemplateId(element: ITreeListElement<T>): string {
return this.delegate.getTemplateId(element.element);
}
}
interface ITreeListTemplateData<T> {
twistie: HTMLElement;
templateData: T;
}
class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeListElement<T>, ITreeListTemplateData<TTemplateData>> {
readonly templateId: string;
constructor(private renderer: IRenderer<T, TTemplateData>) {
this.templateId = renderer.templateId;
}
renderTemplate(container: HTMLElement): ITreeListTemplateData<TTemplateData> {
const el = append(container, $('.monaco-tree-row'));
const twistie = append(el, $('.row-twistie'));
const contents = append(el, $('.row-contents'));
const templateData = this.renderer.renderTemplate(contents);
return { twistie, templateData };
}
renderElement(element: ITreeListElement<T>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
const { twistie } = templateData;
twistie.innerText = element.collapsed ? '▹' : '◢';
twistie.style.width = `${element.depth * 20}px`;
this.renderer.renderElement(element.element, index, templateData.templateData);
}
disposeTemplate(templateData: ITreeListTemplateData<TTemplateData>): void {
this.renderer.disposeTemplate(templateData.templateData);
}
}
export class Tree<T> implements IDisposable {
@@ -26,14 +97,13 @@ export class Tree<T> implements IDisposable {
container: HTMLElement,
delegate: IDelegate<T>,
renderers: IRenderer<T, any>[],
options: ITreeOptions<T> = DefaultOptions
options?: IListOptions<T>
) {
// TODO map provided args into these
const listDelegate: IDelegate<ITreeListElement<T>> = undefined;
const listRenderers: IRenderer<ITreeListElement<T>, any>[] = [];
const listOptions: ITreeOptions<ITreeListElement<T>> = undefined;
const treeDelegate = new TreeDelegate(delegate);
const treeRenderers = renderers.map(r => new TreeRenderer(r));
const treeOptions = toTreeListOptions(options);
this.view = new List(container, listDelegate, listRenderers, listOptions);
this.view = new List(container, treeDelegate, treeRenderers, treeOptions);
this.model = new TreeModel<T>(this.view);
}