Merge pull request #91594 from microsoft/rebornix/listview-item-heightchange
Update list view item height programmatically
This commit is contained in:
commit
63cb05ec37
3 changed files with 56 additions and 6 deletions
|
@ -21,6 +21,7 @@ import { equals, distinct } from 'vs/base/common/arrays';
|
|||
import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { disposableTimeout, Delayer } from 'vs/base/common/async';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
|
||||
interface IItem<T> {
|
||||
readonly id: string;
|
||||
|
@ -198,6 +199,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
get onDidScroll(): Event<ScrollEvent> { return this.scrollableElement.onScroll; }
|
||||
get onWillScroll(): Event<ScrollEvent> { return this.scrollableElement.onWillScroll; }
|
||||
get containerDomNode(): HTMLElement { return this.rowsContainer; }
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
|
@ -273,6 +275,31 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
this.layout();
|
||||
}
|
||||
|
||||
triggerScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent) {
|
||||
this.scrollableElement.triggerScrollFromMouseWheelEvent(browserEvent);
|
||||
}
|
||||
|
||||
updateElementHeight(index: number, size: number): void {
|
||||
if (this.items[index].size === size) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
|
||||
|
||||
const heightDiff = index < lastRenderRange.start ? size - this.items[index].size : 0;
|
||||
this.rangeMap.splice(index, 1, [{ size: size }]);
|
||||
this.items[index].size = size;
|
||||
|
||||
this.render(lastRenderRange, this.lastRenderTop + heightDiff, this.lastRenderHeight, undefined, undefined, true);
|
||||
|
||||
this.eventuallyUpdateScrollDimensions();
|
||||
|
||||
if (this.supportDynamicHeights) {
|
||||
this._rerender(this.lastRenderTop, this.lastRenderHeight);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
splice(start: number, deleteCount: number, elements: T[] = []): T[] {
|
||||
if (this.splicing) {
|
||||
throw new Error('Can\'t run recursive splices.');
|
||||
|
@ -516,14 +543,21 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
// Render
|
||||
|
||||
private render(renderTop: number, renderHeight: number, renderLeft: number, scrollWidth: number): void {
|
||||
const previousRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
|
||||
private render(previousRenderRange: IRange, renderTop: number, renderHeight: number, renderLeft: number | undefined, scrollWidth: number | undefined, updateItemsInDOM: boolean = false): void {
|
||||
const renderRange = this.getRenderRange(renderTop, renderHeight);
|
||||
|
||||
const rangesToInsert = Range.relativeComplement(renderRange, previousRenderRange);
|
||||
const rangesToRemove = Range.relativeComplement(previousRenderRange, renderRange);
|
||||
const beforeElement = this.getNextToLastElement(rangesToInsert);
|
||||
|
||||
if (updateItemsInDOM) {
|
||||
const rangesToUpdate = Range.intersect(previousRenderRange, renderRange);
|
||||
|
||||
for (let i = rangesToUpdate.start; i < rangesToUpdate.end; i++) {
|
||||
this.updateItemInDOM(this.items[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
for (const range of rangesToInsert) {
|
||||
for (let i = range.start; i < range.end; i++) {
|
||||
this.insertItemInDOM(i, beforeElement);
|
||||
|
@ -536,10 +570,13 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
}
|
||||
|
||||
this.rowsContainer.style.left = `-${renderLeft}px`;
|
||||
if (renderLeft !== undefined) {
|
||||
this.rowsContainer.style.left = `-${renderLeft}px`;
|
||||
}
|
||||
|
||||
this.rowsContainer.style.top = `-${renderTop}px`;
|
||||
|
||||
if (this.horizontalScrolling) {
|
||||
if (this.horizontalScrolling && scrollWidth !== undefined) {
|
||||
this.rowsContainer.style.width = `${Math.max(scrollWidth, this.renderWidth)}px`;
|
||||
}
|
||||
|
||||
|
@ -741,7 +778,8 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
private onScroll(e: ScrollEvent): void {
|
||||
try {
|
||||
this.render(e.scrollTop, e.height, e.scrollLeft, e.scrollWidth);
|
||||
const previousRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight);
|
||||
this.render(previousRenderRange, e.scrollTop, e.height, e.scrollLeft, e.scrollWidth);
|
||||
|
||||
if (this.supportDynamicHeights) {
|
||||
this._rerender(e.scrollTop, e.height);
|
||||
|
@ -1097,6 +1135,14 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
|
||||
const size = item.size;
|
||||
|
||||
if (item.row && item.row.domNode) {
|
||||
let newSize = item.row.domNode.offsetHeight;
|
||||
item.size = newSize;
|
||||
item.lastDynamicHeightWidth = this.renderWidth;
|
||||
return newSize - size;
|
||||
}
|
||||
|
||||
const row = this.cache.alloc(item.templateId);
|
||||
|
||||
row.domNode!.style.height = '';
|
||||
|
|
|
@ -1115,7 +1115,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
|||
private focus: Trait<T>;
|
||||
private selection: Trait<T>;
|
||||
private eventBufferer = new EventBufferer();
|
||||
private view: ListView<T>;
|
||||
protected view: ListView<T>;
|
||||
private spliceable: ISpliceable<T>;
|
||||
private styleController: IStyleController;
|
||||
private typeLabelController?: TypeLabelController<T>;
|
||||
|
|
|
@ -303,6 +303,10 @@ export abstract class AbstractScrollableElement extends Widget {
|
|||
this._revealOnScroll = value;
|
||||
}
|
||||
|
||||
public triggerScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent) {
|
||||
this._onMouseWheel(new StandardWheelEvent(browserEvent));
|
||||
}
|
||||
|
||||
// -------------------- mouse wheel scrolling --------------------
|
||||
|
||||
private _setListeningToMouseWheel(shouldListen: boolean): void {
|
||||
|
|
Loading…
Reference in a new issue