From 7cbbb2e51d1a10d0b3d2f85fb3a4e20284932645 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 4 Feb 2017 12:23:57 +0100 Subject: [PATCH] ScrollManager gets passed in the Scrollable --- .../browser/ui/scrollbar/scrollableElement.ts | 9 +- .../browser/viewLayout/layoutProvider.ts | 177 ++++++++++-------- .../browser/viewLayout/scrollManager.ts | 58 +----- 3 files changed, 114 insertions(+), 130 deletions(-) diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index e209c7abf651..8d59e014e29e 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -54,12 +54,17 @@ export class ScrollableElement extends Widget { private _onScroll = this._register(new Emitter()); public onScroll: Event = this._onScroll.event; - constructor(element: HTMLElement, options: ScrollableElementCreationOptions) { + constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable?: Scrollable) { super(); element.style.overflow = 'hidden'; this._options = resolveOptions(options); - this._scrollable = this._register(new Scrollable()); + if (typeof scrollable === 'undefined') { + this._scrollable = this._register(new Scrollable()); + } else { + this._scrollable = scrollable; + } + this._register(this._scrollable.onScroll((e) => { this._onDidScroll(e); this._onScroll.fire(e); diff --git a/src/vs/editor/browser/viewLayout/layoutProvider.ts b/src/vs/editor/browser/viewLayout/layoutProvider.ts index 94c8bf6473d6..4b8e00981e6c 100644 --- a/src/vs/editor/browser/viewLayout/layoutProvider.ts +++ b/src/vs/editor/browser/viewLayout/layoutProvider.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { IDisposable } from 'vs/base/common/lifecycle'; -import { ScrollbarVisibility } from 'vs/base/common/scrollable'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { LinesLayout } from 'vs/editor/common/viewLayout/linesLayout'; import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler'; -import { ScrollManager } from 'vs/editor/browser/viewLayout/scrollManager'; +import { EditorScrollbar } from 'vs/editor/browser/viewLayout/scrollManager'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; import { IViewEventBus } from 'vs/editor/common/view/viewContext'; @@ -99,34 +99,45 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa static LINES_HORIZONTAL_EXTRA_PX = 30; - private configuration: editorCommon.IConfiguration; - private privateViewEventBus: IViewEventBus; - private model: IViewModel; - private scrollManager: ScrollManager; - private linesLayout: LinesLayout; + private _toDispose: IDisposable[]; + private _configuration: editorCommon.IConfiguration; + private _privateViewEventBus: IViewEventBus; + private _model: IViewModel; + private _scrollManager: EditorScrollbar; + private _linesLayout: LinesLayout; + private _scrollable: Scrollable; constructor(configuration: editorCommon.IConfiguration, model: IViewModel, privateViewEventBus: IViewEventBus, linesContent: HTMLElement, viewDomNode: HTMLElement, overflowGuardDomNode: HTMLElement) { super(); - this.configuration = configuration; - this.privateViewEventBus = privateViewEventBus; - this.model = model; + this._scrollable = new Scrollable(); + this._scrollable.updateState({ + width: configuration.editor.layoutInfo.contentWidth, + height: configuration.editor.layoutInfo.contentHeight + }); + this._toDispose = []; + this._toDispose.push(this._scrollable); - this.scrollManager = new ScrollManager(configuration, privateViewEventBus, linesContent, viewDomNode, overflowGuardDomNode); + this._configuration = configuration; + this._privateViewEventBus = privateViewEventBus; + this._model = model; - this.configuration.setMaxLineNumber(this.model.getMaxLineNumber()); + this._scrollManager = new EditorScrollbar(this._scrollable, configuration, privateViewEventBus, linesContent, viewDomNode, overflowGuardDomNode); - this.linesLayout = new LinesLayout(this.model.getLineCount(), this.configuration.editor.lineHeight); + this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); + + this._linesLayout = new LinesLayout(this._model.getLineCount(), this._configuration.editor.lineHeight); this._updateHeight(); } public dispose(): void { - this.scrollManager.dispose(); + this._toDispose = dispose(this._toDispose); + this._scrollManager.dispose(); } - private updateLineCount(): void { - this.configuration.setMaxLineNumber(this.model.getMaxLineNumber()); + private _updateLineCount(): void { + this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); } // ---- begin view event handlers @@ -137,32 +148,35 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa } public onModelFlushed(): boolean { - this.linesLayout.onModelFlushed(this.model.getLineCount()); - this.updateLineCount(); + this._linesLayout.onModelFlushed(this._model.getLineCount()); + this._updateLineCount(); this._updateHeight(); return false; } public onModelLinesDeleted(e: editorCommon.IViewLinesDeletedEvent): boolean { - this.linesLayout.onModelLinesDeleted(e.fromLineNumber, e.toLineNumber); - this.updateLineCount(); + this._linesLayout.onModelLinesDeleted(e.fromLineNumber, e.toLineNumber); + this._updateLineCount(); this._updateHeight(); return false; } public onModelLinesInserted(e: editorCommon.IViewLinesInsertedEvent): boolean { - this.linesLayout.onModelLinesInserted(e.fromLineNumber, e.toLineNumber); - this.updateLineCount(); + this._linesLayout.onModelLinesInserted(e.fromLineNumber, e.toLineNumber); + this._updateLineCount(); this._updateHeight(); return false; } public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean { if (e.lineHeight) { - this.linesLayout.setLineHeight(this.configuration.editor.lineHeight); + this._linesLayout.setLineHeight(this._configuration.editor.lineHeight); } if (e.layoutInfo) { - this.scrollManager.onLayoutInfoChanged(); + this._scrollable.updateState({ + width: this._configuration.editor.layoutInfo.contentWidth, + height: this._configuration.editor.layoutInfo.contentHeight + }); this._emitLayoutChangedEvent(); } this._updateHeight(); @@ -170,7 +184,9 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa } private _updateHeight(): void { - this.scrollManager.setScrollHeight(this.getTotalHeight()); + this._scrollable.updateState({ + scrollHeight: this.getTotalHeight() + }); } // ---- end view event handlers @@ -179,15 +195,15 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa public getCurrentViewport(): editorCommon.Viewport { return new editorCommon.Viewport( - this.scrollManager.getScrollTop(), - this.scrollManager.getScrollLeft(), - this.scrollManager.getWidth(), - this.scrollManager.getHeight() + this._scrollable.getScrollTop(), + this._scrollable.getScrollLeft(), + this._scrollable.getWidth(), + this._scrollable.getHeight() ); } private _emitLayoutChangedEvent(): void { - this.privateViewEventBus.emit(editorCommon.EventType.ViewLayoutChanged, this.configuration.editor.layoutInfo); + this._privateViewEventBus.emit(editorCommon.EventType.ViewLayoutChanged, this._configuration.editor.layoutInfo); } public emitLayoutChangedEvent(): void { @@ -195,7 +211,7 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa } private _computeScrollWidth(maxLineWidth: number, viewportWidth: number): number { - let isViewportWrapping = this.configuration.editor.wrappingInfo.isViewportWrapping; + let isViewportWrapping = this._configuration.editor.wrappingInfo.isViewportWrapping; if (!isViewportWrapping) { return Math.max(maxLineWidth + LayoutProvider.LINES_HORIZONTAL_EXTRA_PX, viewportWidth); } @@ -204,7 +220,9 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa public onMaxLineWidthChanged(maxLineWidth: number): void { let newScrollWidth = this._computeScrollWidth(maxLineWidth, this.getCurrentViewport().width); - this.scrollManager.setScrollWidth(newScrollWidth); + this._scrollable.updateState({ + scrollWidth: newScrollWidth + }); // The height might depend on the fact that there is a horizontal scrollbar or not this._updateHeight(); @@ -213,22 +231,22 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa // ---- view state public saveState(): editorCommon.IViewState { - let scrollTop = this.scrollManager.getScrollTop(); - let firstLineNumberInViewport = this.linesLayout.getLineNumberAtOrAfterVerticalOffset(scrollTop); - let whitespaceAboveFirstLine = this.linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(firstLineNumberInViewport); + let scrollTop = this._scrollable.getScrollTop(); + let firstLineNumberInViewport = this._linesLayout.getLineNumberAtOrAfterVerticalOffset(scrollTop); + let whitespaceAboveFirstLine = this._linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(firstLineNumberInViewport); return { scrollTop: scrollTop, scrollTopWithoutViewZones: scrollTop - whitespaceAboveFirstLine, - scrollLeft: this.scrollManager.getScrollLeft() + scrollLeft: this._scrollable.getScrollLeft() }; } public restoreState(state: editorCommon.IViewState): void { let restoreScrollTop = state.scrollTop; - if (typeof state.scrollTopWithoutViewZones === 'number' && !this.linesLayout.hasWhitespace()) { + if (typeof state.scrollTopWithoutViewZones === 'number' && !this._linesLayout.hasWhitespace()) { restoreScrollTop = state.scrollTopWithoutViewZones; } - this.scrollManager.setScrollPosition({ + this._scrollable.updateState({ scrollLeft: state.scrollLeft, scrollTop: restoreScrollTop }); @@ -237,22 +255,22 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa // ---- IVerticalLayoutProvider public addWhitespace(afterLineNumber: number, ordinal: number, height: number): number { - return this.linesLayout.insertWhitespace(afterLineNumber, ordinal, height); + return this._linesLayout.insertWhitespace(afterLineNumber, ordinal, height); } public changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean { - return this.linesLayout.changeWhitespace(id, newAfterLineNumber, newHeight); + return this._linesLayout.changeWhitespace(id, newAfterLineNumber, newHeight); } public removeWhitespace(id: number): boolean { - return this.linesLayout.removeWhitespace(id); + return this._linesLayout.removeWhitespace(id); } public getVerticalOffsetForLineNumber(lineNumber: number): number { - return this.linesLayout.getVerticalOffsetForLineNumber(lineNumber); + return this._linesLayout.getVerticalOffsetForLineNumber(lineNumber); } public isAfterLines(verticalOffset: number): boolean { - return this.linesLayout.isAfterLines(verticalOffset); + return this._linesLayout.isAfterLines(verticalOffset); } public getLineNumberAtVerticalOffset(verticalOffset: number): number { - return this.linesLayout.getLineNumberAtOrAfterVerticalOffset(verticalOffset); + return this._linesLayout.getLineNumberAtOrAfterVerticalOffset(verticalOffset); } /** @@ -265,10 +283,10 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa * @return Basically, the `scrollHeight` for the editor content. */ private _getTotalHeight(viewport: editorCommon.Viewport, reserveHorizontalScrollbarHeight: number): number { - var totalLinesHeight = this.linesLayout.getLinesTotalHeight(); + var totalLinesHeight = this._linesLayout.getLinesTotalHeight(); - if (this.configuration.editor.viewInfo.scrollBeyondLastLine) { - totalLinesHeight += viewport.height - this.configuration.editor.lineHeight; + if (this._configuration.editor.viewInfo.scrollBeyondLastLine) { + totalLinesHeight += viewport.height - this._configuration.editor.lineHeight; } else { totalLinesHeight += reserveHorizontalScrollbarHeight; } @@ -278,64 +296,65 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa public getTotalHeight(): number { let reserveHorizontalScrollbarHeight = 0; - if (this.scrollManager.getScrollWidth() > this.scrollManager.getWidth()) { - if (this.configuration.editor.viewInfo.scrollbar.horizontal !== ScrollbarVisibility.Hidden) { - reserveHorizontalScrollbarHeight = this.configuration.editor.viewInfo.scrollbar.horizontalScrollbarSize; + if (this._scrollable.getScrollWidth() > this._scrollable.getWidth()) { + if (this._configuration.editor.viewInfo.scrollbar.horizontal !== ScrollbarVisibility.Hidden) { + reserveHorizontalScrollbarHeight = this._configuration.editor.viewInfo.scrollbar.horizontalScrollbarSize; } } return this._getTotalHeight(this.getCurrentViewport(), reserveHorizontalScrollbarHeight); } public getWhitespaceAtVerticalOffset(verticalOffset: number): editorCommon.IViewWhitespaceViewportData { - return this.linesLayout.getWhitespaceAtVerticalOffset(verticalOffset); + return this._linesLayout.getWhitespaceAtVerticalOffset(verticalOffset); } public getLinesViewportData(): IPartialViewLinesViewportData { const visibleBox = this.getCurrentViewport(); - return this.linesLayout.getLinesViewportData(visibleBox.top, visibleBox.top + visibleBox.height); + return this._linesLayout.getLinesViewportData(visibleBox.top, visibleBox.top + visibleBox.height); } public getWhitespaceViewportData(): editorCommon.IViewWhitespaceViewportData[] { const visibleBox = this.getCurrentViewport(); - return this.linesLayout.getWhitespaceViewportData(visibleBox.top, visibleBox.top + visibleBox.height); + return this._linesLayout.getWhitespaceViewportData(visibleBox.top, visibleBox.top + visibleBox.height); } public getWhitespaces(): editorCommon.IEditorWhitespace[] { - return this.linesLayout.getWhitespaces(); + return this._linesLayout.getWhitespaces(); } // ---- IScrollingProvider + + public getScrollWidth(): number { + return this._scrollable.getScrollWidth(); + } + public getScrollLeft(): number { + return this._scrollable.getScrollLeft(); + } + public getScrollHeight(): number { + return this._scrollable.getScrollHeight(); + } + public getScrollTop(): number { + return this._scrollable.getScrollTop(); + } + + public setScrollPosition(position: editorCommon.INewScrollPosition): void { + this._scrollable.updateState(position); + } + public getScrolledTopFromAbsoluteTop(top: number): number { + return top - this._scrollable.getScrollTop(); + } + public getOverviewRulerInsertData(): { parent: HTMLElement; insertBefore: HTMLElement; } { - let layoutInfo = this.scrollManager.getOverviewRulerLayoutInfo(); + let layoutInfo = this._scrollManager.getOverviewRulerLayoutInfo(); return { parent: layoutInfo.parent, insertBefore: layoutInfo.insertBefore }; } public getScrollbarContainerDomNode(): HTMLElement { - return this.scrollManager.getScrollbarContainerDomNode(); + return this._scrollManager.getScrollbarContainerDomNode(); } public delegateVerticalScrollbarMouseDown(browserEvent: MouseEvent): void { - this.scrollManager.delegateVerticalScrollbarMouseDown(browserEvent); + this._scrollManager.delegateVerticalScrollbarMouseDown(browserEvent); } - public getScrollWidth(): number { - return this.scrollManager.getScrollWidth(); - } - public getScrollLeft(): number { - return this.scrollManager.getScrollLeft(); - } - public getScrollHeight(): number { - return this.scrollManager.getScrollHeight(); - } - public getScrollTop(): number { - return this.scrollManager.getScrollTop(); - } - - public setScrollPosition(position: editorCommon.INewScrollPosition): void { - this.scrollManager.setScrollPosition(position); - } - public getScrolledTopFromAbsoluteTop(top: number): number { - return top - this.scrollManager.getScrollTop(); - } - public renderScrollbar(): void { - this.scrollManager.renderScrollbar(); + this._scrollManager.renderScrollbar(); } } \ No newline at end of file diff --git a/src/vs/editor/browser/viewLayout/scrollManager.ts b/src/vs/editor/browser/viewLayout/scrollManager.ts index cfa38268ad30..35da7d55a348 100644 --- a/src/vs/editor/browser/viewLayout/scrollManager.ts +++ b/src/vs/editor/browser/viewLayout/scrollManager.ts @@ -12,6 +12,7 @@ import { EventType, IConfiguration, IConfigurationChangedEvent, IScrollEvent, IN import { ClassNames } from 'vs/editor/browser/editorBrowser'; import { IViewEventBus } from 'vs/editor/common/view/viewContext'; import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart'; +import { Scrollable } from 'vs/base/common/scrollable'; function addPropertyIfPresent(src: any, dst: any, prop: string): void { if (src.hasOwnProperty(prop)) { @@ -19,8 +20,9 @@ function addPropertyIfPresent(src: any, dst: any, prop: string): void { } } -export class ScrollManager implements IDisposable { +export class EditorScrollbar implements IDisposable { + private scrollable: Scrollable; private configuration: IConfiguration; private privateViewEventBus: IViewEventBus; @@ -28,8 +30,9 @@ export class ScrollManager implements IDisposable { private linesContent: HTMLElement; private scrollbar: ScrollableElement; - constructor(configuration: IConfiguration, privateViewEventBus: IViewEventBus, linesContent: HTMLElement, viewDomNode: HTMLElement, overflowGuardDomNode: HTMLElement) { + constructor(scrollable: Scrollable, configuration: IConfiguration, privateViewEventBus: IViewEventBus, linesContent: HTMLElement, viewDomNode: HTMLElement, overflowGuardDomNode: HTMLElement) { this.toDispose = []; + this.scrollable = scrollable; this.configuration = configuration; this.privateViewEventBus = privateViewEventBus; this.linesContent = linesContent; @@ -56,10 +59,9 @@ export class ScrollManager implements IDisposable { addPropertyIfPresent(configScrollbarOpts, scrollbarOptions, 'arrowSize'); addPropertyIfPresent(configScrollbarOpts, scrollbarOptions, 'mouseWheelScrollSensitivity'); - this.scrollbar = new ScrollableElement(linesContent, scrollbarOptions); + this.scrollbar = new ScrollableElement(linesContent, scrollbarOptions, this.scrollable); PartFingerprints.write(this.scrollbar.getDomNode(), PartFingerprint.ScrollableElement); - this.onLayoutInfoChanged(); this.toDispose.push(this.scrollbar); this.toDispose.push(this.scrollbar.onScroll((e: IScrollEvent) => { this.privateViewEventBus.emit(EventType.ViewScrollChanged, e); @@ -87,7 +89,7 @@ export class ScrollManager implements IDisposable { if (lookAtScrollTop) { let deltaTop = domNode.scrollTop; if (deltaTop) { - newScrollPosition.scrollTop = this.getScrollTop() + deltaTop; + newScrollPosition.scrollTop = this.scrollable.getScrollTop() + deltaTop; domNode.scrollTop = 0; } } @@ -95,12 +97,12 @@ export class ScrollManager implements IDisposable { if (lookAtScrollLeft) { let deltaLeft = domNode.scrollLeft; if (deltaLeft) { - newScrollPosition.scrollLeft = this.getScrollLeft() + deltaLeft; + newScrollPosition.scrollLeft = this.scrollable.getScrollLeft() + deltaLeft; domNode.scrollLeft = 0; } } - this.setScrollPosition(newScrollPosition); + this.scrollable.updateState(newScrollPosition); }; // I've seen this happen both on the view dom node & on the lines content dom node. @@ -117,13 +119,6 @@ export class ScrollManager implements IDisposable { this.scrollbar.renderNow(); } - public onLayoutInfoChanged(): void { - this.scrollbar.updateState({ - width: this.configuration.editor.layoutInfo.contentWidth, - height: this.configuration.editor.layoutInfo.contentHeight - }); - } - public getOverviewRulerLayoutInfo(): IOverviewRulerLayoutInfo { return this.scrollbar.getOverviewRulerLayoutInfo(); } @@ -135,39 +130,4 @@ export class ScrollManager implements IDisposable { public delegateVerticalScrollbarMouseDown(browserEvent: MouseEvent): void { this.scrollbar.delegateVerticalScrollbarMouseDown(browserEvent); } - - public getWidth(): number { - return this.scrollbar.getWidth(); - } - public getScrollWidth(): number { - return this.scrollbar.getScrollWidth(); - } - public getScrollLeft(): number { - return this.scrollbar.getScrollLeft(); - } - - public getHeight(): number { - return this.scrollbar.getHeight(); - } - public getScrollHeight(): number { - return this.scrollbar.getScrollHeight(); - } - public getScrollTop(): number { - return this.scrollbar.getScrollTop(); - } - - public setScrollPosition(position: INewScrollPosition): void { - this.scrollbar.updateState(position); - } - - public setScrollHeight(scrollHeight: number): void { - this.scrollbar.updateState({ - scrollHeight: scrollHeight - }); - } - public setScrollWidth(scrollWidth: number): void { - this.scrollbar.updateState({ - scrollWidth: scrollWidth - }); - } }