提交 aae591bd 编写于 作者: A Alex Dima

Move ViewModelCursors out of the ViewModel

上级 beee645a
......@@ -49,6 +49,7 @@ import { EditorScrollbar } from 'vs/editor/browser/viewParts/editorScrollbar/edi
import { Minimap } from 'vs/editor/browser/viewParts/minimap/minimap';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { IThemeService, getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
import { ViewModelCursors } from "vs/editor/common/viewModel/viewModelCursors";
export interface IContentWidgetData {
widget: editorBrowser.IContentWidget;
......@@ -97,6 +98,7 @@ export class View extends ViewEventHandler {
configuration: Configuration,
themeService: IThemeService,
model: IViewModel,
cursor: ViewModelCursors,
execCoreEditorCommandFunc: ExecCoreEditorCommandFunc
) {
super();
......@@ -136,6 +138,10 @@ export class View extends ViewEventHandler {
this._register(model.addEventListener((events: viewEvents.ViewEvent[]) => {
this.eventDispatcher.emitMany(events);
}));
this._register(cursor.addEventListener((events: viewEvents.ViewEvent[]) => {
this.eventDispatcher.emitMany(events);
}));
}
private createViewParts(): void {
......
......@@ -84,9 +84,6 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay {
return false;
}
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
this._primaryCursorIsInEditableRange = true;
this._selectionIsEmpty = true;
this._primaryCursorLineNumber = 1;
return true;
}
public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {
......
......@@ -67,8 +67,6 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay {
return hasChanged;
}
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
this._primaryCursorIsInEditableRange = true;
this._primaryCursorLineNumber = 1;
return true;
}
public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): boolean {
......
......@@ -130,12 +130,6 @@ export class ViewCursor {
return true;
}
public onFlushed(): boolean {
this.updatePosition(new Position(1, 1));
this._isInEditableRange = true;
return true;
}
private _prepareRender(ctx: RenderingContext): ViewCursorRenderData {
if (this._cursorStyle === TextEditorCursorStyle.Line || this._cursorStyle === TextEditorCursorStyle.LineThin) {
const visibleRange = ctx.visibleRangeForPosition(this._position);
......
......@@ -139,11 +139,6 @@ export class ViewCursors extends ViewPart {
return true;
}
public onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
this._primaryCursor.onFlushed();
for (let i = 0, len = this._secondaryCursors.length; i < len; i++) {
this._domNode.removeChild(this._secondaryCursors[i].getDomNode());
}
this._secondaryCursors = [];
return true;
}
public onFocusChanged(e: viewEvents.ViewFocusChangedEvent): boolean {
......
......@@ -422,6 +422,7 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
this._configuration,
this._themeService,
this.viewModel,
this.viewCursor,
(editorCommand: CoreEditorCommand, args: any) => {
if (!this.cursor) {
return;
......
......@@ -28,6 +28,7 @@ import {
import * as editorOptions from 'vs/editor/common/config/editorOptions';
import { CursorEventType, ICursorPositionChangedEvent, VerticalRevealType, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { ViewModelCursors } from "vs/editor/common/viewModel/viewModelCursors";
let EDITOR_ID = 0;
......@@ -99,6 +100,7 @@ export abstract class CommonCodeEditor extends Disposable implements editorCommo
protected viewModel: ViewModel;
protected cursor: Cursor;
protected viewCursor: ViewModelCursors;
protected readonly _instantiationService: IInstantiationService;
protected readonly _contextKeyService: IContextKeyService;
......@@ -932,7 +934,11 @@ export abstract class CommonCodeEditor extends Disposable implements editorCommo
this._enableEmptySelectionClipboard()
);
this.viewModel.addEventSource(this.cursor);
this.viewCursor = new ViewModelCursors(
this._configuration,
this.viewModel,
this.cursor
);
this._createView();
......@@ -994,6 +1000,11 @@ export abstract class CommonCodeEditor extends Disposable implements editorCommo
this.cursor = null;
}
if (this.viewCursor) {
this.viewCursor.dispose();
this.viewCursor = null;
}
if (this.viewModel) {
this.viewModel.dispose();
this.viewModel = null;
......
......@@ -6,10 +6,13 @@
import * as editorCommon from 'vs/editor/common/editorCommon';
import { Position } from 'vs/editor/common/core/position';
import { ICoordinatesConverter, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel';
import { ICoordinatesConverter, ViewEventsCollector, IViewModel } 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 } from 'vs/editor/common/controller/cursorEvents';
import { ICursorRevealRangeEvent, CursorEventType, CursorScrollRequest } from 'vs/editor/common/controller/cursorEvents';
import { Cursor } from "vs/editor/common/controller/cursor";
import { ViewEventEmitter } from "vs/editor/common/viewModel/viewModelImpl";
import { EmitterEvent } from "vs/base/common/eventEmitter";
export interface ICursorPositionChangedEvent {
readonly position: Position;
......@@ -26,19 +29,88 @@ export interface ICursorSelectionChangedEvent {
readonly secondaryViewSelections: Selection[];
}
export class ViewModelCursors {
function containsLineMappingChanged(events: viewEvents.ViewEvent[]): boolean {
for (let i = 0, len = events.length; i < len; i++) {
if (events[i].type === viewEvents.ViewEventType.ViewLineMappingChanged) {
return true;
}
}
return false;
}
export class ViewModelCursors extends ViewEventEmitter {
private readonly configuration: editorCommon.IConfiguration;
private readonly viewModel: IViewModel;
private readonly cursor: Cursor;
private readonly coordinatesConverter: ICoordinatesConverter;
private lastCursorPositionChangedEvent: ICursorPositionChangedEvent;
private lastCursorSelectionChangedEvent: ICursorSelectionChangedEvent;
constructor(configuration: editorCommon.IConfiguration, coordinatesConverter: ICoordinatesConverter) {
constructor(configuration: editorCommon.IConfiguration, viewModel: IViewModel, cursor: Cursor) {
super();
this.configuration = configuration;
this.coordinatesConverter = coordinatesConverter;
this.viewModel = viewModel;
this.cursor = cursor;
this.coordinatesConverter = viewModel.coordinatesConverter;
this.lastCursorPositionChangedEvent = null;
this.lastCursorSelectionChangedEvent = null;
this._register(cursor.addBulkListener((events: EmitterEvent[]) => {
const eventsCollector = new ViewEventsCollector();
this._onCursorEvents(eventsCollector, events);
this._emit(eventsCollector.finalize());
}));
this._register(viewModel.addEventListener((events: viewEvents.ViewEvent[]) => {
if (!containsLineMappingChanged(events)) {
return;
}
const eventsCollector = new ViewEventsCollector();
this.onLineMappingChanged(eventsCollector);
this._emit(eventsCollector.finalize());
}));
}
private _onCursorEvents(eventsCollector: ViewEventsCollector, events: EmitterEvent[]): void {
for (let i = 0, len = events.length; i < len; i++) {
const _e = events[i];
const type = _e.type;
const data = _e.data;
switch (type) {
case CursorEventType.CursorPositionChanged: {
const e = <ICursorPositionChangedEvent>data;
this.onCursorPositionChanged(eventsCollector, e);
break;
}
case CursorEventType.CursorSelectionChanged: {
const e = <ICursorSelectionChangedEvent>data;
this.onCursorSelectionChanged(eventsCollector, e);
break;
}
case CursorEventType.CursorRevealRange: {
const e = <ICursorRevealRangeEvent>data;
this.onCursorRevealRange(eventsCollector, e);
break;
}
case CursorEventType.CursorScrollRequest: {
const e = <CursorScrollRequest>data;
this.viewModel.viewLayout.setScrollPosition({
scrollTop: e.desiredScrollTop
});
break;
}
default:
console.info('View received unknown event: ');
console.info(type, data);
}
}
}
public dispose(): void {
super.dispose();
}
/**
......@@ -52,7 +124,7 @@ export class ViewModelCursors {
return position;
}
public onCursorPositionChanged(eventsCollector: ViewEventsCollector, e: ICursorPositionChangedEvent): void {
private onCursorPositionChanged(eventsCollector: ViewEventsCollector, e: ICursorPositionChangedEvent): void {
this.lastCursorPositionChangedEvent = e;
const stopRenderingLineAfter = this.configuration.editor.viewInfo.stopRenderingLineAfter;
......@@ -66,13 +138,13 @@ export class ViewModelCursors {
eventsCollector.emit(new viewEvents.ViewCursorPositionChangedEvent(position, secondaryPositions, e.isInEditableRange));
}
public onCursorSelectionChanged(eventsCollector: ViewEventsCollector, e: ICursorSelectionChangedEvent): void {
private onCursorSelectionChanged(eventsCollector: ViewEventsCollector, e: ICursorSelectionChangedEvent): void {
this.lastCursorSelectionChangedEvent = e;
eventsCollector.emit(new viewEvents.ViewCursorSelectionChangedEvent(e.viewSelection, e.secondaryViewSelections));
}
public onCursorRevealRange(eventsCollector: ViewEventsCollector, e: ICursorRevealRangeEvent): void {
private onCursorRevealRange(eventsCollector: ViewEventsCollector, e: ICursorRevealRangeEvent): void {
// Ensure event has viewRange
const viewRange = (
e.viewRange
......@@ -86,7 +158,7 @@ export class ViewModelCursors {
));
}
public onLineMappingChanged(eventsCollector: ViewEventsCollector): void {
private onLineMappingChanged(eventsCollector: ViewEventsCollector): void {
if (this.lastCursorPositionChangedEvent) {
const toViewPos = (pos: Position) => this.coordinatesConverter.convertModelPositionToViewPosition(pos);
let e: ICursorPositionChangedEvent = {
......
......@@ -13,7 +13,6 @@ import { Selection } from 'vs/editor/common/core/selection';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { TokenizationRegistry, ColorId, LanguageId } from 'vs/editor/common/modes';
import { tokenizeLineToHTML } from 'vs/editor/common/modes/textToHtmlTokenizer';
import { ViewModelCursors } from 'vs/editor/common/viewModel/viewModelCursors';
import { ViewModelDecorations } from 'vs/editor/common/viewModel/viewModelDecorations';
import { MinimapLinesRenderingData, ViewLineRenderingData, ViewModelDecoration, IViewModelListener, IViewModel, ICoordinatesConverter, ViewEventsCollector } from 'vs/editor/common/viewModel/viewModel';
import { SplitLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection';
......@@ -22,8 +21,7 @@ import * as errors from 'vs/base/common/errors';
import { MinimapTokensColorTracker } from 'vs/editor/common/view/minimapCharRenderer';
import * as textModelEvents from 'vs/editor/common/model/textModelEvents';
import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { CursorEventType, ICursorPositionChangedEvent, VerticalRevealType, ICursorSelectionChangedEvent, ICursorRevealRangeEvent, CursorScrollRequest } from 'vs/editor/common/controller/cursorEvents';
import { Cursor } from 'vs/editor/common/controller/cursor';
import { VerticalRevealType } from 'vs/editor/common/controller/cursorEvents';
import { CharacterHardWrappingLineMapperFactory } from "vs/editor/common/viewModel/characterHardWrappingLineMapper";
import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout';
......@@ -87,7 +85,43 @@ export class CoordinatesConverter implements ICoordinatesConverter {
}
export class ViewModel extends Disposable implements IViewModel {
export class ViewEventEmitter extends Disposable {
private _listeners: IViewModelListener[];
constructor() {
super();
this._listeners = [];
}
public dispose(): void {
this._listeners = [];
super.dispose();
}
protected _emit(events: viewEvents.ViewEvent[]): void {
const listeners = this._listeners.slice(0);
for (let i = 0, len = listeners.length; i < len; i++) {
safeInvokeListener(listeners[i], events);
}
}
public addEventListener(listener: (events: viewEvents.ViewEvent[]) => void): IDisposable {
this._listeners.push(listener);
return {
dispose: () => {
let listeners = this._listeners;
for (let i = 0, len = listeners.length; i < len; i++) {
if (listeners[i] === listener) {
listeners.splice(i, 1);
break;
}
}
}
};
}
}
export class ViewModel extends ViewEventEmitter implements IViewModel {
private readonly editorId: number;
private readonly configuration: editorCommon.IConfiguration;
......@@ -97,11 +131,9 @@ export class ViewModel extends Disposable implements IViewModel {
public readonly viewLayout: ViewLayout;
private readonly decorations: ViewModelDecorations;
private readonly cursors: ViewModelCursors;
private _isDisposing: boolean;
private _centeredViewLine: number;
private _listeners: IViewModelListener[];
constructor(editorId: number, configuration: editorCommon.IConfiguration, model: editorCommon.IModel) {
super();
......@@ -139,12 +171,9 @@ export class ViewModel extends Disposable implements IViewModel {
this._isDisposing = false;
this._centeredViewLine = -1;
this._listeners = [];
this.decorations = new ViewModelDecorations(this.editorId, this.model, this.configuration, this.coordinatesConverter);
this.cursors = new ViewModelCursors(this.configuration, this.coordinatesConverter);
this._register(this.model.addBulkListener((events: EmitterEvent[]) => {
if (this._isDisposing) {
// Disposing the lines might end up sending model decoration changed events
......@@ -171,61 +200,9 @@ export class ViewModel extends Disposable implements IViewModel {
this._isDisposing = true;
this.decorations.dispose();
this.lines.dispose();
this._listeners = [];
super.dispose();
}
private _emit(events: viewEvents.ViewEvent[]): void {
const listeners = this._listeners.slice(0);
for (let i = 0, len = listeners.length; i < len; i++) {
safeInvokeListener(listeners[i], events);
}
}
public addEventSource(cursor: Cursor): void {
this._register(cursor.addBulkListener((events: EmitterEvent[]) => {
const eventsCollector = new ViewEventsCollector();
this._onCursorEvents(eventsCollector, events);
this._emit(eventsCollector.finalize());
}));
}
private _onCursorEvents(eventsCollector: ViewEventsCollector, events: EmitterEvent[]): void {
for (let i = 0, len = events.length; i < len; i++) {
const _e = events[i];
const type = _e.type;
const data = _e.data;
switch (type) {
case CursorEventType.CursorPositionChanged: {
const e = <ICursorPositionChangedEvent>data;
this.cursors.onCursorPositionChanged(eventsCollector, e);
break;
}
case CursorEventType.CursorSelectionChanged: {
const e = <ICursorSelectionChangedEvent>data;
this.cursors.onCursorSelectionChanged(eventsCollector, e);
break;
}
case CursorEventType.CursorRevealRange: {
const e = <ICursorRevealRangeEvent>data;
this.cursors.onCursorRevealRange(eventsCollector, e);
break;
}
case CursorEventType.CursorScrollRequest: {
const e = <CursorScrollRequest>data;
this.viewLayout.setScrollPosition({
scrollTop: e.desiredScrollTop
});
break;
}
default:
console.info('View received unknown event: ');
console.info(type, data);
}
}
}
private _onConfigurationChanged(eventsCollector: ViewEventsCollector, e: IConfigurationChangedEvent): void {
// We might need to restore the current centered view range, so save it (if available)
......@@ -238,7 +215,6 @@ export class ViewModel extends Disposable implements IViewModel {
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;
}
......@@ -377,7 +353,6 @@ export class ViewModel extends Disposable implements IViewModel {
eventsCollector.emit(new viewEvents.ViewFlushedEvent());
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
this.decorations.onLineMappingChanged(eventsCollector);
this.cursors.onLineMappingChanged(eventsCollector);
this.viewLayout.onFlushed(this.getLineCount());
}
......@@ -401,7 +376,6 @@ export class ViewModel extends Disposable implements IViewModel {
if (!hadOtherModelChange && hadModelLineChangeThatChangedLineMapping) {
eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent());
this.decorations.onLineMappingChanged(eventsCollector);
this.cursors.onLineMappingChanged(eventsCollector);
}
}
......@@ -412,27 +386,11 @@ export class ViewModel extends Disposable implements IViewModel {
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());
}
public addEventListener(listener: (events: viewEvents.ViewEvent[]) => void): IDisposable {
this._listeners.push(listener);
return {
dispose: () => {
let listeners = this._listeners;
for (let i = 0, len = listeners.length; i < len; i++) {
if (listeners[i] === listener) {
listeners.splice(i, 1);
break;
}
}
}
};
}
public getCenteredRangeInViewport(): Range {
if (this._centeredViewLine === -1) {
// Never got rendered or not rendered since last content change event
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册