diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts index bb60cd8719322c17949618333f79deca73951668..076d78d77254c9ef5e16dd13a8ae39592c5a31ac 100644 --- a/src/vs/base/browser/ui/list/list.ts +++ b/src/vs/base/browser/ui/list/list.ts @@ -115,3 +115,19 @@ export class ListError extends Error { super(`ListError [${user}] ${message}`); } } + +export abstract class CachedListVirtualDelegate implements IListVirtualDelegate { + + private cache = new WeakMap(); + + getHeight(element: T): number { + return this.cache.get(element) ?? this.estimateHeight(element); + } + + protected abstract estimateHeight(element: T): number; + abstract getTemplateId(element: T): string; + + setDynamicHeight(element: T, height: number): void { + this.cache.set(element, height); + } +} diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 27f5a3a7d8092df9832e3ff350dbc259c9242569..35f9ab1c6609091eab85baa56d7e29b6326b054e 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -46,7 +46,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget'; import { Variable } from 'vs/workbench/contrib/debug/common/debugModel'; import { SimpleReplElement, RawObjectReplElement, ReplEvaluationInput, ReplEvaluationResult } from 'vs/workbench/contrib/debug/common/replModel'; -import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { CachedListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { ITreeRenderer, ITreeNode, ITreeContextMenuEvent, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { renderExpressionValue, AbstractExpressionsRenderer, IExpressionTemplateData, renderVariable, IInputBoxOptions } from 'vs/workbench/contrib/debug/browser/baseDebugView'; @@ -795,29 +795,28 @@ class ReplRawObjectsRenderer implements ITreeRenderer { +class ReplDelegate extends CachedListVirtualDelegate { - private heightCache = new WeakMap(); - - constructor(private configurationService: IConfigurationService) { } + constructor(private configurationService: IConfigurationService) { + super(); + } getHeight(element: IReplElement): number { - const countNumberOfLines = (str: string) => Math.max(1, (str && str.match(/\r\n|\n/g) || []).length); - const hasValue = (e: any): e is { value: string } => typeof e.value === 'string'; - - // Give approximate heights. Repl has dynamic height so the tree will measure the actual height on its own. const config = this.configurationService.getValue('debug'); - const { fontSize, wordWrap } = config.console; - const rowHeight = Math.ceil(1.4 * fontSize); - if (!wordWrap) { - return rowHeight; - } - const cachedHeight = this.heightCache.get(element); - if (typeof cachedHeight === 'number') { - return cachedHeight; + if (!config.console.wordWrap) { + return Math.ceil(1.4 * config.console.fontSize); } + return super.getHeight(element); + } + + protected estimateHeight(element: IReplElement): number { + const config = this.configurationService.getValue('debug'); + const rowHeight = Math.ceil(1.4 * config.console.fontSize); + const countNumberOfLines = (str: string) => Math.max(1, (str && str.match(/\r\n|\n/g) || []).length); + const hasValue = (e: any): e is { value: string } => typeof e.value === 'string'; + // Calculate a rough overestimation for the height // For every 30 characters increase the number of lines needed if (hasValue(element)) { @@ -852,10 +851,6 @@ class ReplDelegate implements IListVirtualDelegate { // Empty elements should not have dynamic height since they will be invisible return element.toString().length > 0; } - - setDynamicHeight(element: IReplElement, height: number): void { - this.heightCache.set(element, height); - } } function isDebugSession(obj: any): obj is IDebugSession { diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 5a52035756705dedd03892baac2b289a75d44884..329d660bca6e1dd31633e75fe35cba17f923bc4e 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -12,7 +12,7 @@ import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria'; import { Button } from 'vs/base/browser/ui/button/button'; import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; -import { IListVirtualDelegate, ListAriaRootRole } from 'vs/base/browser/ui/list/list'; +import { ListAriaRootRole, CachedListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { DefaultStyleController } from 'vs/base/browser/ui/list/listWidget'; import { ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; @@ -1379,29 +1379,7 @@ export class SettingsTreeFilter implements ITreeFilter { } } -class SettingsTreeDelegate implements IListVirtualDelegate { - - private heightCache = new WeakMap(); - - getHeight(element: SettingsTreeGroupChild): number { - const cachedHeight = this.heightCache.get(element); - - if (typeof cachedHeight === 'number') { - return cachedHeight; - } - - if (element instanceof SettingsTreeGroupElement) { - if (element.isFirstGroup) { - return 31; - } - - return 40 + (7 * element.level); - } - - return element instanceof SettingsTreeSettingElement && element.valueType === SettingValueType.Boolean ? - 78 : - 104; - } +class SettingsTreeDelegate extends CachedListVirtualDelegate { getTemplateId(element: SettingsTreeGroupElement | SettingsTreeSettingElement | SettingsTreeNewExtensionsElement): string { if (element instanceof SettingsTreeGroupElement) { @@ -1447,8 +1425,16 @@ class SettingsTreeDelegate implements IListVirtualDelegate