diff --git a/src/vs/base/browser/ui/list/list.css b/src/vs/base/browser/ui/list/list.css index 88e9c43e78b..666bdaa9167 100644 --- a/src/vs/base/browser/ui/list/list.css +++ b/src/vs/base/browser/ui/list/list.css @@ -29,6 +29,11 @@ height: 100%; } +.monaco-list.horizontal-scrolling .monaco-list-rows { + width: auto; + min-width: 100%; +} + .monaco-list-row { position: absolute; -moz-box-sizing: border-box; diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index 51129e1bd97..1acd51e015f 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -190,8 +190,8 @@ export class PagedList implements IDisposable { return this.list.getSelection(); } - layout(height?: number): void { - this.list.layout(height); + layout(height?: number, width?: number): void { + this.list.layout(height, width); } reveal(index: number, relativeTop?: number): void { diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index 701ab69ceb2..056bfa2b29f 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -21,7 +21,7 @@ import { memoize } from 'vs/base/common/decorators'; import { Range, IRange } from 'vs/base/common/range'; import { equals, distinct } from 'vs/base/common/arrays'; import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd'; -import { disposableTimeout } from 'vs/base/common/async'; +import { disposableTimeout, Delayer } from 'vs/base/common/async'; interface IItem { readonly id: string; @@ -29,8 +29,9 @@ interface IItem { readonly templateId: string; row: IRow | null; size: number; + width: number | undefined; hasDynamicHeight: boolean; - renderWidth: number | undefined; + lastDynamicHeightWidth: number | undefined; uri: string | undefined; dropTarget: boolean; dragStartDisposable: IDisposable; @@ -47,6 +48,7 @@ export interface IListViewOptions { readonly setRowLineHeight?: boolean; readonly supportDynamicHeights?: boolean; readonly mouseSupport?: boolean; + readonly horizontalScrolling?: boolean; } const DefaultOptions = { @@ -60,7 +62,8 @@ const DefaultOptions = { onDragStart(): void { }, onDragOver() { return false; }, drop() { } - } + }, + horizontalScrolling: false }; export class ElementsDragAndDropData implements IDragAndDropData { @@ -154,12 +157,14 @@ export class ListView implements ISpliceable, IDisposable { private scrollableElement: ScrollableElement; private _scrollHeight: number; private scrollableElementUpdateDisposable: IDisposable | null = null; + private scrollableElementWidthDelayer = new Delayer(50); private splicing = false; private dragOverAnimationDisposable: IDisposable | undefined; private dragOverAnimationStopDisposable: IDisposable = Disposable.None; private dragOverMouseY: number; private setRowLineHeight: boolean; private supportDynamicHeights: boolean; + private horizontalScrolling: boolean; private canUseTranslate3d: boolean | undefined = undefined; private dnd: IListViewDragAndDrop; @@ -189,6 +194,10 @@ export class ListView implements ISpliceable, IDisposable { renderers: IListRenderer[], options: IListViewOptions = DefaultOptions ) { + if (options.horizontalScrolling && options.supportDynamicHeights) { + throw new Error('Horizontal scrolling and dynamic heights not supported simultaneously'); + } + this.items = []; this.itemId = 0; this.rangeMap = new RangeMap(); @@ -206,13 +215,16 @@ export class ListView implements ISpliceable, IDisposable { this.domNode.className = 'monaco-list'; DOM.toggleClass(this.domNode, 'mouse-support', typeof options.mouseSupport === 'boolean' ? options.mouseSupport : true); + this.horizontalScrolling = getOrDefault(options, o => o.horizontalScrolling, DefaultOptions.horizontalScrolling); + DOM.toggleClass(this.domNode, 'horizontal-scrolling', this.horizontalScrolling); + this.rowsContainer = document.createElement('div'); this.rowsContainer.className = 'monaco-list-rows'; Gesture.addTarget(this.rowsContainer); this.scrollableElement = new ScrollableElement(this.rowsContainer, { alwaysConsumeMouseWheel: true, - horizontal: ScrollbarVisibility.Hidden, + horizontal: this.horizontalScrolling ? ScrollbarVisibility.Auto : ScrollbarVisibility.Hidden, vertical: getOrDefault(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode), useShadows: getOrDefault(options, o => o.useShadows, DefaultOptions.useShadows) }); @@ -275,8 +287,9 @@ export class ListView implements ISpliceable, IDisposable { element, templateId: this.virtualDelegate.getTemplateId(element), size: this.virtualDelegate.getHeight(element), + width: undefined, hasDynamicHeight: !!this.virtualDelegate.hasDynamicHeight && this.virtualDelegate.hasDynamicHeight(element), - renderWidth: undefined, + lastDynamicHeightWidth: undefined, row: null, uri: undefined, dropTarget: false, @@ -324,7 +337,7 @@ export class ListView implements ISpliceable, IDisposable { } } - this.updateScrollHeight(); + this.eventuallyUpdateScrollDimensions(); if (this.supportDynamicHeights) { this.rerender(this.scrollTop, this.renderHeight); @@ -333,18 +346,47 @@ export class ListView implements ISpliceable, IDisposable { return deleted.map(i => i.element); } - private updateScrollHeight(): void { + private eventuallyUpdateScrollDimensions(): void { this._scrollHeight = this.contentHeight; this.rowsContainer.style.height = `${this._scrollHeight}px`; if (!this.scrollableElementUpdateDisposable) { this.scrollableElementUpdateDisposable = DOM.scheduleAtNextAnimationFrame(() => { this.scrollableElement.setScrollDimensions({ scrollHeight: this._scrollHeight }); + this.updateScrollWidth(); this.scrollableElementUpdateDisposable = null; }); } } + private eventuallyUpdateScrollWidth(): void { + if (!this.horizontalScrolling) { + return; + } + + this.scrollableElementWidthDelayer.trigger(() => this.updateScrollWidth()); + } + + private updateScrollWidth(): void { + if (!this.horizontalScrolling) { + return; + } + + if (this.items.length === 0) { + this.scrollableElement.setScrollDimensions({ scrollWidth: 0 }); + } + + let scrollWidth = 0; + + for (const item of this.items) { + if (typeof item.width !== 'undefined') { + scrollWidth = Math.max(scrollWidth, item.width); + } + } + + this.scrollableElement.setScrollDimensions({ scrollWidth: scrollWidth + 10 }); + } + get length(): number { return this.items.length; } @@ -379,7 +421,7 @@ export class ListView implements ISpliceable, IDisposable { return this.rangeMap.indexAfter(position); } - layout(height?: number): void { + layout(height?: number, width?: number): void { let scrollDimensions: INewScrollDimensions = { height: height || DOM.getContentHeight(this.domNode) }; @@ -391,19 +433,25 @@ export class ListView implements ISpliceable, IDisposable { } this.scrollableElement.setScrollDimensions(scrollDimensions); - } - layoutWidth(width: number): void { - this.renderWidth = width; + if (typeof width !== 'undefined') { + this.renderWidth = width; - if (this.supportDynamicHeights) { - this.rerender(this.scrollTop, this.renderHeight); + if (this.supportDynamicHeights) { + this.rerender(this.scrollTop, this.renderHeight); + } + + if (this.horizontalScrolling) { + this.scrollableElement.setScrollDimensions({ + width: width || DOM.getContentWidth(this.domNode) + }); + } } } // Render - private render(renderTop: number, renderHeight: number): void { + private render(renderTop: number, renderHeight: number, renderLeft: number, scrollWidth: number): void { const previousRenderRange = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight); const renderRange = this.getRenderRange(renderTop, renderHeight); @@ -426,14 +474,16 @@ export class ListView implements ISpliceable, IDisposable { const canUseTranslate3d = !isWindows && !browser.isFirefox && browser.getZoomLevel() === 0; if (canUseTranslate3d) { - const transform = `translate3d(0px, -${renderTop}px, 0px)`; + const transform = `translate3d(-${renderLeft}px, -${renderTop}px, 0px)`; this.rowsContainer.style.transform = transform; this.rowsContainer.style.webkitTransform = transform; if (canUseTranslate3d !== this.canUseTranslate3d) { + this.rowsContainer.style.left = '0'; this.rowsContainer.style.top = '0'; } } else { + this.rowsContainer.style.left = `-${renderLeft}px`; this.rowsContainer.style.top = `-${renderTop}px`; if (canUseTranslate3d !== this.canUseTranslate3d) { @@ -442,7 +492,12 @@ export class ListView implements ISpliceable, IDisposable { } } + if (this.horizontalScrolling) { + this.rowsContainer.style.width = `${Math.max(scrollWidth, this.renderWidth)}px`; + } + this.canUseTranslate3d = canUseTranslate3d; + this.lastRenderTop = renderTop; this.lastRenderHeight = renderHeight; } @@ -467,10 +522,34 @@ export class ListView implements ISpliceable, IDisposable { this.updateItemInDOM(item, index); const renderer = this.renderers.get(item.templateId); + + if (!renderer) { + throw new Error(`No renderer found for template id ${item.templateId}`); + } + + if (this.horizontalScrolling) { + item.row.domNode!.style.width = 'fit-content'; + } + if (renderer) { renderer.renderElement(item.element, index, item.row.templateData); } + if (this.horizontalScrolling) { + item.width = DOM.getContentWidth(item.row.domNode!); + const style = window.getComputedStyle(item.row.domNode!); + + if (style.paddingLeft) { + item.width += parseFloat(style.paddingLeft); + } + + if (style.paddingRight) { + item.width += parseFloat(style.paddingRight); + } + + item.row.domNode!.style.width = ''; + } + const uri = this.dnd.getDragURI(item.element); item.dragStartDisposable.dispose(); @@ -479,6 +558,10 @@ export class ListView implements ISpliceable, IDisposable { const onDragStart = domEvent(item.row.domNode!, 'dragstart'); item.dragStartDisposable = onDragStart(event => this.onDragStart(item.element, uri, event)); } + + if (this.horizontalScrolling) { + this.eventuallyUpdateScrollWidth(); + } } private updateItemInDOM(item: IItem, index: number): void { @@ -507,6 +590,10 @@ export class ListView implements ISpliceable, IDisposable { this.cache.release(item.row!); item.row = null; + + if (this.horizontalScrolling) { + this.eventuallyUpdateScrollWidth(); + } } getScrollTop(): number { @@ -580,7 +667,7 @@ export class ListView implements ISpliceable, IDisposable { private onScroll(e: ScrollEvent): void { try { - this.render(e.scrollTop, e.height); + this.render(e.scrollTop, e.height, e.scrollLeft, e.scrollWidth); if (this.supportDynamicHeights) { this.rerender(e.scrollTop, e.height); @@ -879,7 +966,7 @@ export class ListView implements ISpliceable, IDisposable { if (!didChange) { if (heightDiff !== 0) { - this.updateScrollHeight(); + this.eventuallyUpdateScrollDimensions(); } const unrenderRanges = Range.relativeComplement(previousRenderRange, renderRange); @@ -922,7 +1009,7 @@ export class ListView implements ISpliceable, IDisposable { private probeDynamicHeight(index: number): number { const item = this.items[index]; - if (!item.hasDynamicHeight || item.renderWidth === this.renderWidth) { + if (!item.hasDynamicHeight || item.lastDynamicHeightWidth === this.renderWidth) { return 0; } @@ -936,7 +1023,7 @@ export class ListView implements ISpliceable, IDisposable { renderer.renderElement(item.element, index, row.templateData); } item.size = row.domNode!.offsetHeight; - item.renderWidth = this.renderWidth; + item.lastDynamicHeightWidth = this.renderWidth; this.rowsContainer.removeChild(row.domNode!); this.cache.release(row); diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 13daf5d8072..cd4ad77d3bb 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -798,6 +798,7 @@ export interface IListOptions extends IListStyles { readonly setRowLineHeight?: boolean; readonly supportDynamicHeights?: boolean; readonly mouseSupport?: boolean; + readonly horizontalScrolling?: boolean; } export interface IListStyles { @@ -1269,12 +1270,8 @@ export class List implements ISpliceable, IDisposable { this.view.domNode.focus(); } - layout(height?: number): void { - this.view.layout(height); - } - - layoutWidth(width: number): void { - this.view.layoutWidth(width); + layout(height?: number, width?: number): void { + this.view.layout(height, width); } setSelection(indexes: number[], browserEvent?: UIEvent): void { diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts index a78bb77de5e..18fecbbaafa 100644 --- a/src/vs/base/browser/ui/splitview/panelview.ts +++ b/src/vs/base/browser/ui/splitview/panelview.ts @@ -109,6 +109,8 @@ export abstract class Panel implements IView { return headerSize + maximumBodySize; } + width: number; + constructor(options: IPanelOptions = {}) { this._expanded = typeof options.expanded === 'undefined' ? true : !!options.expanded; this.ariaHeaderLabel = options.ariaHeaderLabel || ''; @@ -188,12 +190,12 @@ export abstract class Panel implements IView { this.renderBody(body); } - layout(size: number): void { + layout(height: number): void { const headerSize = this.headerVisible ? Panel.HEADER_SIZE : 0; if (this.isExpanded()) { - this.layoutBody(size - headerSize); - this.expandedSize = size; + this.layoutBody(height - headerSize, this.width); + this.expandedSize = height; } } @@ -224,7 +226,7 @@ export abstract class Panel implements IView { protected abstract renderHeader(container: HTMLElement): void; protected abstract renderBody(container: HTMLElement): void; - protected abstract layoutBody(size: number): void; + protected abstract layoutBody(height: number, width: number): void; dispose(): void { this.disposables = dispose(this.disposables); @@ -369,6 +371,7 @@ export class PanelView extends Disposable { private dndContext: IDndContext = { draggable: null }; private el: HTMLElement; private panelItems: IPanelItem[] = []; + private width: number; private splitview: SplitView; private animationTimer: number | null = null; @@ -398,6 +401,7 @@ export class PanelView extends Disposable { const panelItem = { panel, disposable: combinedDisposable(disposables) }; this.panelItems.splice(index, 0, panelItem); + panel.width = this.width; this.splitview.addView(panel, size, index); if (this.dnd) { @@ -453,8 +457,14 @@ export class PanelView extends Disposable { return this.splitview.getViewSize(index); } - layout(size: number): void { - this.splitview.layout(size); + layout(height: number, width: number): void { + this.width = width; + + for (const panelItem of this.panelItems) { + panelItem.panel.width = width; + } + + this.splitview.layout(height); } private setupAnimation(): void { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 2b5bc0486cc..1e2cf248eb2 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -766,12 +766,8 @@ export abstract class AbstractTree implements IDisposable return this.getHTMLElement() === document.activeElement; } - layout(height?: number): void { - this.view.layout(height); - } - - layoutWidth(width: number): void { - this.view.layoutWidth(width); + layout(height?: number, width?: number): void { + this.view.layout(height, width); } style(styles: IListStyles): void { diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index b982e323d45..4100092ef3d 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -348,8 +348,8 @@ export class AsyncDataTree implements IDisposable this.tree.domFocus(); } - layout(height?: number): void { - this.tree.layout(height); + layout(height?: number, width?: number): void { + this.tree.layout(height, width); } style(styles: IListStyles): void { diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index a5e63476dbb..1b4bfd87b19 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -427,7 +427,7 @@ export class ReferenceWidget extends PeekViewWidget { this._treeContainer.style.height = height; this._treeContainer.style.width = right; // forward - this._tree.layout(heightInPixel); + this._tree.layout(heightInPixel, widthInPixel); this._preview.layout(); // store layout data diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 9a1548a49cd..f19f80ebeb2 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -217,6 +217,7 @@ function handleTreeController(configuration: ITreeConfiguration, instantiationSe export class WorkbenchList extends List { readonly contextKeyService: IContextKeyService; + private readonly configurationService: IConfigurationService; private listHasSelectionOrFocus: IContextKey; private listDoubleSelection: IContextKey; @@ -232,19 +233,23 @@ export class WorkbenchList extends List { @IContextKeyService contextKeyService: IContextKeyService, @IListService listService: IListService, @IThemeService themeService: IThemeService, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IConfigurationService configurationService: IConfigurationService, @IKeybindingService keybindingService: IKeybindingService ) { + const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : configurationService.getValue(horizontalScrollingKey); + super(container, delegate, renderers, { keyboardSupport: false, styleController: new DefaultStyleController(getSharedListStyleSheet()), ...computeStyles(themeService.getTheme(), defaultListStyles), - ...toWorkbenchListOptions(options, configurationService, keybindingService) + ...toWorkbenchListOptions(options, configurationService, keybindingService), + horizontalScrolling } as IListOptions ); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); + this.configurationService = configurationService; const listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey.bindTo(this.contextKeyService); listSupportsMultiSelect.set(!(options.multipleSelectionSupport === false)); @@ -294,8 +299,9 @@ export class WorkbenchList extends List { export class WorkbenchPagedList extends PagedList { readonly contextKeyService: IContextKeyService; + private readonly configurationService: IConfigurationService; - private disposables: IDisposable[] = []; + private disposables: IDisposable[]; private _useAltAsMultipleSelectionModifier: boolean; @@ -307,19 +313,24 @@ export class WorkbenchPagedList extends PagedList { @IContextKeyService contextKeyService: IContextKeyService, @IListService listService: IListService, @IThemeService themeService: IThemeService, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IConfigurationService configurationService: IConfigurationService, @IKeybindingService keybindingService: IKeybindingService ) { + const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : configurationService.getValue(horizontalScrollingKey); super(container, delegate, renderers, { keyboardSupport: false, styleController: new DefaultStyleController(getSharedListStyleSheet()), ...computeStyles(themeService.getTheme(), defaultListStyles), - ...toWorkbenchListOptions(options, configurationService, keybindingService) + ...toWorkbenchListOptions(options, configurationService, keybindingService), + horizontalScrolling } as IListOptions ); + this.disposables = []; + this.contextKeyService = createScopedContextKeyService(contextKeyService, this); + this.configurationService = configurationService; const listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey.bindTo(this.contextKeyService); listSupportsMultiSelect.set(!(options.multipleSelectionSupport === false)); @@ -907,6 +918,7 @@ export class WorkbenchObjectTree, TFilterData = void> @IKeybindingService keybindingService: IKeybindingService ) { const keyboardNavigation = configurationService.getValue(keyboardNavigationSettingKey); + const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : configurationService.getValue(horizontalScrollingKey); super(container, delegate, renderers, { keyboardSupport: false, @@ -915,7 +927,8 @@ export class WorkbenchObjectTree, TFilterData = void> ...toWorkbenchListOptions(options, configurationService, keybindingService), indent: configurationService.getValue(treeIndentKey), simpleKeyboardNavigation: keyboardNavigation === 'simple', - filterOnType: keyboardNavigation === 'filter' + filterOnType: keyboardNavigation === 'filter', + horizontalScrolling }); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); @@ -999,6 +1012,7 @@ export class WorkbenchDataTree extends DataTree(keyboardNavigationSettingKey); + const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : configurationService.getValue(horizontalScrollingKey); super(container, delegate, renderers, dataSource, { keyboardSupport: false, @@ -1007,7 +1021,8 @@ export class WorkbenchDataTree extends DataTree extends Async @IKeybindingService keybindingService: IKeybindingService ) { const keyboardNavigation = configurationService.getValue(keyboardNavigationSettingKey); + const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : configurationService.getValue(horizontalScrollingKey); super(container, delegate, renderers, dataSource, { keyboardSupport: false, @@ -1094,7 +1110,8 @@ export class WorkbenchAsyncDataTree extends Async ...toWorkbenchListOptions(options, configurationService, keybindingService), indent: configurationService.getValue(treeIndentKey), simpleKeyboardNavigation: keyboardNavigation === 'simple', - filterOnType: keyboardNavigation === 'filter' + filterOnType: keyboardNavigation === 'filter', + horizontalScrolling }); this.contextKeyService = createScopedContextKeyService(contextKeyService, this); diff --git a/src/vs/workbench/browser/parts/notifications/notificationsList.ts b/src/vs/workbench/browser/parts/notifications/notificationsList.ts index 08669edfbf3..fd26a6fa1d6 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsList.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsList.ts @@ -77,7 +77,8 @@ export class NotificationsList extends Themable { [renderer], { ...this.options, - setRowLineHeight: false + setRowLineHeight: false, + horizontalScrolling: false } )); diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 5d8f7aceeae..f24bb0bcc09 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -248,7 +248,8 @@ export class QuickInputList { identityProvider: { getId: element => element.saneLabel }, openController: { shouldOpen: () => false }, // Workaround #58124 setRowLineHeight: false, - multipleSelectionSupport: false + multipleSelectionSupport: false, + horizontalScrolling: false } as IListOptions) as WorkbenchList; this.list.getHTMLElement().id = id; this.disposables.push(this.list); diff --git a/src/vs/workbench/browser/parts/views/panelViewlet.ts b/src/vs/workbench/browser/parts/views/panelViewlet.ts index f69ee245d69..8622e66392e 100644 --- a/src/vs/workbench/browser/parts/views/panelViewlet.ts +++ b/src/vs/workbench/browser/parts/views/panelViewlet.ts @@ -305,7 +305,7 @@ export class PanelViewlet extends Viewlet { } layout(dimension: Dimension): void { - this.panelview.layout(dimension.height); + this.panelview.layout(dimension.height, dimension.width); } getOptimalWidth(): number { diff --git a/src/vs/workbench/parts/debug/browser/breakpointsView.ts b/src/vs/workbench/parts/debug/browser/breakpointsView.ts index 1c572502b27..7361a91dbb4 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointsView.ts @@ -134,9 +134,9 @@ export class BreakpointsView extends ViewletPanel { } } - protected layoutBody(size: number): void { + protected layoutBody(height: number, width: number): void { if (this.list) { - this.list.layout(size); + this.list.layout(height, width); } } diff --git a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts index c8584cb4ef3..fabd77cd8c0 100644 --- a/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/parts/debug/browser/loadedScriptsView.ts @@ -500,8 +500,8 @@ export class LoadedScriptsView extends ViewletPanel { })); } - layoutBody(size: number): void { - this.tree.layout(size); + layoutBody(height: number, width: number): void { + this.tree.layout(height, width); } dispose(): void { diff --git a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts index 06797efabb7..38c16c1817c 100644 --- a/src/vs/workbench/parts/debug/electron-browser/callStackView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/callStackView.ts @@ -223,8 +223,8 @@ export class CallStackView extends ViewletPanel { })); } - layoutBody(size: number): void { - this.tree.layout(size); + layoutBody(height: number, width: number): void { + this.tree.layout(height, width); } private updateTreeSelection(): void { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts index 3cc5eabfdbe..b07b5f08469 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts @@ -85,7 +85,8 @@ export class DebugHoverWidget implements IContentWidget { this.dataSource, { ariaLabel: nls.localize('treeAriaLabel', "Debug Hover"), accessibilityProvider: new DebugHoverAccessibilityProvider(), - mouseSupport: false + mouseSupport: false, + horizontalScrolling: true }, this.contextKeyService, this.listService, this.themeService, this.configurationService, this.keybindingService); this.valueContainer = $('.value'); diff --git a/src/vs/workbench/parts/debug/electron-browser/repl.ts b/src/vs/workbench/parts/debug/electron-browser/repl.ts index 5183a792b49..e88a79861c7 100644 --- a/src/vs/workbench/parts/debug/electron-browser/repl.ts +++ b/src/vs/workbench/parts/debug/electron-browser/repl.ts @@ -269,7 +269,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati this.replDelegate.setWidth(dimension.width - 25, this.characterWidth); const treeHeight = dimension.height - this.replInputHeight; this.treeContainer.style.height = `${treeHeight}px`; - this.tree.layout(treeHeight); + this.tree.layout(treeHeight, dimension.width); } this.replInputContainer.style.height = `${this.replInputHeight}px`; diff --git a/src/vs/workbench/parts/debug/electron-browser/variablesView.ts b/src/vs/workbench/parts/debug/electron-browser/variablesView.ts index a1c4b9b5666..21c171270ca 100644 --- a/src/vs/workbench/parts/debug/electron-browser/variablesView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/variablesView.ts @@ -117,8 +117,8 @@ export class VariablesView extends ViewletPanel { })); } - layoutBody(size: number): void { - this.tree.layout(size); + layoutBody(width: number, height: number): void { + this.tree.layout(width, height); } private onMouseDblClick(e: ITreeMouseEvent): void { diff --git a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts index 409b49ad7ff..7b344d0abbf 100644 --- a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts @@ -113,8 +113,8 @@ export class WatchExpressionsView extends ViewletPanel { })); } - layoutBody(size: number): void { - this.tree.layout(size); + layoutBody(height: number, width: number): void { + this.tree.layout(height, width); } private onMouseDblClick(e: ITreeMouseEvent): void { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts index d28726e3bb0..58e70c850e1 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsViews.ts @@ -110,7 +110,8 @@ export class ExtensionsListView extends ViewletPanel { this.list = this.instantiationService.createInstance(WorkbenchPagedList, this.extensionsList, delegate, [renderer], { ariaLabel: localize('extensions', "Extensions"), multipleSelectionSupport: false, - setRowLineHeight: false + setRowLineHeight: false, + horizontalScrolling: false }) as WorkbenchPagedList; this.list.onContextMenu(e => this.onContextMenu(e), this, this.disposables); this.list.onFocusChange(e => extensionsViewState.onFocusChange(e.elements), this, this.disposables); @@ -128,9 +129,9 @@ export class ExtensionsListView extends ViewletPanel { .on(this.pin, this, this.disposables); } - layoutBody(size: number): void { - this.extensionsList.style.height = size + 'px'; - this.list.layout(size); + protected layoutBody(height: number, width: number): void { + this.extensionsList.style.height = height + 'px'; + this.list.layout(height, width); } async show(query: string): Promise> { diff --git a/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts index 4642d292181..d8b3b30fe8b 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -398,7 +398,8 @@ export class RuntimeExtensionsEditor extends BaseEditor { this._list = this._instantiationService.createInstance(WorkbenchList, parent, delegate, [renderer], { multipleSelectionSupport: false, - setRowLineHeight: false + setRowLineHeight: false, + horizontalScrolling: false }) as WorkbenchList; this._list.splice(0, this._list.length, this._elements); diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts index 46360bd1759..7bf3b826f07 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerView.ts @@ -147,8 +147,8 @@ export class ExplorerView extends ViewletPanel { setHeader(); } - protected layoutBody(size: number): void { - this.tree.layout(size); + protected layoutBody(height: number, width: number): void { + this.tree.layout(height, width); } renderBody(container: HTMLElement): void { diff --git a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts index ab9376bce14..06474606ccd 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/openEditorsView.ts @@ -307,9 +307,9 @@ export class OpenEditorsView extends ViewletPanel { return this.list; } - protected layoutBody(size: number): void { + protected layoutBody(height: number, width: number): void { if (this.list) { - this.list.layout(size); + this.list.layout(height, width); } } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts index 61e67c71b45..a87ac486e8c 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts @@ -151,7 +151,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { public layout(dimension: dom.Dimension): void { this.treeContainer.style.height = `${dimension.height}px`; - this.tree.layout(dimension.height); + this.tree.layout(dimension.height, dimension.width); if (this.filterInputActionItem) { this.filterInputActionItem.toggleLayout(dimension.width < 1200); } diff --git a/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts index 3605aad7566..72e4cd23c34 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingsEditor.ts @@ -407,7 +407,12 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor private createList(parent: HTMLElement): void { this.keybindingsListContainer = DOM.append(parent, $('.keybindings-list-container')); this.keybindingsList = this._register(this.instantiationService.createInstance(WorkbenchList, this.keybindingsListContainer, new Delegate(), [new KeybindingItemRenderer(this, this.keybindingsService)], - { identityProvider: { getId: e => e.id }, ariaLabel: localize('keybindingsLabel', "Keybindings"), setRowLineHeight: false })) as WorkbenchList; + { + identityProvider: { getId: e => e.id }, + ariaLabel: localize('keybindingsLabel', "Keybindings"), + setRowLineHeight: false, + horizontalScrolling: false + })) as WorkbenchList; this._register(this.keybindingsList.onContextMenu(e => this.onContextMenu(e))); this._register(this.keybindingsList.onFocusChange(e => this.onFocusChange(e))); this._register(this.keybindingsList.onDidFocus(() => { diff --git a/src/vs/workbench/parts/preferences/electron-browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/electron-browser/settingsEditor2.ts index 5fd660b0669..1eafe1e69c0 100644 --- a/src/vs/workbench/parts/preferences/electron-browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/electron-browser/settingsEditor2.ts @@ -1189,8 +1189,7 @@ export class SettingsEditor2 extends BaseEditor { const listHeight = dimension.height - (76 + 11 /* header height + padding*/); const settingsTreeHeight = listHeight - 14; this.settingsTreeContainer.style.height = `${settingsTreeHeight}px`; - this.settingsTree.layout(settingsTreeHeight); - this.settingsTree.layoutWidth(dimension.width); + this.settingsTree.layout(settingsTreeHeight, dimension.width); const tocTreeHeight = listHeight - 16; this.tocTreeContainer.style.height = `${tocTreeHeight}px`; diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index 19d30856bec..2f7895892bb 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -724,6 +724,7 @@ function convertValidationType(type: InputValidationType): MessageType { export class RepositoryPanel extends ViewletPanel { private cachedHeight: number | undefined = undefined; + private cachedWidth: number | undefined = undefined; private inputBoxContainer: HTMLElement; private inputBox: InputBox; private listContainer: HTMLElement; @@ -910,7 +911,7 @@ export class RepositoryPanel extends ViewletPanel { } } - layoutBody(height: number = this.cachedHeight): void { + layoutBody(height: number = this.cachedHeight, width: number = this.cachedWidth): void { if (height === undefined) { return; } @@ -924,7 +925,7 @@ export class RepositoryPanel extends ViewletPanel { const editorHeight = this.inputBox.height; const listHeight = height - (editorHeight + 12 /* margin */); this.listContainer.style.height = `${listHeight}px`; - this.list.layout(listHeight); + this.list.layout(listHeight, width); toggleClass(this.inputBoxContainer, 'scroll', editorHeight >= 134); } else { @@ -932,7 +933,7 @@ export class RepositoryPanel extends ViewletPanel { removeClass(this.inputBoxContainer, 'scroll'); this.listContainer.style.height = `${height}px`; - this.list.layout(height); + this.list.layout(height, width); } } diff --git a/src/vs/workbench/parts/search/browser/searchView.ts b/src/vs/workbench/parts/search/browser/searchView.ts index f5077e3bb16..e333d5aea17 100644 --- a/src/vs/workbench/parts/search/browser/searchView.ts +++ b/src/vs/workbench/parts/search/browser/searchView.ts @@ -900,7 +900,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel { this.resultsElement.style.height = searchResultContainerSize + 'px'; - this.tree.layout(searchResultContainerSize); + this.tree.layout(searchResultContainerSize, this.size.width); } layout(dimension: dom.Dimension): void {