Path: blob/main/src/vs/workbench/contrib/notebook/browser/diff/diffNestedCellViewModel.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Emitter } from '../../../../../base/common/event.js';6import { Disposable } from '../../../../../base/common/lifecycle.js';7import { generateUuid } from '../../../../../base/common/uuid.js';8import { PrefixSumComputer } from '../../../../../editor/common/model/prefixSumComputer.js';9import { IDiffNestedCellViewModel } from './notebookDiffEditorBrowser.js';10import { ICellOutputViewModel, IGenericCellViewModel } from '../notebookBrowser.js';11import { CellViewModelStateChangeEvent } from '../notebookViewEvents.js';12import { CellOutputViewModel } from '../viewModel/cellOutputViewModel.js';13import { NotebookCellTextModel } from '../../common/model/notebookCellTextModel.js';14import { INotebookService } from '../../common/notebookService.js';1516export class DiffNestedCellViewModel extends Disposable implements IDiffNestedCellViewModel, IGenericCellViewModel {17private _id: string;18get id() {19return this._id;20}2122get outputs() {23return this.textModel.outputs;24}2526get language() {27return this.textModel.language;28}2930get metadata() {31return this.textModel.metadata;32}3334get uri() {35return this.textModel.uri;36}3738get handle() {39return this.textModel.handle;40}4142protected readonly _onDidChangeState: Emitter<CellViewModelStateChangeEvent> = this._register(new Emitter<CellViewModelStateChangeEvent>());4344private _hoveringOutput: boolean = false;45public get outputIsHovered(): boolean {46return this._hoveringOutput;47}4849public set outputIsHovered(v: boolean) {50this._hoveringOutput = v;51this._onDidChangeState.fire({ outputIsHoveredChanged: true });52}5354private _focusOnOutput: boolean = false;55public get outputIsFocused(): boolean {56return this._focusOnOutput;57}5859public set outputIsFocused(v: boolean) {60this._focusOnOutput = v;61this._onDidChangeState.fire({ outputIsFocusedChanged: true });62}6364private _focusInputInOutput: boolean = false;65public get inputInOutputIsFocused(): boolean {66return this._focusInputInOutput;67}6869public set inputInOutputIsFocused(v: boolean) {70this._focusInputInOutput = v;71}7273private _outputViewModels: ICellOutputViewModel[];7475get outputsViewModels() {76return this._outputViewModels;77}7879protected _outputCollection: number[] = [];80protected _outputsTop: PrefixSumComputer | null = null;8182protected readonly _onDidChangeOutputLayout = this._register(new Emitter<void>());83readonly onDidChangeOutputLayout = this._onDidChangeOutputLayout.event;8485constructor(86readonly textModel: NotebookCellTextModel,87@INotebookService private _notebookService: INotebookService88) {89super();90this._id = generateUuid();9192this._outputViewModels = this.textModel.outputs.map(output => new CellOutputViewModel(this, output, this._notebookService));93this._register(this.textModel.onDidChangeOutputs((splice) => {94this._outputCollection.splice(splice.start, splice.deleteCount, ...splice.newOutputs.map(() => 0));95const removed = this._outputViewModels.splice(splice.start, splice.deleteCount, ...splice.newOutputs.map(output => new CellOutputViewModel(this, output, this._notebookService)));96removed.forEach(vm => vm.dispose());9798this._outputsTop = null;99this._onDidChangeOutputLayout.fire();100}));101this._outputCollection = new Array(this.textModel.outputs.length);102}103104private _ensureOutputsTop() {105if (!this._outputsTop) {106const values = new Uint32Array(this._outputCollection.length);107for (let i = 0; i < this._outputCollection.length; i++) {108values[i] = this._outputCollection[i];109}110111this._outputsTop = new PrefixSumComputer(values);112}113}114115getOutputOffset(index: number): number {116this._ensureOutputsTop();117118if (index >= this._outputCollection.length) {119throw new Error('Output index out of range!');120}121122return this._outputsTop!.getPrefixSum(index - 1);123}124125updateOutputHeight(index: number, height: number): void {126if (index >= this._outputCollection.length) {127throw new Error('Output index out of range!');128}129130this._ensureOutputsTop();131this._outputCollection[index] = height;132if (this._outputsTop!.setValue(index, height)) {133this._onDidChangeOutputLayout.fire();134}135}136137getOutputTotalHeight() {138this._ensureOutputsTop();139140return this._outputsTop?.getTotalSum() ?? 0;141}142143public override dispose(): void {144super.dispose();145146this._outputViewModels.forEach(output => {147output.dispose();148});149}150}151152153