listPaging.ts 4.1 KB
Newer Older
J
Joao Moreno 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import 'vs/css!./list';
import { IDisposable } from 'vs/base/common/lifecycle';
J
Joao Moreno 已提交
8
import { range } from 'vs/base/common/arrays';
J
Joao Moreno 已提交
9
import { IDelegate, IRenderer, IFocusChangeEvent, ISelectionChangeEvent } from './list';
J
João Moreno 已提交
10
import { List, IListOptions } from './listWidget';
J
Joao Moreno 已提交
11
import { IPagedModel } from 'vs/base/common/paging';
J
Joao Moreno 已提交
12
import Event, { mapEvent } from 'vs/base/common/event';
J
Joao Moreno 已提交
13 14 15 16 17 18 19 20 21 22

export interface IPagedRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
	renderPlaceholder(index: number, templateData: TTemplateData): void;
}

export interface ITemplateData<T> {
	data: T;
	disposable: IDisposable;
}

J
Joao Moreno 已提交
23
class PagedRenderer<TElement, TTemplateData> implements IRenderer<number, ITemplateData<TTemplateData>> {
J
Joao Moreno 已提交
24 25 26

	get templateId(): string { return this.renderer.templateId; }

J
Joao Moreno 已提交
27 28
	constructor(
		private renderer: IPagedRenderer<TElement, TTemplateData>,
J
Joao Moreno 已提交
29
		private modelProvider: () => IPagedModel<TElement>
J
Johannes Rieken 已提交
30
	) { }
J
Joao Moreno 已提交
31 32 33

	renderTemplate(container: HTMLElement): ITemplateData<TTemplateData> {
		const data = this.renderer.renderTemplate(container);
J
Johannes Rieken 已提交
34
		return { data, disposable: { dispose: () => { } } };
J
Joao Moreno 已提交
35 36 37 38 39
	}

	renderElement(index: number, _: number, data: ITemplateData<TTemplateData>): void {
		data.disposable.dispose();

J
Joao Moreno 已提交
40
		const model = this.modelProvider();
J
Joao Moreno 已提交
41

J
Joao Moreno 已提交
42 43
		if (model.isResolved(index)) {
			return this.renderer.renderElement(model.get(index), index, data.data);
J
Joao Moreno 已提交
44 45
		}

J
Joao Moreno 已提交
46
		const promise = model.resolve(index);
J
Joao Moreno 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60
		data.disposable = { dispose: () => promise.cancel() };

		this.renderer.renderPlaceholder(index, data.data);
		promise.done(entry => this.renderer.renderElement(entry, index, data.data));
	}

	disposeTemplate(data: ITemplateData<TTemplateData>): void {
		data.disposable.dispose();
		data.disposable = null;
		this.renderer.disposeTemplate(data.data);
		data.data = null;
	}
}

J
Joao Moreno 已提交
61
export class PagedList<T> {
J
Joao Moreno 已提交
62

J
Joao Moreno 已提交
63
	private list: List<number>;
J
Joao Moreno 已提交
64
	private _model: IPagedModel<T>;
J
Joao Moreno 已提交
65
	get onDOMFocus(): Event<FocusEvent> { return this.list.onDOMFocus; }
J
Joao Moreno 已提交
66 67 68

	constructor(
		container: HTMLElement,
J
Joao Moreno 已提交
69
		delegate: IDelegate<number>,
J
João Moreno 已提交
70 71
		renderers: IPagedRenderer<T, any>[],
		options: IListOptions = {}
J
Joao Moreno 已提交
72
	) {
J
Joao Moreno 已提交
73
		const pagedRenderers = renderers.map(r => new PagedRenderer<T, ITemplateData<T>>(r, () => this.model));
J
João Moreno 已提交
74
		this.list = new List(container, delegate, pagedRenderers, options);
J
Joao Moreno 已提交
75 76
	}

77 78 79 80
	get widget(): List<number> {
		return this.list;
	}

J
Joao Moreno 已提交
81 82 83 84 85 86
	get onFocusChange(): Event<IFocusChangeEvent<T>> {
		return mapEvent(this.list.onFocusChange, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
	}

	get onSelectionChange(): Event<ISelectionChangeEvent<T>> {
		return mapEvent(this.list.onSelectionChange, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
J
Joao Moreno 已提交
87 88
	}

J
Joao Moreno 已提交
89
	get model(): IPagedModel<T> {
J
Joao Moreno 已提交
90
		return this._model;
J
Joao Moreno 已提交
91 92
	}

J
Joao Moreno 已提交
93
	set model(model: IPagedModel<T>) {
J
Joao Moreno 已提交
94
		this._model = model;
J
Joao Moreno 已提交
95
		this.list.splice(0, this.list.length, range(model.length));
J
Joao Moreno 已提交
96 97
	}

J
Joao Moreno 已提交
98 99 100 101
	get length(): number {
		return this.list.length;
	}

J
Joao Moreno 已提交
102 103 104 105
	get scrollTop(): number {
		return this.list.scrollTop;
	}

J
Joao Moreno 已提交
106 107 108 109
	set scrollTop(scrollTop: number) {
		this.list.scrollTop = scrollTop;
	}

J
Joao Moreno 已提交
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
	focusNext(n?: number, loop?: boolean): void {
		this.list.focusNext(n, loop);
	}

	focusPrevious(n?: number, loop?: boolean): void {
		this.list.focusPrevious(n, loop);
	}

	selectNext(n?: number, loop?: boolean): void {
		this.list.selectNext(n, loop);
	}

	selectPrevious(n?: number, loop?: boolean): void {
		this.list.selectPrevious(n, loop);
	}

J
Joao Moreno 已提交
126 127 128 129 130 131 132 133
	focusNextPage(): void {
		this.list.focusNextPage();
	}

	focusPreviousPage(): void {
		this.list.focusPreviousPage();
	}

J
Joao Moreno 已提交
134 135 136 137
	getFocus(): number[] {
		return this.list.getFocus();
	}

J
Joao Moreno 已提交
138 139
	setSelection(indexes: number[]): void {
		this.list.setSelection(indexes);
J
Joao Moreno 已提交
140 141
	}

J
Joao Moreno 已提交
142 143
	layout(height?: number): void {
		this.list.layout(height);
J
Joao Moreno 已提交
144
	}
J
Joao Moreno 已提交
145 146 147 148

	reveal(index: number, relativeTop?: number): void {
		this.list.reveal(index, relativeTop);
	}
J
Joao Moreno 已提交
149
}