From 5ab4210487330074b85311a8d4d9cee497a588a0 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sun, 5 Feb 2017 12:31:01 +0100 Subject: [PATCH] Establish IViewLayout shape --- src/vs/editor/browser/view/viewImpl.ts | 14 ++- src/vs/editor/browser/view/viewOverlays.ts | 22 ++-- .../browser/viewLayout/layoutProvider.ts | 106 ++---------------- .../currentLineHighlight.ts | 12 +- .../currentLineMarginHighlight.ts | 8 +- .../browser/viewParts/lines/viewLines.ts | 38 +++---- .../editor/browser/viewParts/margin/margin.ts | 10 +- .../editor/browser/viewParts/rulers/rulers.ts | 10 +- .../browser/viewParts/viewZones/viewZones.ts | 20 ++-- src/vs/editor/common/view/renderingContext.ts | 30 ++--- src/vs/editor/common/viewModel/viewModel.ts | 46 +++++++- .../editor/common/viewModel/viewModelImpl.ts | 6 +- 12 files changed, 137 insertions(+), 185 deletions(-) diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 6de54eb7adc..53d0fcab571 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -127,7 +127,6 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp // - whitespaces (a.k.a. view zones) management & co. // - line heights updating & co. this.layoutProvider = new LayoutProvider(configuration, model, this.eventDispatcher); - this.eventDispatcher.addEventHandler(this.layoutProvider); this._scrollbar = new EditorScrollbar(this.layoutProvider.getScrollable(), configuration, this.eventDispatcher, this.linesContent, this.domNode, this.overflowGuardContainer); @@ -448,6 +447,18 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp // --- begin event handlers + public onModelFlushed(): boolean { + this.layoutProvider.onModelFlushed(); + return false; + } + public onModelLinesDeleted(e: editorCommon.IViewLinesDeletedEvent): boolean { + this.layoutProvider.onModelLinesDeleted(e); + return false; + } + public onModelLinesInserted(e: editorCommon.IViewLinesInsertedEvent): boolean { + this.layoutProvider.onModelLinesInserted(e); + return false; + } public onLayoutChanged(layoutInfo: editorCommon.EditorLayoutInfo): boolean { if (browser.isChrome) { /* tslint:disable:no-unused-variable */ @@ -479,6 +490,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp if (e.viewInfo.ariaLabel) { this.textArea.setAttribute('aria-label', this._context.configuration.editor.viewInfo.ariaLabel); } + this.layoutProvider.onConfigurationChanged(e); return false; } public onScrollChanged(e: editorCommon.IScrollEvent): boolean { diff --git a/src/vs/editor/browser/view/viewOverlays.ts b/src/vs/editor/browser/view/viewOverlays.ts index dcd8fe9345b..dd6ab8f1f13 100644 --- a/src/vs/editor/browser/view/viewOverlays.ts +++ b/src/vs/editor/browser/view/viewOverlays.ts @@ -12,21 +12,21 @@ import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay'; import { Configuration } from 'vs/editor/browser/config/configuration'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; -import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; export class ViewOverlays extends ViewLayer { private _dynamicOverlays: DynamicViewOverlay[]; private _isFocused: boolean; - _layoutProvider: ILayoutProvider; + protected _viewLayout: IViewLayout; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(context); this._dynamicOverlays = []; this._isFocused = false; - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; this.domNode.setClassName('view-overlays'); } @@ -48,7 +48,7 @@ export class ViewOverlays extends ViewLayer { public dispose(): void { super.dispose(); - this._layoutProvider = null; + this._viewLayout = null; for (let i = 0, len = this._dynamicOverlays.length; i < len; i++) { let dynamicOverlay = this._dynamicOverlays[i]; @@ -183,10 +183,10 @@ export class ContentViewOverlays extends ViewOverlays { private _scrollWidth: number; private _contentWidth: number; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { - super(context, layoutProvider); + constructor(context: ViewContext, viewLayout: IViewLayout) { + super(context, viewLayout); - this._scrollWidth = this._layoutProvider.getScrollWidth(); + this._scrollWidth = this._viewLayout.getScrollWidth(); this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; this.domNode.setWidth(this._scrollWidth); @@ -216,8 +216,8 @@ export class MarginViewOverlays extends ViewOverlays { private _contentLeft: number; private _canUseTranslate3d: boolean; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { - super(context, layoutProvider); + constructor(context: ViewContext, viewLayout: IViewLayout) { + super(context, viewLayout); this._contentLeft = context.configuration.editor.layoutInfo.contentLeft; this._canUseTranslate3d = context.configuration.editor.viewInfo.canUseTranslate3d; @@ -250,7 +250,7 @@ export class MarginViewOverlays extends ViewOverlays { _viewOverlaysRender(ctx: IRestrictedRenderingContext): void { super._viewOverlaysRender(ctx); - let height = Math.min(this._layoutProvider.getTotalHeight(), 1000000); + let height = Math.min(this._viewLayout.getTotalHeight(), 1000000); this.domNode.setHeight(height); this.domNode.setWidth(this._contentLeft); } diff --git a/src/vs/editor/browser/viewLayout/layoutProvider.ts b/src/vs/editor/browser/viewLayout/layoutProvider.ts index 84d29c69671..8405939890d 100644 --- a/src/vs/editor/browser/viewLayout/layoutProvider.ts +++ b/src/vs/editor/browser/viewLayout/layoutProvider.ts @@ -8,89 +8,11 @@ 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 { IViewModel } from 'vs/editor/common/viewModel/viewModel'; +import { IViewLayout, IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; import { IViewEventBus } from 'vs/editor/common/view/viewContext'; -import { ILayoutProvider as IRenderingLayoutProvider } from 'vs/editor/common/view/renderingContext'; -export interface IWhitespaceManager { - /** - * Reserve rendering space. - * @param height is specified in pixels. - * @return an identifier that can be later used to remove or change the whitespace. - */ - addWhitespace(afterLineNumber: number, ordinal: number, height: number): number; - - /** - * Change the properties of a whitespace. - * @param height is specified in pixels. - */ - changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean; - - /** - * Remove rendering space - */ - removeWhitespace(id: number): boolean; - - /** - * Get the layout information for whitespaces currently in the viewport - */ - getWhitespaceViewportData(): editorCommon.IViewWhitespaceViewportData[]; - - getWhitespaces(): editorCommon.IEditorWhitespace[]; -} - -export interface ILayoutProvider extends IVerticalLayoutProvider, IScrollingProvider { - - dispose(): void; - - getCurrentViewport(): editorCommon.Viewport; - - onMaxLineWidthChanged(width: number): void; - - saveState(): editorCommon.IViewState; - restoreState(state: editorCommon.IViewState): void; -} - -export interface IScrollingProvider { - - // This is for the glyphs, line numbers, etc. - getScrolledTopFromAbsoluteTop(top: number): number; - - getScrollWidth(): number; - getScrollLeft(): number; - - getScrollHeight(): number; - getScrollTop(): number; - - setScrollPosition(position: editorCommon.INewScrollPosition): void; -} - -export interface IVerticalLayoutProvider { - /** - * Compute vertical offset (top) of line number - */ - getVerticalOffsetForLineNumber(lineNumber: number): number; - - /** - * Return line number at `verticalOffset` or closest line number - */ - getLineNumberAtVerticalOffset(verticalOffset: number): number; - - /** - * Compute content height (including one extra scroll page if necessary) - */ - getTotalHeight(): number; - - /** - * Compute the lines that need to be rendered in the current viewport position. - */ - getLinesViewportData(): IPartialViewLinesViewportData; - -} - -export class LayoutProvider extends ViewEventHandler implements IDisposable, ILayoutProvider, IWhitespaceManager, IRenderingLayoutProvider { +export class LayoutProvider implements IDisposable, IViewLayout { static LINES_HORIZONTAL_EXTRA_PX = 30; @@ -102,8 +24,6 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa private _scrollable: Scrollable; constructor(configuration: editorCommon.IConfiguration, model: IViewModel, privateViewEventBus: IViewEventBus) { - super(); - this._scrollable = new Scrollable(); this._scrollable.updateState({ width: configuration.editor.layoutInfo.contentWidth, @@ -131,38 +51,31 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa return this._scrollable; } - private _updateLineCount(): void { - this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); - } - public onHeightMaybeChanged(): void { this._updateHeight(); } // ---- begin view event handlers - public onModelFlushed(): boolean { + public onModelFlushed(): void { this._linesLayout.onModelFlushed(this._model.getLineCount()); - this._updateLineCount(); + this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); this._updateHeight(); - return false; } - public onModelLinesDeleted(e: editorCommon.IViewLinesDeletedEvent): boolean { + public onModelLinesDeleted(e: editorCommon.IViewLinesDeletedEvent): void { this._linesLayout.onModelLinesDeleted(e.fromLineNumber, e.toLineNumber); - this._updateLineCount(); + this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); this._updateHeight(); - return false; } - public onModelLinesInserted(e: editorCommon.IViewLinesInsertedEvent): boolean { + public onModelLinesInserted(e: editorCommon.IViewLinesInsertedEvent): void { this._linesLayout.onModelLinesInserted(e.fromLineNumber, e.toLineNumber); - this._updateLineCount(); + this._configuration.setMaxLineNumber(this._model.getMaxLineNumber()); this._updateHeight(); - return false; } - public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): boolean { + public onConfigurationChanged(e: editorCommon.IConfigurationChangedEvent): void { if (e.lineHeight) { this._linesLayout.setLineHeight(this._configuration.editor.lineHeight); } @@ -174,7 +87,6 @@ export class LayoutProvider extends ViewEventHandler implements IDisposable, ILa this._emitLayoutChangedEvent(); } this._updateHeight(); - return false; } private _updateHeight(): void { diff --git a/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts b/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts index 4c80585ed8d..488683ba81a 100644 --- a/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts +++ b/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts @@ -10,33 +10,33 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { IRenderingContext } from 'vs/editor/common/view/renderingContext'; -import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; export class CurrentLineHighlightOverlay extends DynamicViewOverlay { private _context: ViewContext; private _lineHeight: number; private _readOnly: boolean; private _renderLineHighlight: 'none' | 'gutter' | 'line' | 'all'; - private _layoutProvider: ILayoutProvider; + private _viewLayout: IViewLayout; private _selectionIsEmpty: boolean; private _primaryCursorIsInEditableRange: boolean; private _primaryCursorLineNumber: number; private _scrollWidth: number; private _contentWidth: number; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(); this._context = context; this._lineHeight = this._context.configuration.editor.lineHeight; this._readOnly = this._context.configuration.editor.readOnly; this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight; - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; this._selectionIsEmpty = true; this._primaryCursorIsInEditableRange = true; this._primaryCursorLineNumber = 1; - this._scrollWidth = this._layoutProvider.getScrollWidth(); + this._scrollWidth = this._viewLayout.getScrollWidth(); this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; this._context.addEventHandler(this); @@ -53,7 +53,7 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay { this._primaryCursorIsInEditableRange = true; this._selectionIsEmpty = true; this._primaryCursorLineNumber = 1; - this._scrollWidth = this._layoutProvider.getScrollWidth(); + this._scrollWidth = this._viewLayout.getScrollWidth(); return true; } public onModelLinesDeleted(e: editorCommon.IViewLinesDeletedEvent): boolean { diff --git a/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts b/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts index 77e71f3f900..8f26d223c1a 100644 --- a/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts +++ b/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts @@ -10,24 +10,24 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { IRenderingContext } from 'vs/editor/common/view/renderingContext'; -import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay { private _context: ViewContext; private _lineHeight: number; private _renderLineHighlight: 'none' | 'gutter' | 'line' | 'all'; - private _layoutProvider: ILayoutProvider; + private _viewLayout: IViewLayout; private _primaryCursorIsInEditableRange: boolean; private _primaryCursorLineNumber: number; private _contentLeft: number; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(); this._context = context; this._lineHeight = this._context.configuration.editor.lineHeight; this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight; - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; this._primaryCursorIsInEditableRange = true; this._primaryCursorLineNumber = 1; diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index c546e82dc8d..934cf3b0106 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -17,7 +17,7 @@ import { Configuration } from 'vs/editor/browser/config/configuration'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; import { IViewLines, VisibleRange, LineVisibleRanges } from 'vs/editor/common/view/renderingContext'; -import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart'; class LastRenderedData { @@ -58,7 +58,7 @@ export class ViewLines extends ViewLayer implements IViewLines { private static HORIZONTAL_EXTRA_PX = 30; - private _layoutProvider: ILayoutProvider; + private _viewLayout: IViewLayout; private _textRangeRestingSpot: HTMLElement; // --- config @@ -75,14 +75,14 @@ export class ViewLines extends ViewLayer implements IViewLines { private _lastCursorRevealRangeHorizontallyEvent: editorCommon.IViewRevealRangeEvent; private _lastRenderedData: LastRenderedData; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(context); this._lineHeight = this._context.configuration.editor.lineHeight; this._isViewportWrapping = this._context.configuration.editor.wrappingInfo.isViewportWrapping; this._revealHorizontalRightPadding = this._context.configuration.editor.viewInfo.revealHorizontalRightPadding; this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d; this._viewLineOptions = new ViewLineOptions(this._context.configuration); - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; PartFingerprints.write(this.domNode.domNode, PartFingerprint.ViewLines); this.domNode.setClassName(ClassNames.VIEW_LINES); @@ -103,7 +103,7 @@ export class ViewLines extends ViewLayer implements IViewLines { public dispose(): void { this._asyncUpdateLineWidths.dispose(); - this._layoutProvider = null; + this._viewLayout = null; super.dispose(); } @@ -175,13 +175,13 @@ export class ViewLines extends ViewLayer implements IViewLines { } public onCursorRevealRange(e: editorCommon.IViewRevealRangeEvent): boolean { - let newScrollTop = this._computeScrollTopToRevealRange(this._layoutProvider.getCurrentViewport(), e.range, e.verticalType); + let newScrollTop = this._computeScrollTopToRevealRange(this._viewLayout.getCurrentViewport(), e.range, e.verticalType); if (e.revealHorizontal) { this._lastCursorRevealRangeHorizontallyEvent = e; } - this._layoutProvider.setScrollPosition({ + this._viewLayout.setScrollPosition({ scrollTop: newScrollTop }); @@ -189,9 +189,9 @@ export class ViewLines extends ViewLayer implements IViewLines { } public onCursorScrollRequest(e: editorCommon.IViewScrollRequestEvent): boolean { - let currentScrollTop = this._layoutProvider.getScrollTop(); + let currentScrollTop = this._viewLayout.getScrollTop(); let newScrollTop = currentScrollTop + e.deltaLines * this._lineHeight; - this._layoutProvider.setScrollPosition({ + this._viewLayout.setScrollPosition({ scrollTop: newScrollTop }); return true; @@ -371,7 +371,7 @@ export class ViewLines extends ViewLayer implements IViewLines { continue; } - let adjustedLineNumberVerticalOffset = this._layoutProvider.getVerticalOffsetForLineNumber(lineNumber) - bigNumbersDelta + deltaTop; + let adjustedLineNumberVerticalOffset = this._viewLayout.getVerticalOffsetForLineNumber(lineNumber) - bigNumbersDelta + deltaTop; for (let i = 0, len = visibleRangesForLine.length; i < len; i++) { result.push(new VisibleRange(adjustedLineNumberVerticalOffset, visibleRangesForLine[i].left, visibleRangesForLine[i].width)); } @@ -420,8 +420,8 @@ export class ViewLines extends ViewLayer implements IViewLines { super._renderLines(viewportData); this._lastRenderedData.setBigNumbersDelta(viewportData.bigNumbersDelta); this._lastRenderedData.setCurrentVisibleRange(viewportData.visibleRange); - this.domNode.setWidth(this._layoutProvider.getScrollWidth()); - this.domNode.setHeight(Math.min(this._layoutProvider.getTotalHeight(), 1000000)); + this.domNode.setWidth(this._viewLayout.getScrollWidth()); + this.domNode.setHeight(Math.min(this._viewLayout.getTotalHeight(), 1000000)); // (2) execute DOM writing that forces sync layout (e.g. textArea manipulation) onAfterLinesRendered(); @@ -446,21 +446,21 @@ export class ViewLines extends ViewLayer implements IViewLines { } // set `scrollLeft` - this._layoutProvider.setScrollPosition({ + this._viewLayout.setScrollPosition({ scrollLeft: newScrollLeft.scrollLeft }); } // (4) handle scrolling if (this._canUseTranslate3d) { - let transform = 'translate3d(' + -this._layoutProvider.getScrollLeft() + 'px, ' + viewportData.visibleRangesDeltaTop + 'px, 0px)'; + let transform = 'translate3d(' + -this._viewLayout.getScrollLeft() + 'px, ' + viewportData.visibleRangesDeltaTop + 'px, 0px)'; StyleMutator.setTransform(this.domNode.domNode.parentNode, transform); StyleMutator.setTop(this.domNode.domNode.parentNode, 0); // TODO@Alex StyleMutator.setLeft(this.domNode.domNode.parentNode, 0); // TODO@Alex } else { StyleMutator.setTransform(this.domNode.domNode.parentNode, ''); StyleMutator.setTop(this.domNode.domNode.parentNode, viewportData.visibleRangesDeltaTop); // TODO@Alex - StyleMutator.setLeft(this.domNode.domNode.parentNode, -this._layoutProvider.getScrollLeft()); // TODO@Alex + StyleMutator.setLeft(this.domNode.domNode.parentNode, -this._viewLayout.getScrollLeft()); // TODO@Alex } // Update max line width (not so important, it is just so the horizontal scrollbar doesn't get too small) @@ -473,7 +473,7 @@ export class ViewLines extends ViewLayer implements IViewLines { let iLineWidth = Math.ceil(lineWidth); if (this._maxLineWidth < iLineWidth) { this._maxLineWidth = iLineWidth; - this._layoutProvider.onMaxLineWidthChanged(this._maxLineWidth); + this._viewLayout.onMaxLineWidthChanged(this._maxLineWidth); } } @@ -485,8 +485,8 @@ export class ViewLines extends ViewLayer implements IViewLines { let boxEndY: number; // Have a box that includes one extra line height (for the horizontal scrollbar) - boxStartY = this._layoutProvider.getVerticalOffsetForLineNumber(range.startLineNumber); - boxEndY = this._layoutProvider.getVerticalOffsetForLineNumber(range.endLineNumber) + this._lineHeight; + boxStartY = this._viewLayout.getVerticalOffsetForLineNumber(range.startLineNumber); + boxEndY = this._viewLayout.getVerticalOffsetForLineNumber(range.endLineNumber) + this._lineHeight; if (verticalType === editorCommon.VerticalRevealType.Simple || verticalType === editorCommon.VerticalRevealType.Bottom) { // Reveal one line more when the last line would be covered by the scrollbar - arrow down case or revealing a line explicitly at bottom boxEndY += this._lineHeight; @@ -522,7 +522,7 @@ export class ViewLines extends ViewLayer implements IViewLines { }; } - let viewport = this._layoutProvider.getCurrentViewport(); + let viewport = this._viewLayout.getCurrentViewport(); let viewportStartX = viewport.left; let viewportEndX = viewportStartX + viewport.width; diff --git a/src/vs/editor/browser/viewParts/margin/margin.ts b/src/vs/editor/browser/viewParts/margin/margin.ts index e225256b7e3..17996316b0e 100644 --- a/src/vs/editor/browser/viewParts/margin/margin.ts +++ b/src/vs/editor/browser/viewParts/margin/margin.ts @@ -11,20 +11,20 @@ import { ClassNames } from 'vs/editor/browser/editorBrowser'; import { ViewPart } from 'vs/editor/browser/view/viewPart'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; -import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; export class Margin extends ViewPart { public domNode: HTMLElement; - private _layoutProvider: ILayoutProvider; + private _viewLayout: IViewLayout; private _canUseTranslate3d: boolean; private _contentLeft: number; private _glyphMarginLeft: number; private _glyphMarginWidth: number; private _glyphMarginBackgroundDomNode: FastDomNode; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(context); - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; this._canUseTranslate3d = this._context.configuration.editor.viewInfo.canUseTranslate3d; this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; this._glyphMarginLeft = this._context.configuration.editor.layoutInfo.glyphMarginLeft; @@ -89,7 +89,7 @@ export class Margin extends ViewPart { StyleMutator.setTop(this.domNode, ctx.viewportData.visibleRangesDeltaTop); } - let height = Math.min(this._layoutProvider.getTotalHeight(), 1000000); + let height = Math.min(this._viewLayout.getTotalHeight(), 1000000); StyleMutator.setHeight(this.domNode, height); StyleMutator.setWidth(this.domNode, this._contentLeft); diff --git a/src/vs/editor/browser/viewParts/rulers/rulers.ts b/src/vs/editor/browser/viewParts/rulers/rulers.ts index 0aa0befd1f5..ab9f71174bd 100644 --- a/src/vs/editor/browser/viewParts/rulers/rulers.ts +++ b/src/vs/editor/browser/viewParts/rulers/rulers.ts @@ -11,19 +11,19 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { ViewPart } from 'vs/editor/browser/view/viewPart'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; -import { ILayoutProvider } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; export class Rulers extends ViewPart { public domNode: HTMLElement; - private _layoutProvider: ILayoutProvider; + private _viewLayout: IViewLayout; private _rulers: number[]; private _height: number; private _typicalHalfwidthCharacterWidth: number; - constructor(context: ViewContext, layoutProvider: ILayoutProvider) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(context); - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; this.domNode = document.createElement('div'); this.domNode.className = 'view-rulers'; this._rulers = this._context.configuration.editor.viewInfo.rulers; @@ -79,7 +79,7 @@ export class Rulers extends ViewPart { this.domNode.appendChild(node); } - StyleMutator.setHeight(node, Math.min(this._layoutProvider.getTotalHeight(), 1000000)); + StyleMutator.setHeight(node, Math.min(this._viewLayout.getTotalHeight(), 1000000)); StyleMutator.setLeft(node, this._rulers[i] * this._typicalHalfwidthCharacterWidth); } } diff --git a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts index efa387ddf52..1038c2b59fd 100644 --- a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts +++ b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts @@ -12,7 +12,7 @@ import { ViewPart } from 'vs/editor/browser/view/viewPart'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { Position } from 'vs/editor/common/core/position'; import { IRenderingContext, IRestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; -import { IWhitespaceManager } from 'vs/editor/browser/viewLayout/layoutProvider'; +import { IViewLayout } from 'vs/editor/common/viewModel/viewModel'; export interface IMyViewZone { whitespaceId: number; @@ -31,7 +31,7 @@ interface IComputedViewZoneProps { export class ViewZones extends ViewPart { - private _whitespaceManager: IWhitespaceManager; + private _viewLayout: IViewLayout; private _zones: { [id: string]: IMyViewZone; }; private _lineHeight: number; private _contentWidth: number; @@ -41,12 +41,12 @@ export class ViewZones extends ViewPart { public marginDomNode: HTMLElement; - constructor(context: ViewContext, whitespaceManager: IWhitespaceManager) { + constructor(context: ViewContext, viewLayout: IViewLayout) { super(context); this._lineHeight = this._context.configuration.editor.lineHeight; this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; - this._whitespaceManager = whitespaceManager; + this._viewLayout = viewLayout; this.domNode = document.createElement('div'); this.domNode.className = ClassNames.VIEW_ZONES; @@ -65,7 +65,7 @@ export class ViewZones extends ViewPart { public dispose(): void { super.dispose(); - this._whitespaceManager = null; + this._viewLayout = null; this._zones = {}; } @@ -79,7 +79,7 @@ export class ViewZones extends ViewPart { let id = keys[i]; let zone = this._zones[id]; let props = this._computeWhitespaceProps(zone.delegate); - if (this._whitespaceManager.changeWhitespace(parseInt(id, 10), props.afterViewLineNumber, props.heightInPx)) { + if (this._viewLayout.changeWhitespace(parseInt(id, 10), props.afterViewLineNumber, props.heightInPx)) { this._safeCallOnComputedHeight(zone.delegate, props.heightInPx); hadAChange = true; } @@ -188,7 +188,7 @@ export class ViewZones extends ViewPart { public addZone(zone: IViewZone): number { let props = this._computeWhitespaceProps(zone); - let whitespaceId = this._whitespaceManager.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx); + let whitespaceId = this._viewLayout.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx); let myZone: IMyViewZone = { whitespaceId: whitespaceId, @@ -224,7 +224,7 @@ export class ViewZones extends ViewPart { if (this._zones.hasOwnProperty(id.toString())) { let zone = this._zones[id.toString()]; delete this._zones[id.toString()]; - this._whitespaceManager.removeWhitespace(zone.whitespaceId); + this._viewLayout.removeWhitespace(zone.whitespaceId); zone.delegate.domNode.removeAttribute('monaco-visible-view-zone'); zone.delegate.domNode.removeAttribute('monaco-view-zone'); @@ -249,7 +249,7 @@ export class ViewZones extends ViewPart { let zone = this._zones[id.toString()]; let props = this._computeWhitespaceProps(zone.delegate); // let newOrdinal = this._getZoneOrdinal(zone.delegate); - changed = this._whitespaceManager.changeWhitespace(zone.whitespaceId, props.afterViewLineNumber, props.heightInPx) || changed; + changed = this._viewLayout.changeWhitespace(zone.whitespaceId, props.afterViewLineNumber, props.heightInPx) || changed; // TODO@Alex: change `newOrdinal` too if (changed) { @@ -306,7 +306,7 @@ export class ViewZones extends ViewPart { } public render(ctx: IRestrictedRenderingContext): void { - let visibleWhitespaces = this._whitespaceManager.getWhitespaceViewportData(); + let visibleWhitespaces = this._viewLayout.getWhitespaceViewportData(); let visibleZones: { [id: string]: editorCommon.IViewWhitespaceViewportData; } = {}; let hasVisibleZone = false; diff --git a/src/vs/editor/common/view/renderingContext.ts b/src/vs/editor/common/view/renderingContext.ts index 9a16f9a8527..18e48e07744 100644 --- a/src/vs/editor/common/view/renderingContext.ts +++ b/src/vs/editor/common/view/renderingContext.ts @@ -4,20 +4,10 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel'; +import { IViewLayout, ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; -import { Viewport } from 'vs/editor/common/editorCommon'; - -export interface ILayoutProvider { - getScrollWidth(): number; - getScrollHeight(): number; - getCurrentViewport(): Viewport; - - getScrolledTopFromAbsoluteTop(top: number): number; - getVerticalOffsetForLineNumber(lineNumber: number): number; -} export interface IViewLines { linesVisibleRangesForRange(range: Range, includeNewLines: boolean): LineVisibleRanges[]; @@ -41,21 +31,21 @@ export class RenderingContext implements IRenderingContext { public readonly viewportHeight: number; public readonly viewportLeft: number; - private readonly _layoutProvider: ILayoutProvider; + private readonly _viewLayout: IViewLayout; private readonly _viewLines: IViewLines; - constructor(viewLines: IViewLines, layoutProvider: ILayoutProvider, viewportData: ViewportData) { + constructor(viewLines: IViewLines, viewLayout: IViewLayout, viewportData: ViewportData) { this._viewLines = viewLines; - this._layoutProvider = layoutProvider; + this._viewLayout = viewLayout; this.viewportData = viewportData; - this.scrollWidth = this._layoutProvider.getScrollWidth(); - this.scrollHeight = this._layoutProvider.getScrollHeight(); + this.scrollWidth = this._viewLayout.getScrollWidth(); + this.scrollHeight = this._viewLayout.getScrollHeight(); this.visibleRange = this.viewportData.visibleRange; this.bigNumbersDelta = this.viewportData.bigNumbersDelta; - const vInfo = this._layoutProvider.getCurrentViewport(); + const vInfo = this._viewLayout.getCurrentViewport(); this.viewportWidth = vInfo.width; this.viewportHeight = vInfo.height; this.viewportLeft = vInfo.left; @@ -63,12 +53,12 @@ export class RenderingContext implements IRenderingContext { } public getScrolledTopFromAbsoluteTop(absoluteTop: number): number { - return this._layoutProvider.getScrolledTopFromAbsoluteTop(absoluteTop); + return this._viewLayout.getScrolledTopFromAbsoluteTop(absoluteTop); } public getViewportVerticalOffsetForLineNumber(lineNumber: number): number { - const verticalOffset = this._layoutProvider.getVerticalOffsetForLineNumber(lineNumber); - const scrolledTop = this._layoutProvider.getScrolledTopFromAbsoluteTop(verticalOffset); + const verticalOffset = this._viewLayout.getVerticalOffsetForLineNumber(lineNumber); + const scrolledTop = this._viewLayout.getScrolledTopFromAbsoluteTop(verticalOffset); return scrolledTop; } diff --git a/src/vs/editor/common/viewModel/viewModel.ts b/src/vs/editor/common/viewModel/viewModel.ts index a5b3754fbdf..8d90dc5720e 100644 --- a/src/vs/editor/common/viewModel/viewModel.ts +++ b/src/vs/editor/common/viewModel/viewModel.ts @@ -5,11 +5,49 @@ 'use strict'; import { IEventEmitter } from 'vs/base/common/eventEmitter'; -import { IModelDecoration, EndOfLinePreference, IPosition } from 'vs/editor/common/editorCommon'; +import { INewScrollPosition, IViewWhitespaceViewportData, Viewport, IModelDecoration, EndOfLinePreference, IPosition } from 'vs/editor/common/editorCommon'; import { ViewLineToken } from 'vs/editor/common/core/viewLineToken'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; +// import { Viewport } from 'vs/editor/common/editorCommon'; + +export interface IViewLayout { + + onMaxLineWidthChanged(width: number): void; + + getScrollLeft(): number; + getScrollWidth(): number; + getScrollHeight(): number; + getScrollTop(): number; + getCurrentViewport(): Viewport; + getTotalHeight(): number; + getScrolledTopFromAbsoluteTop(top: number): number; + getVerticalOffsetForLineNumber(lineNumber: number): number; + setScrollPosition(position: INewScrollPosition): void; + + // --------------- Begin vertical whitespace management + + /** + * Reserve rendering space. + * @return an identifier that can be later used to remove or change the whitespace. + */ + addWhitespace(afterLineNumber: number, ordinal: number, height: number): number; + /** + * Change the properties of a whitespace. + */ + changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean; + /** + * Remove rendering space + */ + removeWhitespace(id: number): boolean; + /** + * Get the layout information for whitespaces currently in the viewport + */ + getWhitespaceViewportData(): IViewWhitespaceViewportData[]; + + // --------------- End vertical whitespace management +} export interface ICoordinatesConverter { // View -> Model conversion and related methods @@ -17,7 +55,7 @@ export interface ICoordinatesConverter { convertViewRangeToModelRange(viewRange: Range): Range; convertViewSelectionToModelSelection(viewSelection: Selection): Selection; validateViewPosition(viewPosition: Position, expectedModelPosition: Position): Position; - validateViewRange(viewRange: Range, modelRange: Range): Range; + validateViewRange(viewRange: Range, expectedModelRange: Range): Range; // Model -> View conversion and related methods convertModelPositionToViewPosition(modelPosition: Position): Position; @@ -52,9 +90,9 @@ export interface IViewModel extends IEventEmitter { getEOL(): string; getValueInRange(range: Range, eol: EndOfLinePreference): string; - getModelLineContent(lineNumber: number): string; + getModelLineContent(modelLineNumber: number): string; getModelLineMaxColumn(modelLineNumber: number): number; - validateModelPosition(position: IPosition): Position; + validateModelPosition(modelPosition: IPosition): Position; } export class ViewLineRenderingData { diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index a3996ca22e4..66bae78542d 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -46,9 +46,9 @@ export class CoordinatesConverter implements ICoordinatesConverter { return this._lines.validateViewPosition(viewPosition.lineNumber, viewPosition.column, expectedModelPosition); } - public validateViewRange(viewRange: Range, modelRange: Range): Range { - var validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, modelRange.getStartPosition()); - var validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, modelRange.getEndPosition()); + public validateViewRange(viewRange: Range, expectedModelRange: Range): Range { + var validViewStart = this._lines.validateViewPosition(viewRange.startLineNumber, viewRange.startColumn, expectedModelRange.getStartPosition()); + var validViewEnd = this._lines.validateViewPosition(viewRange.endLineNumber, viewRange.endColumn, expectedModelRange.getEndPosition()); return new Range(validViewStart.lineNumber, validViewStart.column, validViewEnd.lineNumber, validViewEnd.column); } -- GitLab