From e2d1be58150c664efeb055626cb62e9dac335408 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 15 Mar 2022 18:20:28 -0700 Subject: [PATCH] Move more code out of cellRenderer and into cell parts For #131808 --- .../browser/view/cellParts/cellExecution.ts | 12 +-- .../view/cellParts/cellFocusIndicator.ts | 36 +++++++- .../browser/view/cellParts/codeCell.ts | 3 +- .../browser/view/cellParts/markdownCell.ts | 18 ++-- .../browser/view/notebookRenderingCommon.ts | 11 +-- .../browser/view/renderers/cellRenderer.ts | 83 ++++++------------- 6 files changed, 77 insertions(+), 86 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts index fa55fbc4bfdf3..3607f2c6adbbe 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution.ts @@ -13,33 +13,33 @@ import { NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/comm export class CellExecutionPart extends CellPart { private kernelDisposables = new DisposableStore(); + private currentCell: ICellViewModel | undefined; constructor( private readonly _notebookEditor: INotebookEditorDelegate, private readonly _executionOrderLabel: HTMLElement ) { super(); - } - setup(templateData: BaseCellRenderTemplate): void { this._register(this._notebookEditor.onDidChangeActiveKernel(() => { - if (templateData.currentRenderedCell) { + if (this.currentCell) { this.kernelDisposables.clear(); if (this._notebookEditor.activeKernel) { this.kernelDisposables.add(this._notebookEditor.activeKernel.onDidChange(() => { - if (templateData.currentRenderedCell) { - this.updateExecutionOrder(templateData.currentRenderedCell.internalMetadata); + if (this.currentCell) { + this.updateExecutionOrder(this.currentCell.internalMetadata); } })); } - this.updateExecutionOrder(templateData.currentRenderedCell.internalMetadata); + this.updateExecutionOrder(this.currentCell.internalMetadata); } })); } renderCell(element: ICellViewModel, _templateData: BaseCellRenderTemplate): void { + this.currentCell = element; this.updateExecutionOrder(element.internalMetadata); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts index 24f198956ad70..3256bf57fe99f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts @@ -5,9 +5,12 @@ import * as DOM from 'vs/base/browser/dom'; import { FastDomNode } from 'vs/base/browser/fastDomNode'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellViewModelStateChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents'; import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; +import { CellTitleToolbarPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars'; +import { BaseCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel'; import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -20,6 +23,7 @@ export class CellFocusIndicator extends CellPart { constructor( readonly notebookEditor: INotebookEditorDelegate, + readonly titleToolbar: CellTitleToolbarPart, readonly top: FastDomNode, readonly left: FastDomNode, readonly right: FastDomNode, @@ -53,8 +57,9 @@ export class CellFocusIndicator extends CellPart { })); } - renderCell(element: ICellViewModel): void { + renderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void { this.currentElement = element; + this.updateFocusIndicatorsForTitleMenuAndSubscribe(element, templateData.elementDisposables); } prepareLayout(): void { @@ -86,4 +91,33 @@ export class CellFocusIndicator extends CellPart { updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void { // nothing to update } + + private updateFocusIndicatorsForTitleMenuAndSubscribe(element: ICellViewModel, disposables: DisposableStore) { + // todo@rebornix, consolidate duplicated requests in next frame + disposables.add(DOM.scheduleAtNextAnimationFrame(() => { + this.updateFocusIndicatorsForTitleMenu(); + })); + + disposables.add(element.onDidChangeLayout(() => { + disposables.add(DOM.scheduleAtNextAnimationFrame(() => { + this.updateFocusIndicatorsForTitleMenu(); + })); + })); + + disposables.add(this.titleToolbar.onDidUpdateActions(() => { + this.updateFocusIndicatorsForTitleMenu(); + })); + } + + private updateFocusIndicatorsForTitleMenu(): void { + const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration(); + if (this.titleToolbar.hasActions) { + this.left.domNode.style.transform = `translateY(${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px)`; + this.right.domNode.style.transform = `translateY(${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px)`; + } else { + this.left.domNode.style.transform = `translateY(${layoutInfo.cellTopMargin}px)`; + this.right.domNode.style.transform = `translateY(${layoutInfo.cellTopMargin}px)`; + } + } + } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts index 3465aa8c244fd..e239f5701d449 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -45,7 +45,6 @@ export class CodeCell extends Disposable { private readonly notebookEditor: IActiveNotebookEditorDelegate, private readonly viewCell: CodeCellViewModel, private readonly templateData: CodeCellRenderTemplate, - cellPartTemplates: CellPart[], @IInstantiationService private readonly instantiationService: IInstantiationService, @INotebookCellStatusBarService readonly notebookCellStatusBarService: INotebookCellStatusBarService, @IKeybindingService readonly keybindingService: IKeybindingService, @@ -58,7 +57,7 @@ export class CodeCell extends Disposable { const cellEditorOptions = this._register(new CellEditorOptions(this.notebookEditor, this.notebookEditor.notebookOptions, this.configurationService, this.viewCell.language)); this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData, { limit: 2 }); - this.cellParts = [...cellPartTemplates, cellEditorOptions, this._outputContainerRenderer]; + this.cellParts = [...templateData.cellParts, cellEditorOptions, this._outputContainerRenderer]; const editorHeight = this.calculateInitEditorHeight(); this.initializeEditor(editorHeight); diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts index d5a0b97e99821..4b3bca20f9b7c 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell.ts @@ -7,28 +7,27 @@ import * as DOM from 'vs/base/browser/dom'; import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels'; import { disposableTimeout, raceCancellation } from 'vs/base/common/async'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { Codicon, CSSIcon } from 'vs/base/common/codicons'; import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { ILanguageService } from 'vs/editor/common/languages/language'; import { tokenizeToStringSync } from 'vs/editor/common/languages/textToHtmlTokenizer'; import { IReadonlyTextBuffer } from 'vs/editor/common/model'; -import { ILanguageService } from 'vs/editor/common/languages/language'; +import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { CellEditState, CellFocusMode, CellFoldingState, EXPAND_CELL_INPUT_COMMAND_ID, IActiveNotebookEditorDelegate, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { collapsedIcon, expandedIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons'; import { CellEditorOptions } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions'; -import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; import { MarkdownCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel'; import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService'; -import { localize } from 'vs/nls'; -import { Codicon, CSSIcon } from 'vs/base/common/codicons'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; export class StatefulMarkdownCell extends Disposable { @@ -48,7 +47,6 @@ export class StatefulMarkdownCell extends Disposable { private readonly notebookEditor: IActiveNotebookEditorDelegate, private readonly viewCell: MarkupCellViewModel, private readonly templateData: MarkdownCellRenderTemplate, - private readonly cellParts: CellPart[], private readonly renderedEditors: Map, @IContextKeyService private readonly contextKeyService: IContextKeyService, @INotebookCellStatusBarService readonly notebookCellStatusBarService: INotebookCellStatusBarService, @@ -70,9 +68,9 @@ export class StatefulMarkdownCell extends Disposable { this.registerListeners(); // update for init state - this.cellParts.forEach(cellPart => cellPart.renderCell(this.viewCell, this.templateData)); + this.templateData.cellParts.forEach(cellPart => cellPart.renderCell(this.viewCell, this.templateData)); this._register(toDisposable(() => { - this.cellParts.forEach(cellPart => cellPart.unrenderCell(this.viewCell, this.templateData)); + this.templateData.cellParts.forEach(cellPart => cellPart.unrenderCell(this.viewCell, this.templateData)); })); this.updateForHover(); @@ -96,7 +94,7 @@ export class StatefulMarkdownCell extends Disposable { } layoutCellParts() { - this.cellParts.forEach(part => { + this.templateData.cellParts.forEach(part => { part.updateInternalLayoutNow(this.viewCell); }); } @@ -118,7 +116,7 @@ export class StatefulMarkdownCell extends Disposable { private registerListeners() { this._register(this.viewCell.onDidChangeState(e => { - this.cellParts.forEach(cellPart => { + this.templateData.cellParts.forEach(cellPart => { cellPart.updateState(this.viewCell, e); }); })); diff --git a/src/vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon.ts b/src/vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon.ts index 87ff800b9fdfc..062193855e885 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon.ts @@ -15,12 +15,9 @@ import { Range } from 'vs/editor/common/core/range'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ICellOutputViewModel, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; -import { CellExecutionPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution'; import { CellFocusIndicator } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator'; -import { CellProgressBar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar'; +import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; import { CellEditorStatusBar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellStatusPart'; -import { BetweenCellToolbar, CellTitleToolbarPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars'; -import { RunToolbar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/codeCellRunToolbar'; import { FoldedCellHint } from 'vs/workbench/contrib/notebook/browser/view/cellParts/foldedCellHint'; import { CellViewModel, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl'; import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; @@ -104,13 +101,12 @@ export interface BaseCellRenderTemplate { container: HTMLElement; cellContainer: HTMLElement; decorationContainer: HTMLElement; - betweenCellToolbar: BetweenCellToolbar; - titleToolbar: CellTitleToolbarPart; focusIndicator: CellFocusIndicator; readonly templateDisposables: DisposableStore; readonly elementDisposables: DisposableStore; currentRenderedCell?: ICellViewModel; statusBar: CellEditorStatusBar; + cellParts: CellPart[]; toJSON: () => object; } @@ -122,12 +118,9 @@ export interface MarkdownCellRenderTemplate extends BaseCellRenderTemplate { } export interface CodeCellRenderTemplate extends BaseCellRenderTemplate { - runToolbar: RunToolbar; outputContainer: FastDomNode; cellOutputCollapsedContainer: HTMLElement; outputShowMoreContainer: FastDomNode; focusSinkElement: HTMLElement; editor: ICodeEditor; - progressBar: CellProgressBar; - cellExecution: CellExecutionPart; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts index 94b34a63d5f74..17232782b7cd8 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -213,6 +213,15 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen const statusBar = templateDisposables.add(this.instantiationService.createInstance(CellEditorStatusBar, this.notebookEditor, container, editorPart)); const foldedCellHint = templateDisposables.add(scopedInstaService.createInstance(FoldedCellHint, this.notebookEditor, DOM.append(container, $('.notebook-folded-hint')))); + const focusIndicator = new CellFocusIndicator(this.notebookEditor, titleToolbar, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom); + const cellParts = [ + betweenCellToolbar, + titleToolbar, + statusBar, + focusIndicator, + foldedCellHint + ]; + const templateData: MarkdownCellRenderTemplate = { rootContainer, cellInputCollapsedContainer, @@ -222,14 +231,13 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen cellContainer: innerContent, editorPart, editorContainer, - focusIndicator: new CellFocusIndicator(this.notebookEditor, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom), + focusIndicator, foldingIndicator, templateDisposables, elementDisposables: new DisposableStore(), - betweenCellToolbar, - titleToolbar, statusBar, foldedCellHint, + cellParts, toJSON: () => { return {}; } }; @@ -255,13 +263,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen return; } - templateData.elementDisposables.add(templateData.instantiationService.createInstance(StatefulMarkdownCell, this.notebookEditor, element, templateData, [ - templateData.betweenCellToolbar, - templateData.titleToolbar, - templateData.statusBar, - templateData.focusIndicator, - templateData.foldedCellHint - ], this.renderedEditors)); + templateData.elementDisposables.add(templateData.instantiationService.createInstance(StatefulMarkdownCell, this.notebookEditor, element, templateData, this.renderedEditors)); } disposeTemplate(templateData: MarkdownCellRenderTemplate): void { @@ -471,9 +473,18 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende rootClassDelegate, this.notebookEditor.creationOptions.menuIds.cellTitleToolbar, this.notebookEditor)); - const betweenCellToolbar = templateDisposables.add(scopedInstaService.createInstance(BetweenCellToolbar, this.notebookEditor, titleToolbarContainer, bottomCellToolbarContainer)); - const focusIndicatorPart = new CellFocusIndicator(this.notebookEditor, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom); + const focusIndicatorPart = new CellFocusIndicator(this.notebookEditor, titleToolbar, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom); + const cellParts = [ + focusIndicatorPart, + templateDisposables.add(scopedInstaService.createInstance(BetweenCellToolbar, this.notebookEditor, titleToolbarContainer, bottomCellToolbarContainer)), + statusBar, + progressBar, + titleToolbar, + runToolbar, + new CellExecutionPart(this.notebookEditor, executionOrderLabel), + ]; + const templateData: CodeCellRenderTemplate = { rootContainer, editorPart, @@ -483,19 +494,15 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende container, decorationContainer, cellContainer, - progressBar, statusBar, focusIndicator: focusIndicatorPart, - cellExecution: new CellExecutionPart(this.notebookEditor, executionOrderLabel), - titleToolbar, - betweenCellToolbar, focusSinkElement, - runToolbar, outputContainer, outputShowMoreContainer, editor, templateDisposables, elementDisposables: new DisposableStore(), + cellParts, toJSON: () => { return {}; } }; @@ -513,7 +520,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende } })); - templateData.cellExecution.setup(templateData); this.commonRenderTemplate(templateData); return templateData; @@ -596,47 +602,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende const elementDisposables = templateData.elementDisposables; - const codeCellView = elementDisposables.add(templateData.instantiationService.createInstance(CodeCell, this.notebookEditor, element, templateData, [ - templateData.focusIndicator, - templateData.betweenCellToolbar, - templateData.statusBar, - templateData.progressBar, - templateData.titleToolbar, - templateData.runToolbar, - templateData.cellExecution - ])); - + elementDisposables.add(templateData.instantiationService.createInstance(CodeCell, this.notebookEditor, element, templateData)); this.renderedEditors.set(element, templateData.editor); - - this.updateFocusIndicatorsForTitleMenuAndSubscribe(element, templateData, codeCellView); - } - - updateFocusIndicatorsForTitleMenuAndSubscribe(element: CodeCellViewModel, templateData: CodeCellRenderTemplate, codeCellView: CodeCell) { - // todo@rebornix, consolidate duplicated requests in next frame - templateData.elementDisposables.add(DOM.scheduleAtNextAnimationFrame(() => { - this.updateFocusIndicatorsForTitleMenu(templateData); - })); - - templateData.elementDisposables.add(element.onDidChangeLayout(() => { - templateData.elementDisposables.add(DOM.scheduleAtNextAnimationFrame(() => { - this.updateFocusIndicatorsForTitleMenu(templateData); - })); - })); - - templateData.elementDisposables.add(templateData.titleToolbar.onDidUpdateActions(() => { - this.updateFocusIndicatorsForTitleMenu(templateData); - })); - } - - private updateFocusIndicatorsForTitleMenu(templateData: CodeCellRenderTemplate): void { - const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration(); - if (templateData.titleToolbar.hasActions) { - templateData.focusIndicator.left.domNode.style.transform = `translateY(${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px)`; - templateData.focusIndicator.right.domNode.style.transform = `translateY(${layoutInfo.editorToolbarHeight + layoutInfo.cellTopMargin}px)`; - } else { - templateData.focusIndicator.left.domNode.style.transform = `translateY(${layoutInfo.cellTopMargin}px)`; - templateData.focusIndicator.right.domNode.style.transform = `translateY(${layoutInfo.cellTopMargin}px)`; - } } disposeTemplate(templateData: CodeCellRenderTemplate): void {