From ed9a644542bd05f6e8aaafa0f2769cc90cd1d765 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 18:19:05 -0800 Subject: [PATCH 1/7] move focus sink update to CodeCell --- .../notebook/browser/view/cellParts/codeCell.ts | 11 +++++++++++ .../notebook/browser/view/renderers/cellRenderer.ts | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) 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 6cf3da89f65ab..bc583d1c0bc84 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -72,6 +72,9 @@ export class CodeCell extends Disposable { })); this.updateForCollapseState(); + + this.updateForOutputs(); + this._register(viewCell.onDidChangeOutputs(_e => this.updateForOutputs())); } private calculateInitEditorHeight() { @@ -124,6 +127,14 @@ export class CodeCell extends Disposable { }); } + private updateForOutputs(): void { + if (this.viewCell.outputsViewModels.length) { + DOM.show(this.templateData.focusSinkElement); + } else { + DOM.hide(this.templateData.focusSinkElement); + } + } + private registerEditorOptionsListener() { const updateEditorOptions = () => { const editor = this.templateData.editor; 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 3cc7ed86e4b03..35df8e1650878 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -591,14 +591,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende return combinedDisposable(dragHandleListener, collapsedPartListener, clickHandler); } - private updateForOutputs(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void { - if (element.outputsViewModels.length) { - DOM.show(templateData.focusSinkElement); - } else { - DOM.hide(templateData.focusSinkElement); - } - } - private updateForInternalMetadata(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void { if (!this.notebookEditor.hasModel()) { return; @@ -717,9 +709,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende templateData.progressBar.updateForCellState(e, element); })); - this.updateForOutputs(element, templateData); - elementDisposables.add(element.onDidChangeOutputs(_e => this.updateForOutputs(element, templateData))); - this.updateForKernel(element, templateData); const toolbarContext = { From ee689f7822282b7702372669f21e107f8f20462c Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 18:28:11 -0800 Subject: [PATCH 2/7] :lipstick: --- .../contrib/notebook/browser/view/renderers/cellRenderer.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 35df8e1650878..2008d922f3de0 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -674,10 +674,10 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende ])); this.renderedEditors.set(element, templateData.editor); - const cellEditorOptions = new CellEditorOptions(this.notebookEditor, this.notebookEditor.notebookOptions, this.configurationService, element.language); - elementDisposables.add(cellEditorOptions); + const cellEditorOptions = elementDisposables.add(new CellEditorOptions(this.notebookEditor, this.notebookEditor.notebookOptions, this.configurationService, element.language)); elementDisposables.add(cellEditorOptions.onDidChange(() => templateData.editor.updateOptions(cellEditorOptions.getUpdatedValue(element.internalMetadata)))); templateData.editor.updateOptions(cellEditorOptions.getUpdatedValue(element.internalMetadata)); + cellEditorOptions.setLineNumbers(element.lineNumbers); this.updateForLayout(element, templateData); elementDisposables.add(element.onDidChangeLayout(() => { @@ -687,7 +687,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende this.updateForInternalMetadata(element, templateData); this.updateForHover(element, templateData); this.updateForFocus(element, templateData); - cellEditorOptions.setLineNumbers(element.lineNumbers); elementDisposables.add(element.onDidChangeState((e) => { if (e.metadataChanged || e.internalMetadataChanged) { this.updateForInternalMetadata(element, templateData); From de68e43a2565b933e60f9dd105192ea81a1a945a Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 18:33:53 -0800 Subject: [PATCH 3/7] move hover and output focus into CodeCell --- .../browser/view/cellParts/codeCell.ts | 29 +++++++++++++++++++ .../browser/view/renderers/cellRenderer.ts | 18 ------------ 2 files changed, 29 insertions(+), 18 deletions(-) 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 bc583d1c0bc84..37d2e45d87182 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -56,6 +56,8 @@ export class CodeCell extends Disposable { this.registerEditorLayoutListeners(); this.registerDecorations(); this.registerMouseListener(); + this.registerHover(); + this.registerOutputFocus(); // Render Outputs this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData, { limit: 500 }); @@ -77,6 +79,33 @@ export class CodeCell extends Disposable { this._register(viewCell.onDidChangeOutputs(_e => this.updateForOutputs())); } + private registerHover() { + const updateForHover = () => { + this.templateData.container.classList.toggle('cell-output-hover', this.viewCell.outputIsHovered); + }; + + updateForHover(); + this._register(this.viewCell.onDidChangeState(e => { + if (e.outputIsHoveredChanged) { + updateForHover(); + } + })); + } + + private registerOutputFocus() { + const updateFocus = () => { + this.templateData.container.classList.toggle('cell-output-focus', this.viewCell.outputIsFocused); + }; + + updateFocus(); + + this._register(this.viewCell.onDidChangeState(e => { + if (e.outputIsFocusedChanged) { + updateFocus(); + } + })); + } + private calculateInitEditorHeight() { const lineNum = this.viewCell.lineCount; const lineHeight = this.viewCell.layoutInfo.fontInfo?.lineHeight || 17; 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 2008d922f3de0..ecac77afe89ba 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -616,14 +616,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende } } - private updateForHover(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void { - templateData.container.classList.toggle('cell-output-hover', element.outputIsHovered); - } - - private updateForFocus(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void { - templateData.container.classList.toggle('cell-output-focus', element.outputIsFocused); - } - private updateForLayout(element: CodeCellViewModel, templateData: CodeCellRenderTemplate): void { templateData.elementDisposables.add(DOM.scheduleAtNextAnimationFrame(() => { const bottomToolbarDimensions = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType); @@ -685,22 +677,12 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende })); this.updateForInternalMetadata(element, templateData); - this.updateForHover(element, templateData); - this.updateForFocus(element, templateData); elementDisposables.add(element.onDidChangeState((e) => { if (e.metadataChanged || e.internalMetadataChanged) { this.updateForInternalMetadata(element, templateData); this.updateForLayout(element, templateData); } - if (e.outputIsHoveredChanged) { - this.updateForHover(element, templateData); - } - - if (e.outputIsFocusedChanged) { - this.updateForFocus(element, templateData); - } - if (e.cellLineNumberChanged) { cellEditorOptions.setLineNumbers(element.lineNumbers); } From 4f9ee29c30d1840fa0ac1c23dce4459440b7cccb Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 18:36:49 -0800 Subject: [PATCH 4/7] cell progress bar update. --- .../browser/view/cellParts/cellProgressBar.ts | 23 ++++++++----------- .../browser/view/renderers/cellRenderer.ts | 4 +++- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar.ts index 00eac1b29e256..46394309daa06 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar.ts @@ -5,7 +5,6 @@ import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar'; import { Disposable } from 'vs/base/common/lifecycle'; -import { CellViewModelStateChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { NotebookCellExecutionState, NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -34,18 +33,16 @@ export class CellProgressBar extends Disposable { } } - updateForCellState(e: CellViewModelStateChangeEvent, element: CodeCellViewModel): void { - if (e.inputCollapsedChanged) { - if (element.isInputCollapsed) { - this._progressBar.hide(); - if (element.internalMetadata.runState === NotebookCellExecutionState.Executing) { - showProgressBar(this._collapsedProgressBar); - } - } else { - this._collapsedProgressBar.hide(); - if (element.internalMetadata.runState === NotebookCellExecutionState.Executing) { - showProgressBar(this._progressBar); - } + updateForCellState(element: CodeCellViewModel): void { + if (element.isInputCollapsed) { + this._progressBar.hide(); + if (element.internalMetadata.runState === NotebookCellExecutionState.Executing) { + showProgressBar(this._collapsedProgressBar); + } + } else { + this._collapsedProgressBar.hide(); + if (element.internalMetadata.runState === NotebookCellExecutionState.Executing) { + showProgressBar(this._progressBar); } } } 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 ecac77afe89ba..205861be77172 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -687,7 +687,9 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende cellEditorOptions.setLineNumbers(element.lineNumbers); } - templateData.progressBar.updateForCellState(e, element); + if (e.inputCollapsedChanged) { + templateData.progressBar.updateForCellState(element); + } })); this.updateForKernel(element, templateData); From cc9e629a1cac90b4e6e75361ab52884c4f7ea3c9 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 18:38:23 -0800 Subject: [PATCH 5/7] move progress bar listener to codecell --- .../contrib/notebook/browser/view/cellParts/codeCell.ts | 9 +++++++++ .../notebook/browser/view/renderers/cellRenderer.ts | 4 ---- 2 files changed, 9 insertions(+), 4 deletions(-) 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 37d2e45d87182..d60def3c3bca1 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -58,6 +58,7 @@ export class CodeCell extends Disposable { this.registerMouseListener(); this.registerHover(); this.registerOutputFocus(); + this.registerProgressBar(); // Render Outputs this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData, { limit: 500 }); @@ -79,6 +80,14 @@ export class CodeCell extends Disposable { this._register(viewCell.onDidChangeOutputs(_e => this.updateForOutputs())); } + private registerProgressBar() { + this._register(this.viewCell.onDidChangeState(e => { + if (e.inputCollapsedChanged) { + this.templateData.progressBar.updateForCellState(this.viewCell); + } + })); + } + private registerHover() { const updateForHover = () => { this.templateData.container.classList.toggle('cell-output-hover', this.viewCell.outputIsHovered); 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 205861be77172..d747089f71cec 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -686,10 +686,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende if (e.cellLineNumberChanged) { cellEditorOptions.setLineNumbers(element.lineNumbers); } - - if (e.inputCollapsedChanged) { - templateData.progressBar.updateForCellState(element); - } })); this.updateForKernel(element, templateData); From 3503de77655d7a95b36a4956cf2d919a4496718b Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 18:50:54 -0800 Subject: [PATCH 6/7] cell part respond to view cell state change. --- .../view/cellParts/cellEditorOptions.ts | 21 +++++++++++++++---- .../view/cellParts/cellFocusIndicator.ts | 6 +++++- .../browser/view/cellParts/cellOutput.ts | 7 ++++++- .../browser/view/cellParts/cellPart.ts | 4 +++- .../browser/view/cellParts/cellToolbars.ts | 7 ++++++- .../browser/view/cellParts/cellWidgets.ts | 7 ++++++- .../browser/view/cellParts/codeCell.ts | 7 +++++++ .../browser/view/renderers/cellRenderer.ts | 10 ++++----- 8 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions.ts index c819584f79726..c89954efb520d 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { deepClone } from 'vs/base/common/objects'; import { IEditorOptions, LineNumbersType } from 'vs/editor/common/config/editorOptions'; import { localize } from 'vs/nls'; @@ -16,13 +16,13 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { Registry } from 'vs/platform/registry/common/platform'; import { ActiveEditorContext } from 'vs/workbench/common/editor'; import { INotebookCellToolbarActionContext, INotebookCommandContext, NotebookMultiCellAction, NOTEBOOK_ACTIONS_CATEGORY } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; -import { ICellViewModel, INotebookEditorDelegate, NOTEBOOK_CELL_LINE_NUMBERS, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellViewModelStateChangeEvent, ICellViewModel, INotebookEditorDelegate, NOTEBOOK_CELL_LINE_NUMBERS, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEditor'; +import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; import { NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOptions'; -export class CellEditorOptions extends Disposable { - +export class CellEditorOptions extends CellPart { private static fixedEditorOptions: IEditorOptions = { scrollBeyondLastLine: false, scrollbar: { @@ -86,6 +86,19 @@ export class CellEditorOptions extends Disposable { this._value = this._computeEditorOptions(); } + prepareRender(): void { + // nothing to read + } + updateLayoutNow(element: ICellViewModel): void { + // nothing to update + } + + updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent) { + if (e.cellLineNumberChanged) { + this.setLineNumbers(element.lineNumbers); + } + } + private _recomputeOptions(): void { this._value = this._computeEditorOptions(); this._onDidChange.fire(); 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 11b345d5e9c6d..2b47bf53039a7 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator.ts @@ -5,7 +5,7 @@ // import * as DOM from 'vs/base/browser/dom'; import { FastDomNode } from 'vs/base/browser/fastDomNode'; -import { ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellViewModelStateChangeEvent, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -42,4 +42,8 @@ export class CellFocusIndicator extends CellPart { this.bottom.domNode.style.transform = `translateY(${cell.layoutInfo.totalHeight - bottomToolbarDimensions.bottomToolbarGap - layoutInfo.cellBottomMargin}px)`; } } + + updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void { + // nothing to update + } } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts index e3cb7ece13283..ef404e39e93f0 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts @@ -24,7 +24,7 @@ import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ViewContainerLocation } from 'vs/workbench/common/views'; import { IExtensionsViewPaneContainer, VIEWLET_ID as EXTENSION_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions'; import { INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; -import { ICellOutputViewModel, ICellViewModel, IInsetRenderOutput, INotebookEditorDelegate, IRenderOutput, JUPYTER_EXTENSION_ID, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellViewModelStateChangeEvent, ICellOutputViewModel, ICellViewModel, IInsetRenderOutput, INotebookEditorDelegate, IRenderOutput, JUPYTER_EXTENSION_ID, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { mimetypeIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons'; import { CodeCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellWidgets'; @@ -602,6 +602,11 @@ export class CellOutputContainer extends CellPart { }); } + + updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void { + // nothing to update + } + render(editorHeight: number) { if (this.viewCell.outputsViewModels.length > 0) { if (this.viewCell.layoutInfo.totalHeight !== 0 && this.viewCell.layoutInfo.editorHeight > editorHeight) { diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellPart.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellPart.ts index 30cb897a804fd..61319b8bbb193 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellPart.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellPart.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from 'vs/base/common/lifecycle'; -import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellViewModelStateChangeEvent, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; export abstract class CellPart extends Disposable { constructor() { @@ -20,4 +20,6 @@ export abstract class CellPart extends Disposable { * Update DOM based on layout info change of cell */ abstract updateLayoutNow(element: ICellViewModel): void; + + abstract updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts index 7dedde54fae86..3c26ff165a8be 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars.ts @@ -18,7 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; import { DeleteCellAction } from 'vs/workbench/contrib/notebook/browser/controller/editActions'; -import { ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellViewModelStateChangeEvent, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellActionView'; import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; @@ -77,6 +77,11 @@ export class BetweenCellToolbar extends CellPart { const bottomToolbarOffset = element.layoutInfo.bottomToolbarOffset; this._bottomCellToolbarContainer.style.transform = `translateY(${bottomToolbarOffset}px)`; } + + + updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void { + // nothing to update + } } diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellWidgets.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellWidgets.ts index 286dd48721e6c..26b22de0038ce 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellWidgets.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellWidgets.ts @@ -20,7 +20,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService, ThemeColor } from 'vs/platform/theme/common/themeService'; import { INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; -import { ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { CellViewModelStateChangeEvent, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart'; import { CellStatusbarAlignment, INotebookCellStatusBarItem } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -112,6 +112,11 @@ export class CellEditorStatusBar extends CellPart { this.rightItems.forEach(item => item.maxWidth = maxItemWidth); } + + updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void { + // nothing to update + } + private getMaxItemWidth() { return this.width / 2; } 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 d60def3c3bca1..237d1678fa063 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -50,6 +50,13 @@ export class CodeCell extends Disposable { const editorHeight = this.calculateInitEditorHeight(); this.initializeEditor(editorHeight); + + this._register(this.viewCell.onDidChangeState(e => { + this.cellParts.forEach(cellPart => { + cellPart.updateState(this.viewCell, e); + }); + })); + this.registerEditorOptionsListener(); this.registerViewCellStateChange(); this.registerFocusModeTracker(); 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 d747089f71cec..aa770285fd814 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -659,14 +659,16 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende templateData.outputContainer.domNode.appendChild(templateData.cellOutputCollapsedContainer); const elementDisposables = templateData.elementDisposables; + const cellEditorOptions = elementDisposables.add(new CellEditorOptions(this.notebookEditor, this.notebookEditor.notebookOptions, this.configurationService, element.language)); + elementDisposables.add(templateData.instantiationService.createInstance(CodeCell, this.notebookEditor, element, templateData, [ templateData.focusIndicator, templateData.betweenCellToolbar, - templateData.statusBar + templateData.statusBar, + cellEditorOptions ])); this.renderedEditors.set(element, templateData.editor); - const cellEditorOptions = elementDisposables.add(new CellEditorOptions(this.notebookEditor, this.notebookEditor.notebookOptions, this.configurationService, element.language)); elementDisposables.add(cellEditorOptions.onDidChange(() => templateData.editor.updateOptions(cellEditorOptions.getUpdatedValue(element.internalMetadata)))); templateData.editor.updateOptions(cellEditorOptions.getUpdatedValue(element.internalMetadata)); cellEditorOptions.setLineNumbers(element.lineNumbers); @@ -682,10 +684,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende this.updateForInternalMetadata(element, templateData); this.updateForLayout(element, templateData); } - - if (e.cellLineNumberChanged) { - cellEditorOptions.setLineNumbers(element.lineNumbers); - } })); this.updateForKernel(element, templateData); From 607fdb78bb1c589c1b9b1760d50f2540cca176f8 Mon Sep 17 00:00:00 2001 From: rebornix Date: Thu, 18 Nov 2021 19:04:52 -0800 Subject: [PATCH 7/7] single state change event. --- .../browser/view/cellParts/codeCell.ts | 191 ++++++++---------- 1 file changed, 82 insertions(+), 109 deletions(-) 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 237d1678fa063..197c98790f760 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/codeCell.ts @@ -51,21 +51,50 @@ export class CodeCell extends Disposable { const editorHeight = this.calculateInitEditorHeight(); this.initializeEditor(editorHeight); + this.registerViewCellLayoutChange(); + this.registerCellEditorEventListeners(); + this.registerDecorations(); + this.registerMouseListener(); + this._register(this.viewCell.onDidChangeState(e => { this.cellParts.forEach(cellPart => { cellPart.updateState(this.viewCell, e); }); + + if (e.outputIsHoveredChanged) { + this.updateForOutputHover(); + } + + if (e.inputCollapsedChanged) { + this.templateData.progressBar.updateForCellState(this.viewCell); + } + + if (e.outputIsFocusedChanged) { + this.updateForOutputFocus(); + } + + if (e.metadataChanged || e.internalMetadataChanged) { + this.updateEditorOptions(); + } + + if (e.inputCollapsedChanged || e.outputCollapsedChanged) { + this.viewCell.pauseLayout(); + const updated = this.updateForCollapseState(); + this.viewCell.resumeLayout(); + if (updated) { + this.relayoutCell(); + } + } + + if (e.focusModeChanged) { + this.updateEditorForFocusModeChange(); + } })); - this.registerEditorOptionsListener(); - this.registerViewCellStateChange(); - this.registerFocusModeTracker(); - this.registerEditorLayoutListeners(); - this.registerDecorations(); - this.registerMouseListener(); - this.registerHover(); - this.registerOutputFocus(); - this.registerProgressBar(); + this.updateEditorOptions(); + this.updateEditorForFocusModeChange(); + this.updateForOutputHover(); + this.updateForOutputFocus(); // Render Outputs this._outputContainerRenderer = this.instantiationService.createInstance(CellOutputContainer, notebookEditor, viewCell, templateData, { limit: 500 }); @@ -87,39 +116,12 @@ export class CodeCell extends Disposable { this._register(viewCell.onDidChangeOutputs(_e => this.updateForOutputs())); } - private registerProgressBar() { - this._register(this.viewCell.onDidChangeState(e => { - if (e.inputCollapsedChanged) { - this.templateData.progressBar.updateForCellState(this.viewCell); - } - })); + private updateForOutputHover() { + this.templateData.container.classList.toggle('cell-output-hover', this.viewCell.outputIsHovered); } - private registerHover() { - const updateForHover = () => { - this.templateData.container.classList.toggle('cell-output-hover', this.viewCell.outputIsHovered); - }; - - updateForHover(); - this._register(this.viewCell.onDidChangeState(e => { - if (e.outputIsHoveredChanged) { - updateForHover(); - } - })); - } - - private registerOutputFocus() { - const updateFocus = () => { - this.templateData.container.classList.toggle('cell-output-focus', this.viewCell.outputIsFocused); - }; - - updateFocus(); - - this._register(this.viewCell.onDidChangeState(e => { - if (e.outputIsFocusedChanged) { - updateFocus(); - } - })); + private updateForOutputFocus() { + this.templateData.container.classList.toggle('cell-output-focus', this.viewCell.outputIsFocused); } private calculateInitEditorHeight() { @@ -180,41 +182,21 @@ export class CodeCell extends Disposable { } } - private registerEditorOptionsListener() { - const updateEditorOptions = () => { - const editor = this.templateData.editor; - if (!editor) { - return; - } - - const isReadonly = this.notebookEditor.isReadOnly; - const padding = this.notebookEditor.notebookOptions.computeEditorPadding(this.viewCell.internalMetadata); - const options = editor.getOptions(); - if (options.get(EditorOption.readOnly) !== isReadonly || options.get(EditorOption.padding) !== padding) { - editor.updateOptions({ readOnly: this.notebookEditor.isReadOnly, padding: this.notebookEditor.notebookOptions.computeEditorPadding(this.viewCell.internalMetadata) }); - } - }; + private updateEditorOptions() { + const editor = this.templateData.editor; + if (!editor) { + return; + } - updateEditorOptions(); - this._register(this.viewCell.onDidChangeState((e) => { - if (e.metadataChanged || e.internalMetadataChanged) { - updateEditorOptions(); - } - })); + const isReadonly = this.notebookEditor.isReadOnly; + const padding = this.notebookEditor.notebookOptions.computeEditorPadding(this.viewCell.internalMetadata); + const options = editor.getOptions(); + if (options.get(EditorOption.readOnly) !== isReadonly || options.get(EditorOption.padding) !== padding) { + editor.updateOptions({ readOnly: this.notebookEditor.isReadOnly, padding: this.notebookEditor.notebookOptions.computeEditorPadding(this.viewCell.internalMetadata) }); + } } - private registerViewCellStateChange() { - this._register(this.viewCell.onDidChangeState((e) => { - if (e.inputCollapsedChanged || e.outputCollapsedChanged) { - this.viewCell.pauseLayout(); - const updated = this.updateForCollapseState(); - this.viewCell.resumeLayout(); - if (updated) { - this.relayoutCell(); - } - } - })); - + private registerViewCellLayoutChange() { this._register(this.viewCell.onDidChangeLayout((e) => { if (e.outerWidth !== undefined) { const layoutInfo = this.templateData.editor.getLayoutInfo(); @@ -229,7 +211,7 @@ export class CodeCell extends Disposable { })); } - private registerEditorLayoutListeners() { + private registerCellEditorEventListeners() { this._register(this.templateData.editor.onDidContentSizeChange((e) => { if (e.contentHeightChanged) { if (this.viewCell.layoutInfo.editorHeight !== e.contentHeight) { @@ -250,6 +232,28 @@ export class CodeCell extends Disposable { this.notebookEditor.revealLineInViewAsync(this.viewCell, primarySelection.positionLineNumber); } })); + + // Focus Mode + const updateFocusModeForEditorEvent = () => { + this.viewCell.focusMode = + (this.templateData.editor.hasWidgetFocus() || (document.activeElement && this.templateData.statusBar.statusBarContainer.contains(document.activeElement))) + ? CellFocusMode.Editor + : CellFocusMode.Container; + }; + + this._register(this.templateData.editor.onDidFocusEditorWidget(() => { + updateFocusModeForEditorEvent(); + })); + this._register(this.templateData.editor.onDidBlurEditorWidget(() => { + // this is for a special case: + // users click the status bar empty space, which we will then focus the editor + // so we don't want to update the focus state too eagerly, it will be updated with onDidFocusEditorWidget + if ( + this.notebookEditor.hasEditorFocus() && + !(document.activeElement && this.templateData.statusBar.statusBarContainer.contains(document.activeElement))) { + updateFocusModeForEditorEvent(); + } + })); } private registerDecorations() { @@ -308,43 +312,12 @@ export class CodeCell extends Disposable { })); } - private registerFocusModeTracker() { - const updateEditorForFocusModeChange = () => { - if (this.viewCell.focusMode === CellFocusMode.Editor && this.notebookEditor.getActiveCell() === this.viewCell) { - this.templateData.editor?.focus(); - } - - this.templateData.container.classList.toggle('cell-editor-focus', this.viewCell.focusMode === CellFocusMode.Editor); - }; - this._register(this.viewCell.onDidChangeState((e) => { - if (e.focusModeChanged) { - updateEditorForFocusModeChange(); - } - })); - - updateEditorForFocusModeChange(); - - // Focus Mode - const updateFocusModeForEditorEvent = () => { - this.viewCell.focusMode = - (this.templateData.editor.hasWidgetFocus() || (document.activeElement && this.templateData.statusBar.statusBarContainer.contains(document.activeElement))) - ? CellFocusMode.Editor - : CellFocusMode.Container; - }; + private updateEditorForFocusModeChange() { + if (this.viewCell.focusMode === CellFocusMode.Editor && this.notebookEditor.getActiveCell() === this.viewCell) { + this.templateData.editor?.focus(); + } - this._register(this.templateData.editor.onDidFocusEditorWidget(() => { - updateFocusModeForEditorEvent(); - })); - this._register(this.templateData.editor.onDidBlurEditorWidget(() => { - // this is for a special case: - // users click the status bar empty space, which we will then focus the editor - // so we don't want to update the focus state too eagerly, it will be updated with onDidFocusEditorWidget - if ( - this.notebookEditor.hasEditorFocus() && - !(document.activeElement && this.templateData.statusBar.statusBarContainer.contains(document.activeElement))) { - updateFocusModeForEditorEvent(); - } - })); + this.templateData.container.classList.toggle('cell-editor-focus', this.viewCell.focusMode === CellFocusMode.Editor); } private updateForCollapseState(): boolean {