Move scroll event emitting through view model (fixes #97447)
This commit is contained in:
parent
1620c36f11
commit
5a1565cefe
6 changed files with 126 additions and 42 deletions
|
@ -13,10 +13,18 @@ export const enum ScrollbarVisibility {
|
|||
}
|
||||
|
||||
export interface ScrollEvent {
|
||||
oldWidth: number;
|
||||
oldScrollWidth: number;
|
||||
oldScrollLeft: number;
|
||||
|
||||
width: number;
|
||||
scrollWidth: number;
|
||||
scrollLeft: number;
|
||||
|
||||
oldHeight: number;
|
||||
oldScrollHeight: number;
|
||||
oldScrollTop: number;
|
||||
|
||||
height: number;
|
||||
scrollHeight: number;
|
||||
scrollTop: number;
|
||||
|
@ -134,10 +142,18 @@ export class ScrollState implements IScrollDimensions, IScrollPosition {
|
|||
const scrollTopChanged = (this.scrollTop !== previous.scrollTop);
|
||||
|
||||
return {
|
||||
oldWidth: previous.width,
|
||||
oldScrollWidth: previous.scrollWidth,
|
||||
oldScrollLeft: previous.scrollLeft,
|
||||
|
||||
width: this.width,
|
||||
scrollWidth: this.scrollWidth,
|
||||
scrollLeft: this.scrollLeft,
|
||||
|
||||
oldHeight: previous.height,
|
||||
oldScrollHeight: previous.scrollHeight,
|
||||
oldScrollTop: previous.scrollTop,
|
||||
|
||||
height: this.height,
|
||||
scrollHeight: this.scrollHeight,
|
||||
scrollTop: this.scrollTop,
|
||||
|
|
|
@ -305,15 +305,6 @@ export class View extends ViewEventHandler {
|
|||
}
|
||||
public onFocusChanged(e: viewEvents.ViewFocusChangedEvent): boolean {
|
||||
this.domNode.setClassName(this.getEditorClassName());
|
||||
if (e.isFocused) {
|
||||
this.outgoingEvents.emitViewFocusGained();
|
||||
} else {
|
||||
this.outgoingEvents.emitViewFocusLost();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
|
||||
this.outgoingEvents.emitScrollChanged(e);
|
||||
return false;
|
||||
}
|
||||
public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
|
||||
|
|
|
@ -9,8 +9,6 @@ import { MouseTarget } from 'vs/editor/browser/controller/mouseTarget';
|
|||
import { IEditorMouseEvent, IMouseTarget, IPartialEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IScrollEvent } from 'vs/editor/common/editorCommon';
|
||||
import * as viewEvents from 'vs/editor/common/view/viewEvents';
|
||||
import { IViewModel, ICoordinatesConverter } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
|
||||
|
@ -20,9 +18,6 @@ export interface EventCallback<T> {
|
|||
|
||||
export class ViewOutgoingEvents extends Disposable {
|
||||
|
||||
public onDidScroll: EventCallback<IScrollEvent> | null = null;
|
||||
public onDidGainFocus: EventCallback<void> | null = null;
|
||||
public onDidLoseFocus: EventCallback<void> | null = null;
|
||||
public onKeyDown: EventCallback<IKeyboardEvent> | null = null;
|
||||
public onKeyUp: EventCallback<IKeyboardEvent> | null = null;
|
||||
public onContextMenu: EventCallback<IEditorMouseEvent> | null = null;
|
||||
|
@ -41,24 +36,6 @@ export class ViewOutgoingEvents extends Disposable {
|
|||
this._viewModel = viewModel;
|
||||
}
|
||||
|
||||
public emitScrollChanged(e: viewEvents.ViewScrollChangedEvent): void {
|
||||
if (this.onDidScroll) {
|
||||
this.onDidScroll(e);
|
||||
}
|
||||
}
|
||||
|
||||
public emitViewFocusGained(): void {
|
||||
if (this.onDidGainFocus) {
|
||||
this.onDidGainFocus(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
public emitViewFocusLost(): void {
|
||||
if (this.onDidLoseFocus) {
|
||||
this.onDidLoseFocus(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
public emitKeyDown(e: IKeyboardEvent): void {
|
||||
if (this.onKeyDown) {
|
||||
this.onKeyDown(e);
|
||||
|
|
|
@ -1515,6 +1515,12 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
|||
case OutgoingViewModelEventKind.ContentSizeChanged:
|
||||
this._onDidContentSizeChange.fire(e);
|
||||
break;
|
||||
case OutgoingViewModelEventKind.FocusChanged:
|
||||
this._editorTextFocus.setValue(e.hasFocus);
|
||||
break;
|
||||
case OutgoingViewModelEventKind.ScrollChanged:
|
||||
this._onDidScrollChange.fire(e);
|
||||
break;
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -1596,14 +1602,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
|||
};
|
||||
}
|
||||
|
||||
const onDidChangeTextFocus = (textFocus: boolean) => {
|
||||
this._editorTextFocus.setValue(textFocus);
|
||||
};
|
||||
|
||||
const viewOutgoingEvents = new ViewOutgoingEvents(viewModel);
|
||||
viewOutgoingEvents.onDidScroll = (e) => this._onDidScrollChange.fire(e);
|
||||
viewOutgoingEvents.onDidGainFocus = () => onDidChangeTextFocus(true);
|
||||
viewOutgoingEvents.onDidLoseFocus = () => onDidChangeTextFocus(false);
|
||||
viewOutgoingEvents.onKeyDown = (e) => this._onKeyDown.fire(e);
|
||||
viewOutgoingEvents.onKeyUp = (e) => this._onKeyUp.fire(e);
|
||||
viewOutgoingEvents.onContextMenu = (e) => this._onContextMenu.fire(e);
|
||||
|
|
|
@ -54,6 +54,9 @@ export class ViewModelEventDispatcher extends Disposable {
|
|||
return;
|
||||
}
|
||||
const event = this._outgoingEvents.shift()!;
|
||||
if (event.isNoOp()) {
|
||||
continue;
|
||||
}
|
||||
this._onEvent.fire(event);
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +146,8 @@ export class ViewModelEventDispatcher extends Disposable {
|
|||
|
||||
export const enum OutgoingViewModelEventKind {
|
||||
ContentSizeChanged,
|
||||
FocusChanged,
|
||||
ScrollChanged,
|
||||
}
|
||||
|
||||
export class ContentSizeChangedEvent implements IContentSizeChangedEvent {
|
||||
|
@ -166,9 +171,100 @@ export class ContentSizeChangedEvent implements IContentSizeChangedEvent {
|
|||
this.contentHeightChanged = (this._oldContentHeight !== this.contentHeight);
|
||||
}
|
||||
|
||||
public merge(other: ContentSizeChangedEvent): ContentSizeChangedEvent {
|
||||
public isNoOp(): boolean {
|
||||
return (!this.contentWidthChanged && !this.contentHeightChanged);
|
||||
}
|
||||
|
||||
|
||||
public merge(other: OutgoingViewModelEvent): ContentSizeChangedEvent {
|
||||
if (other.kind !== OutgoingViewModelEventKind.ContentSizeChanged) {
|
||||
return this;
|
||||
}
|
||||
return new ContentSizeChangedEvent(this._oldContentWidth, this._oldContentHeight, other.contentWidth, other.contentHeight);
|
||||
}
|
||||
}
|
||||
|
||||
export type OutgoingViewModelEvent = ContentSizeChangedEvent;
|
||||
export class FocusChangedEvent {
|
||||
|
||||
public readonly kind = OutgoingViewModelEventKind.FocusChanged;
|
||||
|
||||
readonly oldHasFocus: boolean;
|
||||
readonly hasFocus: boolean;
|
||||
|
||||
constructor(oldHasFocus: boolean, hasFocus: boolean) {
|
||||
this.oldHasFocus = oldHasFocus;
|
||||
this.hasFocus = hasFocus;
|
||||
}
|
||||
|
||||
public isNoOp(): boolean {
|
||||
return (this.oldHasFocus === this.hasFocus);
|
||||
}
|
||||
|
||||
public merge(other: OutgoingViewModelEvent): FocusChangedEvent {
|
||||
if (other.kind !== OutgoingViewModelEventKind.FocusChanged) {
|
||||
return this;
|
||||
}
|
||||
return new FocusChangedEvent(this.oldHasFocus, other.hasFocus);
|
||||
}
|
||||
}
|
||||
|
||||
export class ScrollChangedEvent {
|
||||
|
||||
public readonly kind = OutgoingViewModelEventKind.ScrollChanged;
|
||||
|
||||
private readonly _oldScrollWidth: number;
|
||||
private readonly _oldScrollLeft: number;
|
||||
private readonly _oldScrollHeight: number;
|
||||
private readonly _oldScrollTop: number;
|
||||
|
||||
public readonly scrollWidth: number;
|
||||
public readonly scrollLeft: number;
|
||||
public readonly scrollHeight: number;
|
||||
public readonly scrollTop: number;
|
||||
|
||||
public readonly scrollWidthChanged: boolean;
|
||||
public readonly scrollLeftChanged: boolean;
|
||||
public readonly scrollHeightChanged: boolean;
|
||||
public readonly scrollTopChanged: boolean;
|
||||
|
||||
constructor(
|
||||
oldScrollWidth: number, oldScrollLeft: number, oldScrollHeight: number, oldScrollTop: number,
|
||||
scrollWidth: number, scrollLeft: number, scrollHeight: number, scrollTop: number,
|
||||
) {
|
||||
this._oldScrollWidth = oldScrollWidth;
|
||||
this._oldScrollLeft = oldScrollLeft;
|
||||
this._oldScrollHeight = oldScrollHeight;
|
||||
this._oldScrollTop = oldScrollTop;
|
||||
|
||||
this.scrollWidth = scrollWidth;
|
||||
this.scrollLeft = scrollLeft;
|
||||
this.scrollHeight = scrollHeight;
|
||||
this.scrollTop = scrollTop;
|
||||
|
||||
this.scrollWidthChanged = (this._oldScrollWidth !== this.scrollWidth);
|
||||
this.scrollLeftChanged = (this._oldScrollLeft !== this.scrollLeft);
|
||||
this.scrollHeightChanged = (this._oldScrollHeight !== this.scrollHeight);
|
||||
this.scrollTopChanged = (this._oldScrollTop !== this.scrollTop);
|
||||
}
|
||||
|
||||
public isNoOp(): boolean {
|
||||
return (!this.scrollWidthChanged && !this.scrollLeftChanged && !this.scrollHeightChanged && !this.scrollTopChanged);
|
||||
}
|
||||
|
||||
|
||||
public merge(other: OutgoingViewModelEvent): ScrollChangedEvent {
|
||||
if (other.kind !== OutgoingViewModelEventKind.ScrollChanged) {
|
||||
return this;
|
||||
}
|
||||
return new ScrollChangedEvent(
|
||||
this._oldScrollWidth, this._oldScrollLeft, this._oldScrollHeight, this._oldScrollTop,
|
||||
other.scrollWidth, other.scrollLeft, other.scrollHeight, other.scrollTop
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export type OutgoingViewModelEvent = (
|
||||
ContentSizeChangedEvent
|
||||
| FocusChangedEvent
|
||||
| ScrollChangedEvent
|
||||
);
|
||||
|
|
|
@ -30,7 +30,7 @@ import { Cursor } from 'vs/editor/common/controller/cursor';
|
|||
import { PartialCursorState, CursorState, IColumnSelectData, EditOperationType, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { IWhitespaceChangeAccessor } from 'vs/editor/common/viewLayout/linesLayout';
|
||||
import { ViewModelEventDispatcher, OutgoingViewModelEvent } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
|
||||
import { ViewModelEventDispatcher, OutgoingViewModelEvent, FocusChangedEvent, ScrollChangedEvent } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
|
||||
const USE_IDENTITY_LINES_COLLECTION = true;
|
||||
|
@ -112,6 +112,10 @@ export class ViewModel extends Disposable implements IViewModel {
|
|||
this._tokenizeViewportSoon.schedule();
|
||||
}
|
||||
this._eventDispatcher.emitSingleViewEvent(new viewEvents.ViewScrollChangedEvent(e));
|
||||
this._eventDispatcher.emitOutgoingEvent(new ScrollChangedEvent(
|
||||
e.oldScrollWidth, e.oldScrollLeft, e.oldScrollHeight, e.oldScrollTop,
|
||||
e.scrollWidth, e.scrollLeft, e.scrollHeight, e.scrollTop
|
||||
));
|
||||
}));
|
||||
|
||||
this._register(this.viewLayout.onDidContentSizeChange((e) => {
|
||||
|
@ -172,6 +176,7 @@ export class ViewModel extends Disposable implements IViewModel {
|
|||
this.hasFocus = hasFocus;
|
||||
this.cursor.setHasFocus(hasFocus);
|
||||
this._eventDispatcher.emitSingleViewEvent(new viewEvents.ViewFocusChangedEvent(hasFocus));
|
||||
this._eventDispatcher.emitOutgoingEvent(new FocusChangedEvent(!hasFocus, hasFocus));
|
||||
}
|
||||
|
||||
public onDidColorThemeChange(): void {
|
||||
|
|
Loading…
Reference in a new issue