Path: blob/main/src/vs/workbench/contrib/notebook/browser/viewParts/notebookTopCellToolbar.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 * as DOM from '../../../../../base/browser/dom.js';6import { Disposable, DisposableStore, MutableDisposable } from '../../../../../base/common/lifecycle.js';7import { HiddenItemStrategy, MenuWorkbenchToolBar } from '../../../../../platform/actions/browser/toolbar.js';8import { IMenuService, MenuItemAction } from '../../../../../platform/actions/common/actions.js';9import { IContextMenuService } from '../../../../../platform/contextview/browser/contextView.js';10import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';11import { INotebookActionContext } from '../controller/coreActions.js';12import { INotebookEditorDelegate } from '../notebookBrowser.js';13import { NotebookOptions } from '../notebookOptions.js';14import { CodiconActionViewItem } from '../view/cellParts/cellActionView.js';1516export class ListTopCellToolbar extends Disposable {17private readonly topCellToolbarContainer: HTMLElement;18private topCellToolbar: HTMLElement;19private readonly viewZone: MutableDisposable<DisposableStore> = this._register(new MutableDisposable());20private readonly _modelDisposables = this._register(new DisposableStore());21constructor(22protected readonly notebookEditor: INotebookEditorDelegate,23private readonly notebookOptions: NotebookOptions,24@IInstantiationService protected readonly instantiationService: IInstantiationService,25@IContextMenuService protected readonly contextMenuService: IContextMenuService,26@IMenuService protected readonly menuService: IMenuService27) {28super();2930this.topCellToolbarContainer = DOM.$('div');31this.topCellToolbar = DOM.$('.cell-list-top-cell-toolbar-container');32this.topCellToolbarContainer.appendChild(this.topCellToolbar);3334this._register(this.notebookEditor.onDidAttachViewModel(() => {35this.updateTopToolbar();36}));3738this._register(this.notebookOptions.onDidChangeOptions(e => {39if (e.insertToolbarAlignment || e.insertToolbarPosition || e.cellToolbarLocation) {40this.updateTopToolbar();41}42}));43}4445private updateTopToolbar() {46const layoutInfo = this.notebookOptions.getLayoutConfiguration();47this.viewZone.value = new DisposableStore();4849if (layoutInfo.insertToolbarPosition === 'hidden' || layoutInfo.insertToolbarPosition === 'notebookToolbar') {50const height = this.notebookOptions.computeTopInsertToolbarHeight(this.notebookEditor.textModel?.viewType);5152if (height !== 0) {53// reserve whitespace to avoid overlap with cell toolbar54this.notebookEditor.changeViewZones(accessor => {55const id = accessor.addZone({56afterModelPosition: 0,57heightInPx: height,58domNode: DOM.$('div')59});60accessor.layoutZone(id);61this.viewZone.value?.add({62dispose: () => {63if (!this.notebookEditor.isDisposed) {64this.notebookEditor.changeViewZones(accessor => {65accessor.removeZone(id);66});67}68}69});70});71}72return;73}747576this.notebookEditor.changeViewZones(accessor => {77const height = this.notebookOptions.computeTopInsertToolbarHeight(this.notebookEditor.textModel?.viewType);78const id = accessor.addZone({79afterModelPosition: 0,80heightInPx: height,81domNode: this.topCellToolbarContainer82});83accessor.layoutZone(id);8485this.viewZone.value?.add({86dispose: () => {87if (!this.notebookEditor.isDisposed) {88this.notebookEditor.changeViewZones(accessor => {89accessor.removeZone(id);90});91}92}93});9495DOM.clearNode(this.topCellToolbar);9697const toolbar = this.instantiationService.createInstance(MenuWorkbenchToolBar, this.topCellToolbar, this.notebookEditor.creationOptions.menuIds.cellTopInsertToolbar, {98actionViewItemProvider: (action, options) => {99if (action instanceof MenuItemAction) {100const item = this.instantiationService.createInstance(CodiconActionViewItem, action, { hoverDelegate: options.hoverDelegate });101return item;102}103104return undefined;105},106menuOptions: {107shouldForwardArgs: true108},109toolbarOptions: {110primaryGroup: (g: string) => /^inline/.test(g),111},112hiddenItemStrategy: HiddenItemStrategy.Ignore,113});114115if (this.notebookEditor.hasModel()) {116toolbar.context = {117notebookEditor: this.notebookEditor118} satisfies INotebookActionContext;119}120121this.viewZone.value?.add(toolbar);122123// update toolbar container css based on cell list length124this.viewZone.value?.add(this.notebookEditor.onDidChangeModel(() => {125this._modelDisposables.clear();126127if (this.notebookEditor.hasModel()) {128this._modelDisposables.add(this.notebookEditor.onDidChangeViewCells(() => {129this.updateClass();130}));131132this.updateClass();133}134}));135136this.updateClass();137});138}139140private updateClass() {141if (this.notebookEditor.hasModel() && this.notebookEditor.getLength() === 0) {142this.topCellToolbar.classList.add('emptyNotebook');143} else {144this.topCellToolbar.classList.remove('emptyNotebook');145}146}147}148149150