提交 1d6e3119 编写于 作者: A Alex Dima

Move viewLayout management into viewModel

上级 946e7ebb
......@@ -10,7 +10,6 @@ import * as browser from 'vs/base/browser/browser';
import * as dom from 'vs/base/browser/dom';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { MouseTarget, MouseTargetFactory, IViewZoneData } from 'vs/editor/browser/controller/mouseTarget';
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
......@@ -22,7 +21,6 @@ import { StandardMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel';
import { ViewController } from 'vs/editor/browser/view/viewController';
/**
......@@ -47,16 +45,6 @@ export interface IPointerHandlerHelper {
focusTextArea(): void;
getScrollLeft(): number;
getScrollTop(): number;
setScrollPosition(position: editorCommon.INewScrollPosition): void;
isAfterLines(verticalOffset: number): boolean;
getLineNumberAtVerticalOffset(verticalOffset: number): number;
getVerticalOffsetForLineNumber(lineNumber: number): number;
getWhitespaceAtVerticalOffset(verticalOffset: number): IViewWhitespaceViewportData;
/**
* Get the last rendered information of the cursors.
*/
......@@ -433,27 +421,29 @@ class MouseDownOperation extends Disposable {
private _getPositionOutsideEditor(e: EditorMouseEvent): MouseTarget {
const editorContent = e.editorPos;
const model = this._context.model;
const viewLayout = this._context.viewLayout;
let mouseColumn = this._getMouseColumn(e);
const mouseColumn = this._getMouseColumn(e);
if (e.posy < editorContent.y) {
let aboveLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(Math.max(this._viewHelper.getScrollTop() - (editorContent.y - e.posy), 0));
let aboveLineNumber = viewLayout.getLineNumberAtVerticalOffset(Math.max(viewLayout.getScrollTop() - (editorContent.y - e.posy), 0));
return new MouseTarget(null, editorBrowser.MouseTargetType.OUTSIDE_EDITOR, mouseColumn, new Position(aboveLineNumber, 1));
}
if (e.posy > editorContent.y + editorContent.height) {
let belowLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(this._viewHelper.getScrollTop() + (e.posy - editorContent.y));
return new MouseTarget(null, editorBrowser.MouseTargetType.OUTSIDE_EDITOR, mouseColumn, new Position(belowLineNumber, this._context.model.getLineMaxColumn(belowLineNumber)));
let belowLineNumber = viewLayout.getLineNumberAtVerticalOffset(viewLayout.getScrollTop() + (e.posy - editorContent.y));
return new MouseTarget(null, editorBrowser.MouseTargetType.OUTSIDE_EDITOR, mouseColumn, new Position(belowLineNumber, model.getLineMaxColumn(belowLineNumber)));
}
let possibleLineNumber = this._viewHelper.getLineNumberAtVerticalOffset(this._viewHelper.getScrollTop() + (e.posy - editorContent.y));
let possibleLineNumber = viewLayout.getLineNumberAtVerticalOffset(viewLayout.getScrollTop() + (e.posy - editorContent.y));
if (e.posx < editorContent.x) {
return new MouseTarget(null, editorBrowser.MouseTargetType.OUTSIDE_EDITOR, mouseColumn, new Position(possibleLineNumber, 1));
}
if (e.posx > editorContent.x + editorContent.width) {
return new MouseTarget(null, editorBrowser.MouseTargetType.OUTSIDE_EDITOR, mouseColumn, new Position(possibleLineNumber, this._context.model.getLineMaxColumn(possibleLineNumber)));
return new MouseTarget(null, editorBrowser.MouseTargetType.OUTSIDE_EDITOR, mouseColumn, new Position(possibleLineNumber, model.getLineMaxColumn(possibleLineNumber)));
}
return null;
......
......@@ -228,7 +228,7 @@ class HitTestContext {
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData {
// The target is either a view zone or the empty space after the last view-line
let viewZoneWhitespace = this._viewHelper.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
let viewZoneWhitespace = this._context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
if (viewZoneWhitespace) {
let viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
......@@ -268,7 +268,7 @@ class HitTestContext {
}
public getFullLineRangeAtCoord(mouseVerticalOffset: number): { range: EditorRange; isAfterLines: boolean; } {
if (this._viewHelper.isAfterLines(mouseVerticalOffset)) {
if (this._context.viewLayout.isAfterLines(mouseVerticalOffset)) {
// Below the last line
let lineNumber = this._context.model.getLineCount();
let maxLineColumn = this._context.model.getLineMaxColumn(lineNumber);
......@@ -278,7 +278,7 @@ class HitTestContext {
};
}
let lineNumber = this._viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
let lineNumber = this._context.viewLayout.getLineNumberAtVerticalOffset(mouseVerticalOffset);
let maxLineColumn = this._context.model.getLineMaxColumn(lineNumber);
return {
range: new EditorRange(lineNumber, 1, lineNumber, maxLineColumn),
......@@ -287,15 +287,15 @@ class HitTestContext {
}
public getLineNumberAtVerticalOffset(mouseVerticalOffset: number): number {
return this._viewHelper.getLineNumberAtVerticalOffset(mouseVerticalOffset);
return this._context.viewLayout.getLineNumberAtVerticalOffset(mouseVerticalOffset);
}
public isAfterLines(mouseVerticalOffset: number): boolean {
return this._viewHelper.isAfterLines(mouseVerticalOffset);
return this._context.viewLayout.isAfterLines(mouseVerticalOffset);
}
public getVerticalOffsetForLineNumber(lineNumber: number): number {
return this._viewHelper.getVerticalOffsetForLineNumber(lineNumber);
return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber);
}
public findAttribute(element: Element, attr: string): string {
......@@ -328,11 +328,11 @@ class HitTestContext {
}
public getScrollTop(): number {
return this._viewHelper.getScrollTop();
return this._context.viewLayout.getScrollTop();
}
public getScrollLeft(): number {
return this._viewHelper.getScrollLeft();
return this._context.viewLayout.getScrollLeft();
}
}
......@@ -649,7 +649,7 @@ export class MouseTargetFactory {
public getMouseColumn(editorPos: EditorPagePosition, pos: PageCoordinates): number {
let layoutInfo = this._context.configuration.editor.layoutInfo;
let mouseContentHorizontalOffset = this._viewHelper.getScrollLeft() + pos.x - editorPos.x - layoutInfo.contentLeft;
let mouseContentHorizontalOffset = this._context.viewLayout.getScrollLeft() + pos.x - editorPos.x - layoutInfo.contentLeft;
return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth);
}
......
......@@ -99,9 +99,10 @@ class MsPointerHandler extends MouseHandler implements IDisposable {
}
private _onGestureChange(e: IThrottledGestureEvent): void {
this.viewHelper.setScrollPosition({
scrollLeft: this.viewHelper.getScrollLeft() - e.translationX,
scrollTop: this.viewHelper.getScrollTop() - e.translationY,
const viewLayout = this._context.viewLayout;
viewLayout.setScrollPosition({
scrollLeft: viewLayout.getScrollLeft() - e.translationX,
scrollTop: viewLayout.getScrollTop() - e.translationY,
});
}
......@@ -180,9 +181,10 @@ class StandardPointerHandler extends MouseHandler implements IDisposable {
}
private _onGestureChange(e: IThrottledGestureEvent): void {
this.viewHelper.setScrollPosition({
scrollLeft: this.viewHelper.getScrollLeft() - e.translationX,
scrollTop: this.viewHelper.getScrollTop() - e.translationY,
const viewLayout = this._context.viewLayout;
viewLayout.setScrollPosition({
scrollLeft: viewLayout.getScrollLeft() - e.translationX,
scrollTop: viewLayout.getScrollTop() - e.translationY,
});
}
......@@ -225,9 +227,10 @@ class TouchHandler extends MouseHandler {
}
private onChange(e: GestureEvent): void {
this.viewHelper.setScrollPosition({
scrollLeft: this.viewHelper.getScrollLeft() - e.translationX,
scrollTop: this.viewHelper.getScrollTop() - e.translationY,
const viewLayout = this._context.viewLayout;
viewLayout.setScrollPosition({
scrollLeft: viewLayout.getScrollLeft() - e.translationX,
scrollTop: viewLayout.getScrollTop() - e.translationY,
});
}
}
......
......@@ -27,10 +27,9 @@ import { BareFontInfo } from "vs/editor/common/config/fontInfo";
export interface ITextAreaHandlerHelper {
visibleRangeForPositionRelativeToEditor(lineNumber: number, column: number): HorizontalRange;
getVerticalOffsetForLineNumber(lineNumber: number): number;
}
class VisibleTextArea {
class VisibleTextAreaData {
_visibleTextAreaBrand: void;
public readonly top: number;
......@@ -43,8 +42,8 @@ class VisibleTextArea {
this.width = width;
}
public setWidth(width: number): VisibleTextArea {
return new VisibleTextArea(this.top, this.left, width);
public setWidth(width: number): VisibleTextAreaData {
return new VisibleTextAreaData(this.top, this.left, width);
}
}
......@@ -67,7 +66,7 @@ export class TextAreaHandler extends ViewPart {
/**
* Defined only when the text area is visible (composition case).
*/
private _visibleTextArea: VisibleTextArea;
private _visibleTextArea: VisibleTextAreaData;
private _selections: Selection[];
private _lastCopiedValue: string;
private _lastCopiedValueIsFromEmptySelection: boolean;
......@@ -79,7 +78,6 @@ export class TextAreaHandler extends ViewPart {
constructor(context: ViewContext, viewController: ViewController, viewHelper: ITextAreaHandlerHelper) {
super(context);
this._context = context;
this._viewController = viewController;
this._viewHelper = viewHelper;
......@@ -211,8 +209,8 @@ export class TextAreaHandler extends ViewPart {
const visibleRange = this._viewHelper.visibleRangeForPositionRelativeToEditor(lineNumber, column);
if (visibleRange) {
this._visibleTextArea = new VisibleTextArea(
this._viewHelper.getVerticalOffsetForLineNumber(lineNumber),
this._visibleTextArea = new VisibleTextAreaData(
this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber),
visibleRange.left,
canUseZeroSizeTextarea ? 0 : 1
);
......@@ -379,7 +377,7 @@ export class TextAreaHandler extends ViewPart {
return;
}
const top = this._viewHelper.getVerticalOffsetForLineNumber(this._selections[0].positionLineNumber) - this._scrollTop;
const top = this._context.viewLayout.getVerticalOffsetForLineNumber(this._selections[0].positionLineNumber) - this._scrollTop;
if (top < 0 || top > this._contentHeight) {
// cursor is outside the viewport
this._renderAtTopLeft();
......
......@@ -20,7 +20,6 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser';
import { ViewController, ExecCoreEditorCommandFunc } from 'vs/editor/browser/view/viewController';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
import { ContentViewOverlays, MarginViewOverlays } from 'vs/editor/browser/view/viewOverlays';
import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout';
import { ViewContentWidgets } from 'vs/editor/browser/viewParts/contentWidgets/contentWidgets';
import { CurrentLineHighlightOverlay } from 'vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight';
import { CurrentLineMarginHighlightOverlay } from 'vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight';
......@@ -66,7 +65,6 @@ export class View extends ViewEventHandler {
private eventDispatcher: ViewEventDispatcher;
private layoutProvider: ViewLayout;
private _scrollbar: EditorScrollbar;
private _context: ViewContext;
......@@ -114,12 +112,6 @@ export class View extends ViewEventHandler {
// Ensure the view is the first event handler in order to update the layout
this.eventDispatcher.addEventHandler(this);
// The layout provider has such responsibilities as:
// - scrolling (i.e. viewport / full size) & co.
// - whitespaces (a.k.a. view zones) management & co.
// - line heights updating & co.
this.layoutProvider = new ViewLayout(configuration, model.getLineCount(), this.eventDispatcher);
// The view context is passed on to most classes (basically to reduce param. counts in ctors)
this._context = new ViewContext(configuration, model, this.eventDispatcher);
......@@ -153,20 +145,20 @@ export class View extends ViewEventHandler {
PartFingerprints.write(this.overflowGuardContainer, PartFingerprint.OverflowGuard);
this.overflowGuardContainer.setClassName('overflow-guard');
this._scrollbar = new EditorScrollbar(this._context, this.layoutProvider.getScrollable(), this.linesContent, this.domNode, this.overflowGuardContainer);
this._scrollbar = new EditorScrollbar(this._context, this.linesContent, this.domNode, this.overflowGuardContainer);
this.viewParts.push(this._scrollbar);
// View Lines
this.viewLines = new ViewLines(this._context, this.linesContent, this.layoutProvider);
this.viewLines = new ViewLines(this._context, this.linesContent);
// View Zones
this.viewZones = new ViewZones(this._context, this.layoutProvider);
this.viewZones = new ViewZones(this._context);
this.viewParts.push(this.viewZones);
// Decorations overview ruler
let decorationsOverviewRuler = new DecorationsOverviewRuler(
this._context, this.layoutProvider.getScrollHeight(),
(lineNumber: number) => this.layoutProvider.getVerticalOffsetForLineNumber(lineNumber)
this._context, this._context.viewLayout.getScrollHeight(),
(lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber)
);
this.viewParts.push(decorationsOverviewRuler);
......@@ -208,7 +200,7 @@ export class View extends ViewEventHandler {
let rulers = new Rulers(this._context);
this.viewParts.push(rulers);
let minimap = new Minimap(this._context, this.layoutProvider, this._scrollbar);
let minimap = new Minimap(this._context, this._scrollbar);
this.viewParts.push(minimap);
// -------------- Wire dom nodes up
......@@ -248,29 +240,6 @@ export class View extends ViewEventHandler {
this.focus();
},
getScrollLeft: () => {
return this.layoutProvider.getScrollLeft();
},
getScrollTop: () => {
return this.layoutProvider.getScrollTop();
},
setScrollPosition: (position: editorCommon.INewScrollPosition) => {
this.layoutProvider.setScrollPosition(position);
},
isAfterLines: (verticalOffset: number) => {
return this.layoutProvider.isAfterLines(verticalOffset);
},
getLineNumberAtVerticalOffset: (verticalOffset: number) => {
return this.layoutProvider.getLineNumberAtVerticalOffset(verticalOffset);
},
getVerticalOffsetForLineNumber: (lineNumber: number) => {
return this.layoutProvider.getVerticalOffsetForLineNumber(lineNumber);
},
getWhitespaceAtVerticalOffset: (verticalOffset: number) => {
return this.layoutProvider.getWhitespaceAtVerticalOffset(verticalOffset);
},
getLastViewCursorsRenderData: () => {
return this.viewCursors.getLastRenderData() || [];
},
......@@ -310,9 +279,6 @@ export class View extends ViewEventHandler {
return null;
}
return visibleRanges[0];
},
getVerticalOffsetForLineNumber: (lineNumber: number) => {
return this.layoutProvider.getVerticalOffsetForLineNumber(lineNumber);
}
};
}
......@@ -346,11 +312,6 @@ export class View extends ViewEventHandler {
if (e.layoutInfo) {
this._setLayout();
}
this.layoutProvider.onConfigurationChanged(e);
return false;
}
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
this.layoutProvider.onFlushed(this._context.model.getLineCount());
return false;
}
public onFocusChanged(e: viewEvents.ViewFocusChangedEvent): boolean {
......@@ -362,24 +323,10 @@ export class View extends ViewEventHandler {
}
return false;
}
public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {
this.layoutProvider.onLinesDeleted(e);
return false;
}
public onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): boolean {
this.layoutProvider.onLinesInserted(e);
return false;
}
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
this.outgoingEvents.emitScrollChanged(e);
return false;
}
public onScrollRequest(e: viewEvents.ViewScrollRequestEvent): boolean {
this.layoutProvider.setScrollPosition({
scrollTop: e.desiredScrollTop
});
return false;
}
// --- end event handlers
......@@ -403,8 +350,6 @@ export class View extends ViewEventHandler {
}
this.viewParts = [];
this.layoutProvider.dispose();
super.dispose();
}
......@@ -453,7 +398,7 @@ export class View extends ViewEventHandler {
return;
}
let partialViewportData = this.layoutProvider.getLinesViewportData();
const partialViewportData = this._context.viewLayout.getLinesViewportData();
this._context.model.setViewport(partialViewportData.startLineNumber, partialViewportData.endLineNumber, partialViewportData.centeredLineNumber);
let viewportData = new ViewportData(partialViewportData, this._context.model);
......@@ -470,7 +415,7 @@ export class View extends ViewEventHandler {
this._textAreaHandler.writeToTextArea();
}
let renderingContext = new RenderingContext(this.layoutProvider, viewportData, this.viewLines);
let renderingContext = new RenderingContext(this._context.viewLayout, viewportData, this.viewLines);
// Render the rest of the parts
for (let i = 0, len = viewPartsToRender.length; i < len; i++) {
......@@ -488,27 +433,27 @@ export class View extends ViewEventHandler {
// --- BEGIN CodeEditor helpers
public getScrollWidth(): number {
return this.layoutProvider.getScrollWidth();
return this._context.viewLayout.getScrollWidth();
}
public getScrollLeft(): number {
return this.layoutProvider.getScrollLeft();
return this._context.viewLayout.getScrollLeft();
}
public getScrollHeight(): number {
return this.layoutProvider.getScrollHeight();
return this._context.viewLayout.getScrollHeight();
}
public getScrollTop(): number {
return this.layoutProvider.getScrollTop();
return this._context.viewLayout.getScrollTop();
}
public setScrollPosition(scrollPosition: editorCommon.INewScrollPosition): void {
this.layoutProvider.setScrollPosition(scrollPosition);
this._context.viewLayout.setScrollPosition(scrollPosition);
}
public getVerticalOffsetForViewLineNumber(viewLineNumber: number): number {
return this.layoutProvider.getVerticalOffsetForLineNumber(viewLineNumber);
return this._context.viewLayout.getVerticalOffsetForLineNumber(viewLineNumber);
}
public delegateVerticalScrollbarMouseDown(browserEvent: MouseEvent): void {
......@@ -534,7 +479,7 @@ export class View extends ViewEventHandler {
}
public getCompletelyVisibleViewRange(): Range {
const partialData = this.layoutProvider.getLinesViewportData();
const partialData = this._context.viewLayout.getLinesViewportData();
const startViewLineNumber = partialData.completelyVisibleStartLineNumber;
const endViewLineNumber = partialData.completelyVisibleEndLineNumber;
......@@ -545,7 +490,7 @@ export class View extends ViewEventHandler {
}
public getCompletelyVisibleViewRangeAtScrollTop(scrollTop: number): Range {
const partialData = this.layoutProvider.getLinesViewportDataAtScrollTop(scrollTop);
const partialData = this._context.viewLayout.getLinesViewportDataAtScrollTop(scrollTop);
const startViewLineNumber = partialData.completelyVisibleStartLineNumber;
const endViewLineNumber = partialData.completelyVisibleEndLineNumber;
......@@ -561,8 +506,8 @@ export class View extends ViewEventHandler {
public createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): OverviewRuler {
return new OverviewRuler(
this._context, cssClassName, this.layoutProvider.getScrollHeight(), minimumHeight, maximumHeight,
(lineNumber: number) => this.layoutProvider.getVerticalOffsetForLineNumber(lineNumber)
this._context, cssClassName, this._context.viewLayout.getScrollHeight(), minimumHeight, maximumHeight,
(lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber)
);
}
......@@ -596,7 +541,7 @@ export class View extends ViewEventHandler {
changeAccessor.removeZone = null;
if (zonesHaveChanged) {
this.layoutProvider.onHeightMaybeChanged();
this._context.viewLayout.onHeightMaybeChanged();
this._context.privateViewEventBus.emit(new viewEvents.ViewZonesChangedEvent());
}
});
......@@ -604,7 +549,7 @@ export class View extends ViewEventHandler {
}
public getWhitespaces(): IEditorWhitespace[] {
return this.layoutProvider.getWhitespaces();
return this._context.viewLayout.getWhitespaces();
}
public render(now: boolean, everything: boolean): void {
......@@ -628,11 +573,11 @@ export class View extends ViewEventHandler {
}
public saveState(): editorCommon.IViewState {
return this.layoutProvider.saveState();
return this._context.viewLayout.saveState();
}
public restoreState(state: editorCommon.IViewState): void {
return this.layoutProvider.restoreState(state);
return this._context.viewLayout.restoreState(state);
}
public focus(): void {
......
......@@ -23,14 +23,13 @@ export class EditorScrollbar extends ViewPart {
constructor(
context: ViewContext,
scrollable: Scrollable,
linesContent: FastDomNode<HTMLElement>,
viewDomNode: FastDomNode<HTMLElement>,
overflowGuardDomNode: FastDomNode<HTMLElement>
) {
super(context);
this.scrollable = scrollable;
this.scrollable = this._context.viewLayout.scrollable;
const editor = this._context.configuration.editor;
const configScrollbarOpts = editor.viewInfo.scrollbar;
......
......@@ -15,7 +15,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, HorizontalRange, LineVisibleRanges } from 'vs/editor/common/view/renderingContext';
import { IViewLayout, Viewport } from 'vs/editor/common/viewModel/viewModel';
import { Viewport } from 'vs/editor/common/viewModel/viewModel';
import { ViewPart, PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { VerticalRevealType } from 'vs/editor/common/controller/cursorEvents';
......@@ -48,7 +48,6 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
private static HORIZONTAL_EXTRA_PX = 30;
private readonly _linesContent: FastDomNode<HTMLElement>;
private readonly _viewLayout: IViewLayout;
private readonly _textRangeRestingSpot: HTMLElement;
private readonly _visibleLines: VisibleLinesCollection<ViewLine>;
private readonly domNode: FastDomNode<HTMLElement>;
......@@ -67,10 +66,9 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
private _lastCursorRevealRangeHorizontallyEvent: viewEvents.ViewRevealRangeRequestEvent;
private _lastRenderedData: LastRenderedData;
constructor(context: ViewContext, linesContent: FastDomNode<HTMLElement>, viewLayout: IViewLayout) {
constructor(context: ViewContext, linesContent: FastDomNode<HTMLElement>) {
super(context);
this._linesContent = linesContent;
this._viewLayout = viewLayout;
this._textRangeRestingSpot = document.createElement('div');
this._visibleLines = new VisibleLinesCollection(this);
this.domNode = this._visibleLines.domNode;
......@@ -180,13 +178,13 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
return this._visibleLines.onLinesInserted(e);
}
public onRevealRangeRequest(e: viewEvents.ViewRevealRangeRequestEvent): boolean {
let newScrollTop = this._computeScrollTopToRevealRange(this._viewLayout.getCurrentViewport(), e.range, e.verticalType);
let newScrollTop = this._computeScrollTopToRevealRange(this._context.viewLayout.getCurrentViewport(), e.range, e.verticalType);
if (e.revealHorizontal) {
this._lastCursorRevealRangeHorizontallyEvent = e;
}
this._viewLayout.setScrollPosition({
this._context.viewLayout.setScrollPosition({
scrollTop: newScrollTop
});
......@@ -412,8 +410,8 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
// (1) render lines - ensures lines are in the DOM
this._visibleLines.renderLines(viewportData);
this._lastRenderedData.setCurrentVisibleRange(viewportData.visibleRange);
this.domNode.setWidth(this._viewLayout.getScrollWidth());
this.domNode.setHeight(Math.min(this._viewLayout.getScrollHeight(), 1000000));
this.domNode.setWidth(this._context.viewLayout.getScrollWidth());
this.domNode.setHeight(Math.min(this._context.viewLayout.getScrollHeight(), 1000000));
// (2) execute DOM writing that forces sync layout (e.g. textArea manipulation)
onAfterLinesRendered();
......@@ -438,22 +436,22 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
}
// set `scrollLeft`
this._viewLayout.setScrollPosition({
this._context.viewLayout.setScrollPosition({
scrollLeft: newScrollLeft.scrollLeft
});
}
// (4) handle scrolling
const adjustedScrollTop = this._viewLayout.getScrollTop() - viewportData.bigNumbersDelta;
const adjustedScrollTop = this._context.viewLayout.getScrollTop() - viewportData.bigNumbersDelta;
if (this._canUseTranslate3d) {
let transform = 'translate3d(' + -this._viewLayout.getScrollLeft() + 'px, ' + -adjustedScrollTop + 'px, 0px)';
let transform = 'translate3d(' + -this._context.viewLayout.getScrollLeft() + 'px, ' + -adjustedScrollTop + 'px, 0px)';
this._linesContent.setTransform(transform);
this._linesContent.setTop(0);
this._linesContent.setLeft(0);
} else {
this._linesContent.setTransform('');
this._linesContent.setTop(-adjustedScrollTop);
this._linesContent.setLeft(-this._viewLayout.getScrollLeft());
this._linesContent.setLeft(-this._context.viewLayout.getScrollLeft());
}
// Update max line width (not so important, it is just so the horizontal scrollbar doesn't get too small)
......@@ -466,7 +464,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
let iLineWidth = Math.ceil(lineWidth);
if (this._maxLineWidth < iLineWidth) {
this._maxLineWidth = iLineWidth;
this._viewLayout.onMaxLineWidthChanged(this._maxLineWidth);
this._context.viewLayout.onMaxLineWidthChanged(this._maxLineWidth);
}
}
......@@ -478,8 +476,8 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
let boxEndY: number;
// Have a box that includes one extra line height (for the horizontal scrollbar)
boxStartY = this._viewLayout.getVerticalOffsetForLineNumber(range.startLineNumber);
boxEndY = this._viewLayout.getVerticalOffsetForLineNumber(range.endLineNumber) + this._lineHeight;
boxStartY = this._context.viewLayout.getVerticalOffsetForLineNumber(range.startLineNumber);
boxEndY = this._context.viewLayout.getVerticalOffsetForLineNumber(range.endLineNumber) + this._lineHeight;
if (verticalType === VerticalRevealType.Simple || verticalType === 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;
......@@ -515,7 +513,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
};
}
let viewport = this._viewLayout.getCurrentViewport();
let viewport = this._context.viewLayout.getCurrentViewport();
let viewportStartX = viewport.left;
let viewportEndX = viewportStartX + viewport.width;
......
......@@ -15,7 +15,7 @@ import * as dom from 'vs/base/browser/dom';
import { MinimapCharRenderer, MinimapTokensColorTracker, Constants } from 'vs/editor/common/view/minimapCharRenderer';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { CharCode } from 'vs/base/common/charCode';
import { IViewLayout, ViewLineData } from 'vs/editor/common/viewModel/viewModel';
import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
import { ColorId } from 'vs/editor/common/modes';
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
import { IDisposable } from 'vs/base/common/lifecycle';
......@@ -415,7 +415,6 @@ class MinimapBuffers {
export class Minimap extends ViewPart {
private readonly _viewLayout: IViewLayout;
private readonly _editorScrollbar: EditorScrollbar;
private readonly _domNode: FastDomNode<HTMLElement>;
......@@ -433,9 +432,8 @@ export class Minimap extends ViewPart {
private _lastRenderData: RenderData;
private _buffers: MinimapBuffers;
constructor(context: ViewContext, viewLayout: IViewLayout, editorScrollbar: EditorScrollbar) {
constructor(context: ViewContext, editorScrollbar: EditorScrollbar) {
super(context);
this._viewLayout = viewLayout;
this._editorScrollbar = editorScrollbar;
this._options = new MinimapOptions(this._context.configuration);
......@@ -499,7 +497,7 @@ export class Minimap extends ViewPart {
if (e.leftButton) {
const initialMouseOrthogonalPosition = e.posx;
const initialScrollTop = this._viewLayout.getScrollTop();
const initialScrollTop = this._context.viewLayout.getScrollTop();
const initialSliderCenter = (this._slider.getTop() + this._slider.getHeight() / 2);
const draggingDeltaCenter = e.posy - initialSliderCenter;
this._slider.toggleClassName('active', true);
......@@ -511,7 +509,7 @@ export class Minimap extends ViewPart {
const mouseOrthogonalDelta = Math.abs(mouseOrthogonalPosition - initialMouseOrthogonalPosition);
if (platform.isWindows && mouseOrthogonalDelta > MOUSE_DRAG_RESET_DISTANCE) {
// The mouse has wondered away from the slider => reset dragging
this._viewLayout.setScrollPosition({
this._context.viewLayout.setScrollPosition({
scrollTop: initialScrollTop
});
} else {
......@@ -525,13 +523,13 @@ export class Minimap extends ViewPart {
if (this._context.configuration.editor.viewInfo.scrollBeyondLastLine) {
discountScrollHeight = this._canvas.getHeight() - this._context.configuration.editor.lineHeight;
}
const scrollHeight = this._viewLayout.getScrollHeight() - discountScrollHeight;
const scrollHeight = this._context.viewLayout.getScrollHeight() - discountScrollHeight;
const desiredSliderCenter = mouseMoveData.posy - draggingDeltaCenter;
const desiredScrollCenter = desiredSliderCenter * (scrollHeight / representableHeight);
const desiredScrollTop = desiredScrollCenter - this._canvas.getHeight() / 2;
this._viewLayout.setScrollPosition({
this._context.viewLayout.setScrollPosition({
scrollTop: desiredScrollTop
});
}
......
......@@ -11,7 +11,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 { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext';
import { IViewLayout, IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel';
import { IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
export interface IMyViewZone {
......@@ -33,7 +33,6 @@ interface IComputedViewZoneProps {
export class ViewZones extends ViewPart {
private _viewLayout: IViewLayout;
private _zones: { [id: string]: IMyViewZone; };
private _lineHeight: number;
private _contentWidth: number;
......@@ -43,12 +42,11 @@ export class ViewZones extends ViewPart {
public marginDomNode: FastDomNode<HTMLElement>;
constructor(context: ViewContext, viewLayout: IViewLayout) {
constructor(context: ViewContext) {
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._viewLayout = viewLayout;
this.domNode = createFastDomNode(document.createElement('div'));
this.domNode.setClassName('view-zones');
......@@ -67,7 +65,6 @@ export class ViewZones extends ViewPart {
public dispose(): void {
super.dispose();
this._viewLayout = null;
this._zones = {};
}
......@@ -81,7 +78,7 @@ export class ViewZones extends ViewPart {
let id = keys[i];
let zone = this._zones[id];
let props = this._computeWhitespaceProps(zone.delegate);
if (this._viewLayout.changeWhitespace(parseInt(id, 10), props.afterViewLineNumber, props.heightInPx)) {
if (this._context.viewLayout.changeWhitespace(parseInt(id, 10), props.afterViewLineNumber, props.heightInPx)) {
this._safeCallOnComputedHeight(zone.delegate, props.heightInPx);
hadAChange = true;
}
......@@ -186,7 +183,7 @@ export class ViewZones extends ViewPart {
public addZone(zone: IViewZone): number {
let props = this._computeWhitespaceProps(zone);
let whitespaceId = this._viewLayout.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx);
let whitespaceId = this._context.viewLayout.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx);
let myZone: IMyViewZone = {
whitespaceId: whitespaceId,
......@@ -224,7 +221,7 @@ export class ViewZones extends ViewPart {
if (this._zones.hasOwnProperty(id.toString())) {
let zone = this._zones[id.toString()];
delete this._zones[id.toString()];
this._viewLayout.removeWhitespace(zone.whitespaceId);
this._context.viewLayout.removeWhitespace(zone.whitespaceId);
zone.domNode.removeAttribute('monaco-visible-view-zone');
zone.domNode.removeAttribute('monaco-view-zone');
......@@ -249,7 +246,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._viewLayout.changeWhitespace(zone.whitespaceId, props.afterViewLineNumber, props.heightInPx) || changed;
changed = this._context.viewLayout.changeWhitespace(zone.whitespaceId, props.afterViewLineNumber, props.heightInPx) || changed;
// TODO@Alex: change `newOrdinal` too
if (changed) {
......@@ -303,7 +300,7 @@ export class ViewZones extends ViewPart {
}
public render(ctx: RestrictedRenderingContext): void {
let visibleWhitespaces = this._viewLayout.getWhitespaceViewportData();
let visibleWhitespaces = this._context.viewLayout.getWhitespaceViewportData();
let visibleZones: { [id: string]: IViewWhitespaceViewportData; } = {};
let hasVisibleZone = false;
......
......@@ -5,7 +5,7 @@
'use strict';
import { IConfiguration } from 'vs/editor/common/editorCommon';
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
import { IViewModel, IViewLayout } from 'vs/editor/common/viewModel/viewModel';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
......@@ -13,6 +13,7 @@ export class ViewContext {
public readonly configuration: IConfiguration;
public readonly model: IViewModel;
public readonly viewLayout: IViewLayout;
public readonly privateViewEventBus: ViewEventDispatcher;
constructor(
......@@ -22,6 +23,7 @@ export class ViewContext {
) {
this.configuration = configuration;
this.model = model;
this.viewLayout = model.viewLayout;
this.privateViewEventBus = privateViewEventBus;
}
......
......@@ -10,34 +10,33 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import { LinesLayout } from 'vs/editor/common/viewLayout/linesLayout';
import { IViewLayout, IViewWhitespaceViewportData, Viewport } from 'vs/editor/common/viewModel/viewModel';
import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
import Event from 'vs/base/common/event';
import { IConfigurationChangedEvent } from "vs/editor/common/config/editorOptions";
export class ViewLayout extends Disposable implements IViewLayout {
static LINES_HORIZONTAL_EXTRA_PX = 30;
private _configuration: editorCommon.IConfiguration;
private _privateViewEventBus: ViewEventDispatcher;
private _linesLayout: LinesLayout;
private _scrollable: Scrollable;
private readonly _configuration: editorCommon.IConfiguration;
private readonly _linesLayout: LinesLayout;
constructor(configuration: editorCommon.IConfiguration, lineCount: number, privateViewEventBus: ViewEventDispatcher) {
public readonly scrollable: Scrollable;
public readonly onDidScroll: Event<ScrollEvent>;
constructor(configuration: editorCommon.IConfiguration, lineCount: number) {
super();
this._configuration = configuration;
this._privateViewEventBus = privateViewEventBus;
this._linesLayout = new LinesLayout(lineCount, this._configuration.editor.lineHeight);
this._scrollable = this._register(new Scrollable());
this._scrollable.updateState({
this.scrollable = this._register(new Scrollable());
this.scrollable.updateState({
width: configuration.editor.layoutInfo.contentWidth,
height: configuration.editor.layoutInfo.contentHeight
});
this._register(this._scrollable.onScroll((e: ScrollEvent) => {
this._privateViewEventBus.emit(new viewEvents.ViewScrollChangedEvent(e));
}));
this.onDidScroll = this.scrollable.onScroll;
this._updateHeight();
}
......@@ -47,7 +46,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
}
public getScrollable(): Scrollable {
return this._scrollable;
return this.scrollable;
}
public onHeightMaybeChanged(): void {
......@@ -56,12 +55,12 @@ export class ViewLayout extends Disposable implements IViewLayout {
// ---- begin view event handlers
public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): void {
public onConfigurationChanged(e: IConfigurationChangedEvent): void {
if (e.lineHeight) {
this._linesLayout.setLineHeight(this._configuration.editor.lineHeight);
}
if (e.layoutInfo) {
this._scrollable.updateState({
this.scrollable.updateState({
width: this._configuration.editor.layoutInfo.contentWidth,
height: this._configuration.editor.layoutInfo.contentHeight
});
......@@ -96,7 +95,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
}
private _getTotalHeight(): number {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
let result = this._linesLayout.getLinesTotalHeight();
if (this._configuration.editor.viewInfo.scrollBeyondLastLine) {
......@@ -109,7 +108,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
}
private _updateHeight(): void {
this._scrollable.updateState({
this.scrollable.updateState({
scrollHeight: this._getTotalHeight()
});
}
......@@ -117,7 +116,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
// ---- Layouting logic
public getCurrentViewport(): Viewport {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
return new Viewport(
scrollState.scrollTop,
scrollState.scrollLeft,
......@@ -136,7 +135,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
public onMaxLineWidthChanged(maxLineWidth: number): void {
let newScrollWidth = this._computeScrollWidth(maxLineWidth, this.getCurrentViewport().width);
this._scrollable.updateState({
this.scrollable.updateState({
scrollWidth: newScrollWidth
});
......@@ -147,7 +146,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
// ---- view state
public saveState(): editorCommon.IViewState {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
let scrollTop = scrollState.scrollTop;
let firstLineNumberInViewport = this._linesLayout.getLineNumberAtOrAfterVerticalOffset(scrollTop);
let whitespaceAboveFirstLine = this._linesLayout.getWhitespaceAccumulatedHeightBeforeLineNumber(firstLineNumberInViewport);
......@@ -163,7 +162,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
if (typeof state.scrollTopWithoutViewZones === 'number' && !this._linesLayout.hasWhitespace()) {
restoreScrollTop = state.scrollTopWithoutViewZones;
}
this._scrollable.updateState({
this.scrollable.updateState({
scrollLeft: state.scrollLeft,
scrollTop: restoreScrollTop
});
......@@ -199,7 +198,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
}
public getLinesViewportDataAtScrollTop(scrollTop: number): IPartialViewLinesViewportData {
// do some minimal validations on scrollTop
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
if (scrollTop + scrollState.height > scrollState.scrollHeight) {
scrollTop = scrollState.scrollHeight - scrollState.height;
}
......@@ -220,23 +219,23 @@ export class ViewLayout extends Disposable implements IViewLayout {
public getScrollWidth(): number {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
return scrollState.scrollWidth;
}
public getScrollLeft(): number {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
return scrollState.scrollLeft;
}
public getScrollHeight(): number {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
return scrollState.scrollHeight;
}
public getScrollTop(): number {
const scrollState = this._scrollable.getState();
const scrollState = this.scrollable.getState();
return scrollState.scrollTop;
}
public setScrollPosition(position: editorCommon.INewScrollPosition): void {
this._scrollable.updateState(position);
this.scrollable.updateState(position);
}
}
......@@ -9,7 +9,7 @@ import { Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { LineTokens } from 'vs/editor/common/core/lineTokens';
import { PrefixSumComputerWithCache } from 'vs/editor/common/viewModel/prefixSumComputer';
import { ViewLineData, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel';
import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { WrappingIndent } from 'vs/editor/common/config/editorOptions';
......@@ -165,7 +165,7 @@ export class SplitLinesCollection {
return result;
}
public setHiddenAreas(eventsCollector: ViewEventsCollector, _ranges: Range[]): boolean {
public setHiddenAreas(_ranges: Range[]): boolean {
let newRanges = this._reduceRanges(_ranges);
......@@ -232,7 +232,6 @@ export class SplitLinesCollection {
}
}
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
return true;
}
......@@ -244,19 +243,18 @@ export class SplitLinesCollection {
return this.lines[modelLineNumber - 1].isVisible();
}
public setTabSize(eventsCollector: ViewEventsCollector, newTabSize: number): boolean {
public setTabSize(newTabSize: number): boolean {
if (this.tabSize === newTabSize) {
return false;
}
this.tabSize = newTabSize;
this._constructLines(false);
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
return true;
}
public setWrappingSettings(eventsCollector: ViewEventsCollector, wrappingIndent: WrappingIndent, wrappingColumn: number, columnsForFullWidthChar: number): boolean {
public setWrappingSettings(wrappingIndent: WrappingIndent, wrappingColumn: number, columnsForFullWidthChar: number): boolean {
if (this.wrappingIndent === wrappingIndent && this.wrappingColumn === wrappingColumn && this.columnsForFullWidthChar === columnsForFullWidthChar) {
return false;
}
......@@ -266,21 +264,19 @@ export class SplitLinesCollection {
this.columnsForFullWidthChar = columnsForFullWidthChar;
this._constructLines(false);
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
return true;
}
public onModelFlushed(eventsCollector: ViewEventsCollector): void {
public onModelFlushed(): void {
this._constructLines(true);
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
}
public onModelLinesDeleted(eventsCollector: ViewEventsCollector, versionId: number, fromLineNumber: number, toLineNumber: number): void {
public onModelLinesDeleted(versionId: number, fromLineNumber: number, toLineNumber: number): viewEvents.ViewLinesDeletedEvent {
if (versionId <= this._validModelVersionId) {
// Here we check for versionId in case the lines were reconstructed in the meantime.
// We don't want to apply stale change events on top of a newer read model state.
return;
return null;
}
let outputFromLineNumber = (fromLineNumber === 1 ? 1 : this.prefixSumComputer.getAccumulatedValue(fromLineNumber - 2) + 1);
......@@ -289,14 +285,14 @@ export class SplitLinesCollection {
this.lines.splice(fromLineNumber - 1, toLineNumber - fromLineNumber + 1);
this.prefixSumComputer.removeValues(fromLineNumber - 1, toLineNumber - fromLineNumber + 1);
eventsCollector.emit(new viewEvents.ViewLinesDeletedEvent(outputFromLineNumber, outputToLineNumber));
return new viewEvents.ViewLinesDeletedEvent(outputFromLineNumber, outputToLineNumber);
}
public onModelLinesInserted(eventsCollector: ViewEventsCollector, versionId: number, fromLineNumber: number, toLineNumber: number, text: string[]): void {
public onModelLinesInserted(versionId: number, fromLineNumber: number, toLineNumber: number, text: string[]): viewEvents.ViewLinesInsertedEvent {
if (versionId <= this._validModelVersionId) {
// Here we check for versionId in case the lines were reconstructed in the meantime.
// We don't want to apply stale change events on top of a newer read model state.
return;
return null;
}
let hiddenAreas = this.getHiddenAreas();
......@@ -328,14 +324,14 @@ export class SplitLinesCollection {
this.prefixSumComputer.insertValues(fromLineNumber - 1, insertPrefixSumValues);
eventsCollector.emit(new viewEvents.ViewLinesInsertedEvent(outputFromLineNumber, outputFromLineNumber + totalOutputLineCount - 1));
return new viewEvents.ViewLinesInsertedEvent(outputFromLineNumber, outputFromLineNumber + totalOutputLineCount - 1);
}
public onModelLineChanged(eventsCollector: ViewEventsCollector, versionId: number, lineNumber: number, newText: string): boolean {
public onModelLineChanged(versionId: number, lineNumber: number, newText: string): [boolean, viewEvents.ViewLinesChangedEvent, viewEvents.ViewLinesInsertedEvent, viewEvents.ViewLinesDeletedEvent] {
if (versionId <= this._validModelVersionId) {
// Here we check for versionId in case the lines were reconstructed in the meantime.
// We don't want to apply stale change events on top of a newer read model state.
return false;
return [false, null, null, null];
}
let lineIndex = lineNumber - 1;
......@@ -373,17 +369,11 @@ export class SplitLinesCollection {
this.prefixSumComputer.changeValue(lineIndex, newOutputLineCount);
if (changeFrom <= changeTo) {
eventsCollector.emit(new viewEvents.ViewLinesChangedEvent(changeFrom, changeTo));
}
if (insertFrom <= insertTo) {
eventsCollector.emit(new viewEvents.ViewLinesInsertedEvent(insertFrom, insertTo));
}
if (deleteFrom <= deleteTo) {
eventsCollector.emit(new viewEvents.ViewLinesDeletedEvent(deleteFrom, deleteTo));
}
const viewLinesChangedEvent = (changeFrom <= changeTo ? new viewEvents.ViewLinesChangedEvent(changeFrom, changeTo) : null);
const viewLinesInsertedEvent = (insertFrom <= insertTo ? new viewEvents.ViewLinesInsertedEvent(insertFrom, insertTo) : null);
const viewLinesDeletedEvent = (deleteFrom <= deleteTo ? new viewEvents.ViewLinesDeletedEvent(deleteFrom, deleteTo) : null);
return lineMappingChanged;
return [lineMappingChanged, viewLinesChangedEvent, viewLinesInsertedEvent, viewLinesDeletedEvent];
}
public acceptVersionId(versionId: number): void {
......
......@@ -4,13 +4,16 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { INewScrollPosition, IModelDecoration, EndOfLinePreference } from 'vs/editor/common/editorCommon';
import { INewScrollPosition, IModelDecoration, EndOfLinePreference, IViewState } from 'vs/editor/common/editorCommon';
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { ViewEvent } from 'vs/editor/common/view/viewEvents';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Scrollable } from "vs/base/common/scrollable";
import { IPartialViewLinesViewportData } from "vs/editor/common/viewLayout/viewLinesViewportData";
import { IEditorWhitespace } from "vs/editor/common/viewLayout/whitespaceComputer";
export interface IViewWhitespaceViewportData {
readonly id: number;
......@@ -37,6 +40,8 @@ export class Viewport {
export interface IViewLayout {
readonly scrollable: Scrollable;
onMaxLineWidthChanged(width: number): void;
getScrollLeft(): number;
......@@ -44,9 +49,20 @@ export interface IViewLayout {
getScrollHeight(): number;
getScrollTop(): number;
getCurrentViewport(): Viewport;
getVerticalOffsetForLineNumber(lineNumber: number): number;
setScrollPosition(position: INewScrollPosition): void;
getLinesViewportData(): IPartialViewLinesViewportData;
getLinesViewportDataAtScrollTop(scrollTop: number): IPartialViewLinesViewportData;
getWhitespaces(): IEditorWhitespace[];
saveState(): IViewState;
restoreState(state: IViewState): void;
isAfterLines(verticalOffset: number): boolean;
getLineNumberAtVerticalOffset(verticalOffset: number): number;
getVerticalOffsetForLineNumber(lineNumber: number): number;
getWhitespaceAtVerticalOffset(verticalOffset: number): IViewWhitespaceViewportData;
// --------------- Begin vertical whitespace management
/**
......@@ -67,6 +83,9 @@ export interface IViewLayout {
*/
getWhitespaceViewportData(): IViewWhitespaceViewportData[];
// TODO@Alex
onHeightMaybeChanged();
// --------------- End vertical whitespace management
}
......@@ -95,6 +114,8 @@ export interface IViewModel {
readonly coordinatesConverter: ICoordinatesConverter;
readonly viewLayout: IViewLayout;
/**
* Gives a hint that a lot of requests are about to come in for these line numbers.
*/
......
......@@ -9,7 +9,7 @@ import { Position } from 'vs/editor/common/core/position';
import { ICoordinatesConverter, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel';
import { Selection } from 'vs/editor/common/core/selection';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { ICursorRevealRangeEvent, CursorScrollRequest } from 'vs/editor/common/controller/cursorEvents';
import { ICursorRevealRangeEvent } from 'vs/editor/common/controller/cursorEvents';
export interface ICursorPositionChangedEvent {
readonly position: Position;
......@@ -110,8 +110,4 @@ export class ViewModelCursors {
this.onCursorSelectionChanged(eventsCollector, e);
}
}
public onCursorScrollRequest(eventsCollector: ViewEventsCollector, e: CursorScrollRequest): void {
eventsCollector.emit(new viewEvents.ViewScrollRequestEvent(e.desiredScrollTop));
}
}
......@@ -25,6 +25,7 @@ import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOption
import { CursorEventType, ICursorPositionChangedEvent, VerticalRevealType, ICursorSelectionChangedEvent, ICursorRevealRangeEvent, CursorScrollRequest } from 'vs/editor/common/controller/cursorEvents';
import { Cursor } from 'vs/editor/common/controller/cursor';
import { CharacterHardWrappingLineMapperFactory } from "vs/editor/common/viewModel/characterHardWrappingLineMapper";
import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout';
export class CoordinatesConverter implements ICoordinatesConverter {
......@@ -93,6 +94,7 @@ export class ViewModel extends Disposable implements IViewModel {
private readonly model: editorCommon.IModel;
private readonly lines: SplitLinesCollection;
public readonly coordinatesConverter: ICoordinatesConverter;
public readonly viewLayout: ViewLayout;
private readonly decorations: ViewModelDecorations;
private readonly cursors: ViewModelCursors;
......@@ -129,6 +131,12 @@ export class ViewModel extends Disposable implements IViewModel {
this.coordinatesConverter = new CoordinatesConverter(this.lines);
this.viewLayout = this._register(new ViewLayout(this.configuration, this.getLineCount()));
this._register(this.viewLayout.onDidScroll((e) => {
this._emit([new viewEvents.ViewScrollChangedEvent(e)]);
}));
this._isDisposing = false;
this._centeredViewLine = -1;
this._listeners = [];
......@@ -206,7 +214,10 @@ export class ViewModel extends Disposable implements IViewModel {
}
case CursorEventType.CursorScrollRequest: {
const e = <CursorScrollRequest>data;
this.cursors.onCursorScrollRequest(eventsCollector, e);
this.viewLayout.setScrollPosition({
scrollTop: e.desiredScrollTop
});
eventsCollector.emit(new viewEvents.ViewScrollRequestEvent(e.desiredScrollTop)); // TODO@Alex: delete this ev type
break;
}
default:
......@@ -224,10 +235,12 @@ export class ViewModel extends Disposable implements IViewModel {
const conf = this.configuration.editor;
if (this.lines.setWrappingSettings(eventsCollector, conf.wrappingInfo.wrappingIndent, conf.wrappingInfo.wrappingColumn, conf.fontInfo.typicalFullwidthCharacterWidth / conf.fontInfo.typicalHalfwidthCharacterWidth)) {
if (this.lines.setWrappingSettings(conf.wrappingInfo.wrappingIndent, conf.wrappingInfo.wrappingColumn, conf.fontInfo.typicalFullwidthCharacterWidth / conf.fontInfo.typicalHalfwidthCharacterWidth)) {
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
this.decorations.onLineMappingChanged(eventsCollector);
this.cursors.onLineMappingChanged(eventsCollector);
this.viewLayout.onFlushed(this.getLineCount());
revealPreviousCenteredModelRange = true;
}
......@@ -238,6 +251,7 @@ export class ViewModel extends Disposable implements IViewModel {
}
eventsCollector.emit(new viewEvents.ViewConfigurationChangedEvent(e));
this.viewLayout.onConfigurationChanged(e);
if (revealPreviousCenteredModelRange && previousCenteredModelRange) {
// modelLine -> viewLine
......@@ -286,25 +300,48 @@ export class ViewModel extends Disposable implements IViewModel {
const change = changes[j];
switch (change.changeType) {
case textModelEvents.RawContentChangedType.Flush:
this.lines.onModelFlushed(eventsCollector);
case textModelEvents.RawContentChangedType.Flush: {
this.lines.onModelFlushed();
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
this.decorations.reset();
this.viewLayout.onFlushed(this.getLineCount());
hadOtherModelChange = true;
break;
case textModelEvents.RawContentChangedType.LinesDeleted:
this.lines.onModelLinesDeleted(eventsCollector, versionId, change.fromLineNumber, change.toLineNumber);
}
case textModelEvents.RawContentChangedType.LinesDeleted: {
const linesDeletedEvent = this.lines.onModelLinesDeleted(versionId, change.fromLineNumber, change.toLineNumber);
if (linesDeletedEvent !== null) {
eventsCollector.emit(linesDeletedEvent);
this.viewLayout.onLinesDeleted(linesDeletedEvent);
}
hadOtherModelChange = true;
break;
case textModelEvents.RawContentChangedType.LinesInserted:
this.lines.onModelLinesInserted(eventsCollector, versionId, change.fromLineNumber, change.toLineNumber, change.detail.split('\n'));
}
case textModelEvents.RawContentChangedType.LinesInserted: {
const linesInsertedEvent = this.lines.onModelLinesInserted(versionId, change.fromLineNumber, change.toLineNumber, change.detail.split('\n'));
if (linesInsertedEvent !== null) {
eventsCollector.emit(linesInsertedEvent);
this.viewLayout.onLinesInserted(linesInsertedEvent);
}
hadOtherModelChange = true;
break;
case textModelEvents.RawContentChangedType.LineChanged:
hadModelLineChangeThatChangedLineMapping = this.lines.onModelLineChanged(eventsCollector, versionId, change.lineNumber, change.detail);
}
case textModelEvents.RawContentChangedType.LineChanged: {
const [lineMappingChanged, viewLinesChangedEvent, viewLinesInsertedEvent, viewLinesDeletedEvent] = this.lines.onModelLineChanged(versionId, change.lineNumber, change.detail);
hadModelLineChangeThatChangedLineMapping = lineMappingChanged;
if (viewLinesChangedEvent) {
eventsCollector.emit(viewLinesChangedEvent);
}
if (viewLinesInsertedEvent) {
eventsCollector.emit(viewLinesInsertedEvent);
this.viewLayout.onLinesInserted(viewLinesInsertedEvent);
}
if (viewLinesDeletedEvent) {
eventsCollector.emit(viewLinesDeletedEvent);
this.viewLayout.onLinesDeleted(viewLinesDeletedEvent);
}
break;
}
}
}
this.lines.acceptVersionId(versionId);
......@@ -337,10 +374,12 @@ export class ViewModel extends Disposable implements IViewModel {
}
case textModelEvents.TextModelEventType.ModelOptionsChanged: {
// A tab size change causes a line mapping changed event => all view parts will repaint OK, no further event needed here
if (this.lines.setTabSize(eventsCollector, this.model.getOptions().tabSize)) {
if (this.lines.setTabSize(this.model.getOptions().tabSize)) {
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
this.decorations.onLineMappingChanged(eventsCollector);
this.cursors.onLineMappingChanged(eventsCollector);
this.viewLayout.onFlushed(this.getLineCount());
}
break;
......@@ -369,11 +408,13 @@ export class ViewModel extends Disposable implements IViewModel {
public setHiddenAreas(ranges: Range[]): void {
let eventsCollector = new ViewEventsCollector();
let lineMappingChanged = this.lines.setHiddenAreas(eventsCollector, ranges);
let lineMappingChanged = this.lines.setHiddenAreas(ranges);
if (lineMappingChanged) {
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
this.decorations.onLineMappingChanged(eventsCollector);
this.cursors.onLineMappingChanged(eventsCollector);
this.viewLayout.onFlushed(this.getLineCount());
}
this._emit(eventsCollector.finalize());
}
......
......@@ -17,7 +17,7 @@ import { NULL_STATE } from 'vs/editor/common/modes/nullMode';
import { TokenizationResult2 } from 'vs/editor/common/core/token';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ViewLineToken } from 'vs/editor/common/core/viewLineToken';
import { ViewLineData, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel';
import { ViewLineData } from 'vs/editor/common/viewModel/viewModel';
import { Range } from 'vs/editor/common/core/range';
suite('Editor ViewModel - SplitLinesCollection', () => {
......@@ -205,7 +205,7 @@ suite('Editor ViewModel - SplitLinesCollection', () => {
].join('\n');
withSplitLinesCollection(text, (model, linesCollection) => {
linesCollection.setHiddenAreas(new ViewEventsCollector(), [
linesCollection.setHiddenAreas([
new Range(1, 1, 3, 1),
new Range(5, 1, 6, 1)
]);
......@@ -530,7 +530,7 @@ suite('SplitLinesCollection', () => {
_expected[7],
]);
splitLinesCollection.setHiddenAreas(new ViewEventsCollector(), [new Range(2, 1, 4, 1)]);
splitLinesCollection.setHiddenAreas([new Range(2, 1, 4, 1)]);
assert.equal(splitLinesCollection.getViewLineCount(), 5);
assert.equal(splitLinesCollection.modelPositionIsVisible(1, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(2, 1), false);
......@@ -700,7 +700,7 @@ suite('SplitLinesCollection', () => {
_expected[11],
]);
splitLinesCollection.setHiddenAreas(new ViewEventsCollector(), [new Range(2, 1, 4, 1)]);
splitLinesCollection.setHiddenAreas([new Range(2, 1, 4, 1)]);
assert.equal(splitLinesCollection.getViewLineCount(), 8);
assert.equal(splitLinesCollection.modelPositionIsVisible(1, 1), true);
assert.equal(splitLinesCollection.modelPositionIsVisible(2, 1), false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册