Event Dispatcher

This commit is contained in:
rebornix
2020-03-23 15:58:50 -07:00
parent 343fdecf0f
commit deddc655bd
12 changed files with 125 additions and 72 deletions
@@ -127,7 +127,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
}
}
async $updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata | undefined): Promise<void> {
async $updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata): Promise<void> {
let controller = this._notebookProviders.get(viewType);
if (controller) {
@@ -236,7 +236,7 @@ export class MainThreadNotebookController implements IMainNotebookController {
document?.textModel.updateLanguages(languages);
}
updateNotebookMetadata(resource: UriComponents, metadata: NotebookDocumentMetadata | undefined) {
updateNotebookMetadata(resource: UriComponents, metadata: NotebookDocumentMetadata) {
let document = this._mapping.get(URI.from(resource).toString());
document?.textModel.updateNotebookMetadata(metadata);
}
@@ -693,7 +693,7 @@ export interface MainThreadNotebookShape extends IDisposable {
$unregisterNotebookRenderer(handle: number): Promise<void>;
$createNotebookDocument(handle: number, viewType: string, resource: UriComponents): Promise<void>;
$updateNotebookLanguages(viewType: string, resource: UriComponents, languages: string[]): Promise<void>;
$updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata | undefined): Promise<void>;
$updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata): Promise<void>;
$updateNotebookCellMetadata(viewType: string, resource: UriComponents, handle: number, metadata: NotebookCellMetadata): Promise<void>;
$spliceNotebookCells(viewType: string, resource: UriComponents, splices: NotebookCellsSplice[], renderers: number[]): Promise<void>;
$spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[], renderers: number[]): Promise<void>;
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
@@ -17,10 +16,12 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
import { IModelDecorationsChangeAccessor, NotebookViewModel, CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellKind, IOutput, IRenderOutput, NotebookCellMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { NOTEBOOK_EDITABLE_CONTEXT_KEY } from 'vs/workbench/contrib/notebook/browser/constants';
export const KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED = new RawContextKey<boolean>('notebookFindWidgetFocused', false);
export const NOTEBOOK_EDITOR_FOCUSED = new RawContextKey<boolean>('notebookEditorFocused', false);
export const NOTEBOOK_EDITOR_EDITABLE = new RawContextKey<boolean>(NOTEBOOK_EDITABLE_CONTEXT_KEY, true);
export interface NotebookLayoutInfo {
width: number;
@@ -34,11 +35,6 @@ export interface NotebookLayoutChangeEvent {
fontInfo?: boolean;
}
export interface NotebookViewLayoutAccessor {
layoutInfo: NotebookLayoutInfo | null;
onDidChangeLayout: Event<NotebookLayoutChangeEvent>;
}
export interface CodeCellLayoutInfo {
readonly fontInfo: BareFontInfo | null;
readonly editorHeight: number;
@@ -52,7 +48,8 @@ export interface CodeCellLayoutChangeEvent {
editorHeight?: boolean;
outputHeight?: boolean;
totalHeight?: boolean;
outerWidth?: boolean;
outerWidth?: number;
font?: BareFontInfo;
}
export interface MarkdownCellLayoutInfo {
@@ -61,7 +58,8 @@ export interface MarkdownCellLayoutInfo {
}
export interface MarkdownCellLayoutChangeEvent {
outerWidth?: boolean;
font?: BareFontInfo;
outerWidth?: number;
}
export interface ICellViewModel {
@@ -22,7 +22,7 @@ import { contrastBorder, editorBackground, focusBorder, foreground, textBlockQuo
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { EditorOptions, IEditorMemento, IEditorCloseEvent } from 'vs/workbench/common/editor';
import { INotebookEditor, NotebookLayoutInfo, CellEditState, NOTEBOOK_EDITOR_FOCUSED, CellFocusMode, ICellViewModel, CellRunState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { INotebookEditor, NotebookLayoutInfo, CellEditState, NOTEBOOK_EDITOR_FOCUSED, CellFocusMode, ICellViewModel, CellRunState, NOTEBOOK_EDITOR_EDITABLE } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NotebookEditorInput, NotebookEditorModel } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput';
import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService';
import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/view/output/outputRenderer';
@@ -44,6 +44,7 @@ import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewMod
import { Range } from 'vs/editor/common/core/range';
import { CELL_MARGIN, RUN_BUTTON_WIDTH } from 'vs/workbench/contrib/notebook/browser/constants';
import { Color, RGBA } from 'vs/base/common/color';
import { NotebookEventDispatcher, NotebookLayoutChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
const $ = DOM.$;
const NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'NotebookEditorViewState';
@@ -95,6 +96,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
private list: NotebookCellList | undefined;
private control: ICompositeCodeEditor | undefined;
private renderedEditors: Map<ICellViewModel, ICodeEditor | undefined> = new Map();
private eventDispatcher: NotebookEventDispatcher | undefined;
private notebookViewModel: NotebookViewModel | undefined;
private localStore: DisposableStore = this._register(new DisposableStore());
private editorMemento: IEditorMemento<INotebookEditorViewState>;
@@ -102,6 +104,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
private fontInfo: BareFontInfo | undefined;
private dimension: DOM.Dimension | null = null;
private editorFocus: IContextKey<boolean> | null = null;
private editorEditable: IContextKey<boolean> | null = null;
private outputRenderer: OutputRenderer;
private findWidget: NotebookFindWidget;
@@ -156,6 +159,9 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
this._register(this.onDidBlur(() => {
this.editorFocus?.set(false);
}));
this.editorEditable = NOTEBOOK_EDITOR_EDITABLE.bindTo(this.contextKeyService);
this.editorEditable.set(true);
}
private generateFontInfo(): void {
@@ -175,8 +181,8 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
DOM.addClass(this.body, 'cell-list-container');
const renders = [
this.instantiationService.createInstance(CodeCellRenderer, this, this.renderedEditors),
this.instantiationService.createInstance(MarkdownCellRenderer, this),
this.instantiationService.createInstance(CodeCellRenderer, this, this.contextKeyService, this.renderedEditors),
this.instantiationService.createInstance(MarkdownCellRenderer, this.contextKeyService, this),
];
this.list = <NotebookCellList>this.instantiationService.createInstance(
@@ -331,11 +337,16 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
this.list?.rowsContainer.insertAdjacentElement('afterbegin', this.webview!.element);
}
this.notebookViewModel = this.instantiationService.createInstance(NotebookViewModel, input.viewType!, model);
this.notebookViewModel?.updateLayoutInfo(this.getLayoutInfo());
this.eventDispatcher = new NotebookEventDispatcher();
this.notebookViewModel = this.instantiationService.createInstance(NotebookViewModel, input.viewType!, model, this.eventDispatcher);
this.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
const viewState = this.loadTextEditorViewState(input);
this.notebookViewModel.restoreEditorViewState(viewState);
this.localStore.add(this.eventDispatcher.onDidChangeMetadata((e) => {
this.editorEditable?.set(e.source.editable);
}));
this.localStore.add(this.notebookViewModel.onDidChangeViewCells((e) => {
if (e.synchronous) {
e.splices.reverse().forEach((diff) => {
@@ -408,7 +419,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
DOM.toggleClass(this.rootElement, 'narrow-width', dimension.width < 600);
DOM.size(this.body, dimension.width, dimension.height);
this.list?.layout(dimension.height, dimension.width);
this.notebookViewModel?.updateLayoutInfo(this.getLayoutInfo());
this.eventDispatcher?.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
}
protected saveState(): void {
@@ -23,7 +23,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_PADDING, NOTEBOOK_CELL_EDITABLE_CONTEXT_KEY, NOTEBOOK_CELL_TYPE_CONTEXT_KEY, NOTEBOOK_EDITABLE_CONTEXT_KEY, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE_CONTEXT_KEY } from 'vs/workbench/contrib/notebook/browser/constants';
import { EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_PADDING, NOTEBOOK_CELL_EDITABLE_CONTEXT_KEY, NOTEBOOK_CELL_TYPE_CONTEXT_KEY, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE_CONTEXT_KEY } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellRenderTemplate, CellRunState, ICellViewModel, INotebookEditor, CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellMenus } from 'vs/workbench/contrib/notebook/browser/view/renderers/cellMenus';
import { CodeCell } from 'vs/workbench/contrib/notebook/browser/view/renderers/codeCell';
@@ -155,13 +155,13 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
private disposables: Map<ICellViewModel, DisposableStore> = new Map();
constructor(
contextKeyService: IContextKeyService,
notehookEditor: INotebookEditor,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@IContextMenuService contextMenuService: IContextMenuService,
@IKeybindingService keybindingService: IKeybindingService,
@INotificationService notificationService: INotificationService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super(instantiationService, notehookEditor, contextMenuService, configurationService, keybindingService, notificationService, contextKeyService, 'markdown');
}
@@ -215,9 +215,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
elementDisposable.add(new StatefullMarkdownCell(this.notebookEditor, element, templateData, this.editorOptions, this.instantiationService));
const contextKeyService = this.contextKeyService.createScoped(templateData.container);
contextKeyService.createKey(NOTEBOOK_EDITABLE_CONTEXT_KEY, this.notebookEditor.viewModel?.metadata?.editable);
contextKeyService.createKey(NOTEBOOK_CELL_TYPE_CONTEXT_KEY, 'markdown');
const cellEditableKey = contextKeyService.createKey(NOTEBOOK_CELL_EDITABLE_CONTEXT_KEY, element.metadata.editable);
elementDisposable.add(element.onDidChangeMetadata((e) => {
cellEditableKey.set(e.editable);
@@ -256,13 +254,13 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
constructor(
protected notebookEditor: INotebookEditor,
protected contextKeyService: IContextKeyService,
private renderedEditors: Map<ICellViewModel, ICodeEditor | undefined>,
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService configurationService: IConfigurationService,
@IInstantiationService instantiationService: IInstantiationService,
@IKeybindingService keybindingService: IKeybindingService,
@INotificationService notificationService: INotificationService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
super(instantiationService, notebookEditor, contextMenuService, configurationService, keybindingService, notificationService, contextKeyService, 'python');
}
@@ -357,9 +355,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
};
const contextKeyService = this.contextKeyService.createScoped(templateData.container);
contextKeyService.createKey(NOTEBOOK_EDITABLE_CONTEXT_KEY, this.notebookEditor.viewModel?.metadata?.editable);
contextKeyService.createKey(NOTEBOOK_CELL_TYPE_CONTEXT_KEY, 'code');
const cellEditableKey = contextKeyService.createKey(NOTEBOOK_CELL_EDITABLE_CONTEXT_KEY, element.metadata.editable);
elementDisposable.add(element.onDidChangeMetadata((e) => {
cellEditableKey.set(e.editable);
@@ -9,9 +9,10 @@ import * as model from 'vs/editor/common/model';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer';
import { EDITOR_BOTTOM_PADDING, EDITOR_TOOLBAR_HEIGHT, EDITOR_TOP_PADDING, CELL_MARGIN, RUN_BUTTON_WIDTH } from 'vs/workbench/contrib/notebook/browser/constants';
import { CellEditState, ICellViewModel, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo, NotebookViewLayoutAccessor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellEditState, ICellViewModel, CellFindMatch, CodeCellLayoutChangeEvent, CodeCellLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellKind, ICell, NotebookCellOutputsSplice } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { BaseCellViewModel } from './baseCellViewModel';
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
export class CodeCellViewModel extends BaseCellViewModel implements ICellViewModel {
cellKind: CellKind.Code = CellKind.Code;
@@ -59,7 +60,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
readonly viewType: string,
readonly notebookHandle: number,
readonly cell: ICell,
private _layoutAccessor: NotebookViewLayoutAccessor,
readonly eventDispatcher: NotebookEventDispatcher,
@ITextModelService private readonly _modelService: ITextModelService,
) {
super(viewType, notebookHandle, cell, UUID.generateUuid());
@@ -75,7 +76,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
this._buffer = null;
this._layoutInfo = {
fontInfo: _layoutAccessor.layoutInfo?.fontInfo || null,
fontInfo: null,
editorHeight: 0,
editorWidth: 0,
outputTotalHeight: 0,
@@ -83,9 +84,9 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
indicatorHeight: 0
};
this._register(_layoutAccessor.onDidChangeLayout((e) => {
if (e.width) {
this.layoutChange({ outerWidth: true });
this._register(eventDispatcher.onDidChangeLayout((e) => {
if (e.source.width !== undefined) {
this.layoutChange({ outerWidth: e.value.width, font: e.value.fontInfo });
}
}));
}
@@ -98,9 +99,9 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
? EDITOR_TOOLBAR_HEIGHT + this.editorHeight + EDITOR_TOP_PADDING + EDITOR_BOTTOM_PADDING + 16 + outputTotalHeight
: EDITOR_TOOLBAR_HEIGHT + this.editorHeight + EDITOR_TOP_PADDING + EDITOR_BOTTOM_PADDING + outputTotalHeight;
const indicatorHeight = totalHeight - EDITOR_TOOLBAR_HEIGHT - 16;
const editorWidth = this._layoutAccessor.layoutInfo ? this._layoutAccessor.layoutInfo.width - CELL_MARGIN * 2 - RUN_BUTTON_WIDTH : 0;
const editorWidth = state.outerWidth !== undefined ? state.outerWidth - CELL_MARGIN * 2 - RUN_BUTTON_WIDTH : 0;
this._layoutInfo = {
fontInfo: this._layoutAccessor.layoutInfo?.fontInfo || null,
fontInfo: state.font || null,
editorHeight: this._editorHeight,
editorWidth,
outputTotalHeight,
@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Emitter } from 'vs/base/common/event';
import { NotebookDocumentMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { NotebookLayoutChangeEvent, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
export enum NotebookViewEventType {
LayoutChanged = 1,
MetadataChanged = 2
}
export class NotebookLayoutChangedEvent {
public readonly type = NotebookViewEventType.LayoutChanged;
constructor(readonly source: NotebookLayoutChangeEvent, readonly value: NotebookLayoutInfo) {
}
}
export class NotebookMetadataChangedEvent {
public readonly type = NotebookViewEventType.MetadataChanged;
constructor(readonly source: NotebookDocumentMetadata) {
}
}
export type NotebookViewEvent = NotebookLayoutChangedEvent | NotebookMetadataChangedEvent;
export class NotebookEventDispatcher {
protected readonly _onDidChangeLayout = new Emitter<NotebookLayoutChangedEvent>();
readonly onDidChangeLayout = this._onDidChangeLayout.event;
protected readonly _onDidChangeMetadata = new Emitter<NotebookMetadataChangedEvent>();
readonly onDidChangeMetadata = this._onDidChangeMetadata.event;
constructor() {
}
emit(events: NotebookViewEvent[]) {
for (let i = 0, len = events.length; i < len; i++) {
let e = events[i];
switch (e.type) {
case NotebookViewEventType.LayoutChanged:
this._onDidChangeLayout.fire(e);
break;
case NotebookViewEventType.MetadataChanged:
this._onDidChangeMetadata.fire(e);
break;
}
}
}
}
@@ -8,11 +8,12 @@ import * as UUID from 'vs/base/common/uuid';
import * as model from 'vs/editor/common/model';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICellViewModel, CellFindMatch, NotebookViewLayoutAccessor, MarkdownCellLayoutInfo, MarkdownCellLayoutChangeEvent, CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { ICellViewModel, CellFindMatch, MarkdownCellLayoutInfo, MarkdownCellLayoutChangeEvent, CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { MarkdownRenderer } from 'vs/workbench/contrib/notebook/browser/view/renderers/mdRenderer';
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
import { CellKind, ICell } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CELL_MARGIN } from 'vs/workbench/contrib/notebook/browser/constants';
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
export class MarkdownCellViewModel extends BaseCellViewModel implements ICellViewModel {
cellKind: CellKind.Markdown = CellKind.Markdown;
@@ -34,29 +35,29 @@ export class MarkdownCellViewModel extends BaseCellViewModel implements ICellVie
readonly viewType: string,
readonly notebookHandle: number,
readonly cell: ICell,
private _layoutAccessor: NotebookViewLayoutAccessor,
readonly eventDispatcher: NotebookEventDispatcher,
@IInstantiationService private readonly _instaService: IInstantiationService,
@ITextModelService private readonly _modelService: ITextModelService) {
super(viewType, notebookHandle, cell, UUID.generateUuid());
this._layoutInfo = {
fontInfo: this._layoutAccessor.layoutInfo?.fontInfo || null,
fontInfo: null,
editorWidth: 0
};
this._register(_layoutAccessor.onDidChangeLayout((e) => {
if (e.width) {
this.layoutChange({ outerWidth: true });
this._register(eventDispatcher.onDidChangeLayout((e) => {
if (e.source.width || e.source.fontInfo) {
this.layoutChange({ outerWidth: e.value.width, font: e.value.fontInfo });
}
}));
}
layoutChange(state: MarkdownCellLayoutChangeEvent) {
// recompute
const editorWidth = this._layoutAccessor.layoutInfo ? this._layoutAccessor.layoutInfo.width - CELL_MARGIN * 2 : 0;
const editorWidth = state.outerWidth !== undefined ? state.outerWidth - CELL_MARGIN * 2 : 0;
this._layoutInfo = {
fontInfo: this._layoutAccessor.layoutInfo?.fontInfo || null,
fontInfo: state.font || null,
editorWidth
};
@@ -14,12 +14,13 @@ import { IModelDeltaDecoration } from 'vs/editor/common/model';
import { WorkspaceTextEdit } from 'vs/editor/common/modes';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { CellFindMatch, CellEditState, ICellViewModel, NotebookLayoutChangeEvent, NotebookViewLayoutAccessor, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellFindMatch, CellEditState, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NotebookEditorModel } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput';
import { DeleteCellEdit, InsertCellEdit, MoveCellEdit } from 'vs/workbench/contrib/notebook/browser/viewModel/cellEdit';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { MarkdownCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markdownCellViewModel';
import { CellKind, ICell } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { NotebookEventDispatcher, NotebookMetadataChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
export interface INotebookEditorViewState {
editingCells: { [key: number]: boolean };
@@ -54,7 +55,7 @@ export interface INotebookViewCellsUpdateEvent {
splices: NotebookViewCellsSplice[];
}
export class NotebookViewModel extends Disposable implements NotebookViewLayoutAccessor {
export class NotebookViewModel extends Disposable {
private _localStore: DisposableStore = this._register(new DisposableStore());
private _viewCells: CellViewModel[] = [];
@@ -98,16 +99,10 @@ export class NotebookViewModel extends Disposable implements NotebookViewLayoutA
return null;
}
protected readonly _onDidChangeLayout = new Emitter<NotebookLayoutChangeEvent>();
readonly onDidChangeLayout = this._onDidChangeLayout.event;
private _layoutInfo: NotebookLayoutInfo | null = null;
get layoutInfo() {
return this._layoutInfo;
}
constructor(
public viewType: string,
private _model: NotebookEditorModel,
readonly eventDispatcher: NotebookEventDispatcher,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IBulkEditService private readonly bulkEditService: IBulkEditService,
@IUndoRedoService private readonly undoService: IUndoRedoService
@@ -125,6 +120,10 @@ export class NotebookViewModel extends Disposable implements NotebookViewLayoutA
});
}));
this._register(this._model.notebook.onDidChangeMetadata(e => {
this.eventDispatcher.emit([new NotebookMetadataChangedEvent(e)]);
}));
this._viewCells = this._model!.notebook!.cells.map(cell => {
return createCellViewModel(this.instantiationService, this, cell);
});
@@ -383,24 +382,6 @@ export class NotebookViewModel extends Disposable implements NotebookViewLayoutA
return this._model === model;
}
updateLayoutInfo(layoutInfo: NotebookLayoutInfo | null) {
if (layoutInfo === null) {
return;
}
if (this._layoutInfo === null) {
this._layoutInfo = layoutInfo;
this._onDidChangeLayout.fire({ width: true, height: true });
return;
}
let widthChanged = layoutInfo.width !== this._layoutInfo.width;
let heightChanged = layoutInfo.height !== this._layoutInfo.height;
this._layoutInfo = layoutInfo;
this._onDidChangeLayout.fire({ width: widthChanged, height: heightChanged });
}
dispose() {
this._localStore.clear();
this._viewCells.forEach(cell => {
@@ -416,8 +397,8 @@ export type CellViewModel = CodeCellViewModel | MarkdownCellViewModel;
export function createCellViewModel(instantiationService: IInstantiationService, notebookViewModel: NotebookViewModel, cell: ICell) {
if (cell.cellKind === CellKind.Code) {
return instantiationService.createInstance(CodeCellViewModel, notebookViewModel.viewType, notebookViewModel.handle, cell, notebookViewModel);
return instantiationService.createInstance(CodeCellViewModel, notebookViewModel.viewType, notebookViewModel.handle, cell, notebookViewModel.eventDispatcher);
} else {
return instantiationService.createInstance(MarkdownCellViewModel, notebookViewModel.viewType, notebookViewModel.handle, cell, notebookViewModel);
return instantiationService.createInstance(MarkdownCellViewModel, notebookViewModel.viewType, notebookViewModel.handle, cell, notebookViewModel.eventDispatcher);
}
}
@@ -16,6 +16,8 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
get onDidChangeCells(): Event<NotebookCellsSplice[]> { return this._onDidChangeCells.event; }
private _onDidChangeContent = new Emitter<void>();
onDidChangeContent: Event<void> = this._onDidChangeContent.event;
private _onDidChangeMetadata = new Emitter<NotebookDocumentMetadata>();
onDidChangeMetadata: Event<NotebookDocumentMetadata> = this._onDidChangeMetadata.event;
private _mapping: Map<number, NotebookCellTextModel> = new Map();
private _cellListeners: Map<number, IDisposable> = new Map();
cells: NotebookCellTextModel[];
@@ -36,8 +38,9 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
this.languages = languages;
}
updateNotebookMetadata(metadata: NotebookDocumentMetadata | undefined) {
updateNotebookMetadata(metadata: NotebookDocumentMetadata) {
this.metadata = metadata;
this._onDidChangeMetadata.fire(this.metadata);
}
updateNotebookCellMetadata(handle: number, metadata: NotebookCellMetadata) {
@@ -13,6 +13,7 @@ import { withTestNotebook, TestCell } from 'vs/workbench/contrib/notebook/test/t
import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
suite('NotebookViewModel', () => {
const instantiationService = new TestInstantiationService();
@@ -23,7 +24,8 @@ suite('NotebookViewModel', () => {
test('ctor', function () {
const notebook = new NotebookTextModel(0, 'notebook', URI.parse('test'));
const model = new NotebookEditorModel(notebook);
const viewModel = new NotebookViewModel('notebook', model, instantiationService, blukEditService, undoRedoService);
const eventDispatcher = new NotebookEventDispatcher();
const viewModel = new NotebookViewModel('notebook', model, eventDispatcher, instantiationService, blukEditService, undoRedoService);
assert.equal(viewModel.viewType, 'notebook');
});
@@ -19,6 +19,7 @@ import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { NotebookEventDispatcher } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher';
export class TestCell implements ICell {
uri: URI;
@@ -202,7 +203,8 @@ export function withTestNotebook(instantiationService: IInstantiationService, bl
return new NotebookCellTextModel(notebook.uri, index, cell[0], cell[1], cell[2], cell[3], cell[4]);
});
const model = new NotebookEditorModel(notebook);
const viewModel = new NotebookViewModel(viewType, model, instantiationService, blukEditService, undoRedoService);
const eventDispatcher = new NotebookEventDispatcher();
const viewModel = new NotebookViewModel(viewType, model, eventDispatcher, instantiationService, blukEditService, undoRedoService);
callback(editor, viewModel);