From dcf665a29fa2d9b137ee728e23254db126c5c2d9 Mon Sep 17 00:00:00 2001 From: rebornix Date: Fri, 20 Mar 2020 15:17:33 -0700 Subject: [PATCH] layout info for code cell --- .../view/renderers/backLayerWebView.ts | 6 +- .../browser/view/renderers/cellRenderer.ts | 4 +- .../browser/view/renderers/codeCell.ts | 6 +- .../browser/viewModel/baseCellViewModel.ts | 11 +-- .../browser/viewModel/codeCellViewModel.ts | 83 ++++++++++++++----- 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index 2d1e1ff0494..90f4f47c61f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -278,7 +278,7 @@ export class BackLayerWebView extends Disposable { if (cell) { let outputIndex = cell.outputs.indexOf(output); cell.updateOutputHeight(outputIndex, outputHeight); - this.notebookEditor.layoutNotebookCell(cell, cell.getCellTotalHeight()); + this.notebookEditor.layoutNotebookCell(cell, cell.layoutInfo.totalHeight); } } else if (data.type === 'scroll-ack') { // const date = new Date(); @@ -310,7 +310,7 @@ export class BackLayerWebView extends Disposable { let outputIndex = cell.outputs.indexOf(output); let outputOffsetInOutputContainer = cell.getOutputOffset(outputIndex); - let outputOffset = cellTop + cell.editorHeight + 16 /* editor padding */ + 8 + outputOffsetInOutputContainer; + let outputOffset = cellTop + cell.layoutInfo.editorHeight + 16 /* editor padding */ + 8 + outputOffsetInOutputContainer; if (outputOffset === outputCache.cacheOffset) { return false; @@ -326,7 +326,7 @@ export class BackLayerWebView extends Disposable { let outputIndex = item.cell.outputs.indexOf(item.output); let outputOffsetInOutputContainer = item.cell.getOutputOffset(outputIndex); - let outputOffset = item.cellTop + item.cell.editorHeight + 16 /* editor padding */ + 16 + outputOffsetInOutputContainer; + let outputOffset = item.cellTop + item.cell.layoutInfo.editorHeight + 16 /* editor padding */ + 16 + outputOffsetInOutputContainer; outputCache.cacheOffset = outputOffset; return { 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 5faafe5f9a6..31586ed0e16 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts @@ -387,8 +387,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende elementDisposable?.add(this.instantiationService.createInstance(CodeCell, this.notebookEditor, element, templateData)); this.renderedEditors.set(element, templateData.editor); - elementDisposable?.add(element.onDidChangeTotalHeight(() => { - templateData.focusIndicator!.style.height = `${element.getIndicatorHeight()}px`; + elementDisposable?.add(element.onDidChangeLayout(() => { + templateData.focusIndicator!.style.height = `${element.layoutInfo.indicatorHeight}px`; })); const toolbarContext = { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts index e0cd5538a25..392d36c1293 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/codeCell.ts @@ -106,7 +106,7 @@ export class CodeCell extends Disposable { this._register(templateData.editor!.onDidContentSizeChange((e) => { if (e.contentHeightChanged) { - if (this.viewCell.editorHeight !== e.contentHeight) { + if (this.viewCell.layoutInfo.editorHeight !== e.contentHeight) { let viewLayout = templateData.editor!.getLayoutInfo(); templateData.editor?.layout( @@ -256,7 +256,7 @@ export class CodeCell extends Disposable { if (result.shadowContent) { this.viewCell.selfSizeMonitoring = true; - let editorHeight = this.viewCell.editorHeight; + let editorHeight = this.viewCell.layoutInfo.editorHeight; this.notebookEditor.createInset(this.viewCell, currOutput, result.shadowContent, editorHeight + 8 + this.viewCell.getOutputOffset(index)); } else { DOM.addClass(outputItemDiv, 'foreground'); @@ -369,7 +369,7 @@ export class CodeCell extends Disposable { } relayoutCell() { - this.notebookEditor.layoutNotebookCell(this.viewCell, this.viewCell.getCellTotalHeight()); + this.notebookEditor.layoutNotebookCell(this.viewCell, this.viewCell.layoutInfo.totalHeight); } dispose() { diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts index 7c14c587d81..6ac89d54fa0 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel.ts @@ -21,8 +21,6 @@ export abstract class BaseCellViewModel extends Disposable { readonly onDidChangeCellState = this._onDidChangeCellState.event; protected readonly _onDidChangeFocusMode = new Emitter(); readonly onDidChangeFocusMode = this._onDidChangeFocusMode.event; - protected readonly _onDidChangeTotalHeight = new Emitter(); - readonly onDidChangeTotalHeight = this._onDidChangeTotalHeight.event; protected readonly _onDidChangeEditorAttachState = new Emitter(); readonly onDidChangeEditorAttachState = this._onDidChangeEditorAttachState.event; protected readonly _onDidChangeCursorSelection: Emitter = this._register(new Emitter()); @@ -58,14 +56,7 @@ export abstract class BaseCellViewModel extends Disposable { this._focusMode = newMode; this._onDidChangeFocusMode.fire(); } - private _editorHeight = 0; - set editorHeight(height: number) { - this._editorHeight = height; - this._onDidChangeTotalHeight.fire(); - } - get editorHeight(): number { - return this._editorHeight; - } + protected _textEditor?: ICodeEditor; get editorAttached(): boolean { return !!this._textEditor; diff --git a/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts b/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts index c6f12fc5937..7b3f908001d 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel.ts @@ -13,6 +13,19 @@ import { CellState, ICellViewModel, CellFindMatch } from 'vs/workbench/contrib/n import { CellKind, ICell, NotebookCellOutputsSplice } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { BaseCellViewModel } from './baseCellViewModel'; +export interface CodeCellLayoutInfo { + readonly editorHeight: number; + readonly totalHeight: number; + readonly outputTotalHeight: number; + readonly indicatorHeight: number; +} + +export interface CodeCellLayoutChangeEvent { + editorHeight?: boolean; + outputHeight?: boolean; + totalHeight?: boolean; +} + export class CodeCellViewModel extends BaseCellViewModel implements ICellViewModel { cellKind: CellKind.Code = CellKind.Code; protected readonly _onDidChangeOutputs = new Emitter(); @@ -35,6 +48,22 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod private readonly _onDidChangeContent: Emitter = this._register(new Emitter()); public readonly onDidChangeContent: Event = this._onDidChangeContent.event; + protected readonly _onDidChangeLayout = new Emitter(); + readonly onDidChangeLayout = this._onDidChangeLayout.event; + + private _editorHeight = 0; + set editorHeight(height: number) { + this._editorHeight = height; + + this.layoutChange({ editorHeight: true }); + } + + private _layoutInfo: CodeCellLayoutInfo; + + get layoutInfo() { + return this._layoutInfo; + } + constructor( readonly viewType: string, readonly notebookHandle: number, @@ -52,6 +81,36 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod this._outputCollection = new Array(this.cell.outputs.length); this._buffer = null; + + this._layoutInfo = { + editorHeight: 0, + outputTotalHeight: 0, + totalHeight: 0, + indicatorHeight: 0 + }; + } + + layoutChange(state: CodeCellLayoutChangeEvent) { + // recompute + this._ensureOutputsTop(); + const outputTotalHeight = this._outputsTop!.getTotalValue(); + const totalHeight = this.outputs.length + ? 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; + + this._layoutInfo = { + editorHeight: this._editorHeight, + outputTotalHeight, + totalHeight, + indicatorHeight + }; + + if (state.editorHeight || state.outputHeight) { + state.totalHeight = true; + } + + this._onDidChangeLayout.fire(state); } hasDynamicHeight() { @@ -117,7 +176,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod this._outputCollection[index] = height; this._ensureOutputsTop(); this._outputsTop!.changeValue(index, height); - this._onDidChangeTotalHeight.fire(); + this.layoutChange({ outputHeight: true }); } getOutputOffset(index: number): number { @@ -130,12 +189,6 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod return this._outputsTop!.getAccumulatedValue(index - 1); } - private getOutputTotalHeight(): number { - this._ensureOutputsTop(); - - return this._outputsTop!.getTotalValue(); - } - spliceOutputHeights(start: number, deleteCnt: number, heights: number[]) { this._ensureOutputsTop(); @@ -149,22 +202,10 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod this._outputsTop!.insertValues(start, values); } - this._onDidChangeTotalHeight.fire(); - } - - getCellTotalHeight(): number { - if (this.outputs.length) { - return EDITOR_TOOLBAR_HEIGHT + this.editorHeight + EDITOR_TOP_PADDING + EDITOR_BOTTOM_PADDING + 16 + this.getOutputTotalHeight(); - } else { - return EDITOR_TOOLBAR_HEIGHT + this.editorHeight + EDITOR_TOP_PADDING + EDITOR_BOTTOM_PADDING + this.getOutputTotalHeight(); - } - } - - getIndicatorHeight(): number { - return this.getCellTotalHeight() - EDITOR_TOOLBAR_HEIGHT - 16; + this.layoutChange({ outputHeight: true }); } - protected _ensureOutputsTop(): void { + private _ensureOutputsTop(): void { if (!this._outputsTop) { const values = new Uint32Array(this._outputCollection.length); for (let i = 0; i < this._outputCollection.length; i++) { -- GitLab