diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index d616a3ba793..1fdf3135d25 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -9,7 +9,7 @@ import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IEx import { Disposable, IDisposable, combinedDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/notebook/common/notebookService'; -import { NOTEBOOK_DISPLAY_ORDER, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType, CellKind, INotebookKernelInfo, INotebookKernelInfoDto, IEditor, INotebookDocumentFilter } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { NOTEBOOK_DISPLAY_ORDER, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType, CellKind, INotebookKernelInfo, INotebookKernelInfoDto, IEditor, INotebookDocumentFilter, DisplayOrderKey } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -311,7 +311,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo })); const updateOrder = () => { - let userOrder = this.configurationService.getValue('notebook.displayOrder'); + let userOrder = this.configurationService.getValue(DisplayOrderKey); this._proxy.$acceptDisplayOrder({ defaultOrder: this.accessibilityService.isScreenReaderOptimized() ? ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER : NOTEBOOK_DISPLAY_ORDER, userOrder: userOrder @@ -321,7 +321,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo updateOrder(); this._register(this.configurationService.onDidChangeConfiguration(e => { - if (e.affectedKeys.indexOf('notebook.displayOrder') >= 0) { + if (e.affectedKeys.indexOf(DisplayOrderKey) >= 0) { updateOrder(); } })); diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebook.css b/src/vs/workbench/contrib/notebook/browser/media/notebook.css index 4e23c35c249..7c9aa235e5f 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebook.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebook.css @@ -298,12 +298,23 @@ display: inline-flex; position: absolute; height: 26px; - right: 44px; top: -12px; /* this lines up the bottom toolbar border with the current line when on line 01 */ z-index: 30; } +.monaco-workbench .notebookOverlay.cell-title-toolbar-right > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar { + right: 44px; +} + +.monaco-workbench .notebookOverlay.cell-title-toolbar-left > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar { + left: 76px; +} + +.monaco-workbench .notebookOverlay.cell-title-toolbar-hidden > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar { + display: none; +} + .monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar .action-item { width: 24px; height: 24px; diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index e5d962b3ff4..2420ce81f4f 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -30,7 +30,7 @@ import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEd import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { NotebookService } from 'vs/workbench/contrib/notebook/browser/notebookServiceImpl'; -import { CellKind, CellUri, getCellUndoRedoComparisonKey, NotebookDocumentBackupData, NotebookEditorPriority } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellKind, CellToolbarLocKey, CellUri, DisplayOrderKey, getCellUndoRedoComparisonKey, NotebookDocumentBackupData, NotebookEditorPriority } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, IOpenEditorOverride } from 'vs/workbench/services/editor/common/editorService'; @@ -385,13 +385,19 @@ configurationRegistry.registerConfiguration({ title: nls.localize('notebookConfigurationTitle', "Notebook"), type: 'object', properties: { - 'notebook.displayOrder': { - markdownDescription: nls.localize('notebook.displayOrder.description', "Priority list for output mime types"), + [DisplayOrderKey]: { + description: nls.localize('notebook.displayOrder.description', "Priority list for output mime types"), type: ['array'], items: { type: 'string' }, default: [] + }, + [CellToolbarLocKey]: { + description: nls.localize('notebook.cellToolbarLocation.description', "Where the cell toolbar should be shown, or whether it should be hidden."), + type: 'string', + enum: ['left', 'right', 'hidden'], + default: 'right' } } }); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 79f96f2d22d..7f14b13ebdf 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -36,7 +36,7 @@ import { CodeCellRenderer, MarkdownCellRenderer, NotebookCellListDelegate, ListT import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; import { NotebookEventDispatcher, NotebookLayoutChangedEvent } from 'vs/workbench/contrib/notebook/browser/viewModel/eventDispatcher'; import { CellViewModel, IModelDecorationsChangeAccessor, INotebookEditorViewState, NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel'; -import { CellKind, IProcessedOutput, INotebookKernelInfo, INotebookKernelInfoDto, INotebookKernelInfo2, NotebookRunState, NotebookCellRunState, IInsetRenderOutput } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { CellKind, IProcessedOutput, INotebookKernelInfo, INotebookKernelInfoDto, INotebookKernelInfo2, NotebookRunState, NotebookCellRunState, IInsetRenderOutput, CellToolbarLocKey } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -229,6 +229,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor this.layout(this._dimension); } } + + if (e.affectsConfiguration(CellToolbarLocKey)) { + this._updateForNotebookConfiguration(); + } }); this.notebookService.addNotebookEditor(this); @@ -267,6 +271,21 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor return true; } + private _updateForNotebookConfiguration() { + if (!this._overlayContainer) { + return; + } + + const cellToolbarLocation = this.configurationService.getValue(CellToolbarLocKey); + this._overlayContainer.classList.remove('cell-title-toolbar-left'); + this._overlayContainer.classList.remove('cell-title-toolbar-right'); + this._overlayContainer.classList.remove('cell-title-toolbar-hidden'); + + if (cellToolbarLocation === 'left' || cellToolbarLocation === 'right' || cellToolbarLocation === 'hidden') { + this._overlayContainer.classList.add(`cell-title-toolbar-${cellToolbarLocation}`); + } + } + updateEditorFocus() { // Note - focus going to the webview will fire 'blur', but the webview element will be // a descendent of the notebook editor root. @@ -355,6 +374,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor onUnexpectedError(err); } } + + this._updateForNotebookConfiguration(); } private _generateFontInfo(): void { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts index 4fdbe29a434..2fab79b87ab 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts @@ -27,7 +27,7 @@ import { NotebookKernelProviderAssociationRegistry, NotebookViewTypesExtensionRe import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel'; import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; -import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellEditType, CellOutputKind, CellUri, ICellEditOperation, IDisplayOutput, INotebookKernelInfo, INotebookKernelInfo2, INotebookKernelProvider, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, NotebookCellOutputsSplice, notebookDocumentFilterMatch, NotebookEditorPriority, NOTEBOOK_DISPLAY_ORDER, sortMimeTypes } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellEditType, CellOutputKind, CellUri, DisplayOrderKey, ICellEditOperation, IDisplayOutput, INotebookKernelInfo, INotebookKernelInfo2, INotebookKernelProvider, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, NotebookCellOutputsSplice, notebookDocumentFilterMatch, NotebookEditorPriority, NOTEBOOK_DISPLAY_ORDER, sortMimeTypes } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer'; import { NotebookEditorDescriptor, NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; @@ -313,7 +313,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu this._editorService.registerCustomEditorViewTypesHandler('Notebook', this); const updateOrder = () => { - const userOrder = this._configurationService.getValue('notebook.displayOrder'); + const userOrder = this._configurationService.getValue(DisplayOrderKey); this._displayOrder = { defaultOrder: this._accessibilityService.isScreenReaderOptimized() ? ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER : NOTEBOOK_DISPLAY_ORDER, userOrder: userOrder @@ -323,7 +323,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu updateOrder(); this._register(this._configurationService.onDidChangeConfiguration(e => { - if (e.affectedKeys.indexOf('notebook.displayOrder') >= 0) { + if (e.affectedKeys.indexOf(DisplayOrderKey) >= 0) { updateOrder(); } })); diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 68b34d4a5d3..4ae28b0e979 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -715,3 +715,6 @@ export interface INotebookKernelProvider { executeNotebook(uri: URI, kernelId: string, handle: number | undefined): Promise; cancelNotebook(uri: URI, kernelId: string, handle: number | undefined): Promise; } + +export const DisplayOrderKey = 'notebook.displayOrder'; +export const CellToolbarLocKey = 'notebook.cellToolbarLocation';