From 308029c03c3d73b68878160561fc59e4ecbb12e4 Mon Sep 17 00:00:00 2001 From: Cory Rivera Date: Tue, 6 Aug 2019 10:31:46 -0700 Subject: [PATCH] Add buttons to Notebooks for creating new cells between other existing cells (#6596) --- .../notebook/browser/cellToggleMoreActions.ts | 32 -------- .../browser/media/dark/add_code_inverse.svg | 3 + .../browser/media/dark/add_text_inverse.svg | 3 + .../notebook/browser/media/light/add_code.svg | 3 + .../notebook/browser/media/light/add_text.svg | 3 + .../notebook/browser/notebook.component.html | 34 ++++++-- .../notebook/browser/notebook.component.ts | 12 ++- .../parts/notebook/browser/notebook.css | 81 ++++++++++++++++++- .../parts/notebook/browser/notebookStyles.ts | 47 ++++++++++- 9 files changed, 174 insertions(+), 44 deletions(-) create mode 100644 src/sql/workbench/parts/notebook/browser/media/dark/add_code_inverse.svg create mode 100644 src/sql/workbench/parts/notebook/browser/media/dark/add_text_inverse.svg create mode 100644 src/sql/workbench/parts/notebook/browser/media/light/add_code.svg create mode 100644 src/sql/workbench/parts/notebook/browser/media/light/add_text.svg diff --git a/src/sql/workbench/parts/notebook/browser/cellToggleMoreActions.ts b/src/sql/workbench/parts/notebook/browser/cellToggleMoreActions.ts index f4250c6bb6..bd97b8132e 100644 --- a/src/sql/workbench/parts/notebook/browser/cellToggleMoreActions.ts +++ b/src/sql/workbench/parts/notebook/browser/cellToggleMoreActions.ts @@ -30,10 +30,6 @@ export class CellToggleMoreActions { @IInstantiationService private instantiationService: IInstantiationService) { this._actions.push( instantiationService.createInstance(DeleteCellAction, 'delete', localize('delete', "Delete")), - instantiationService.createInstance(AddCellFromContextAction, 'codeBefore', localize('codeBefore', "Insert Code Before"), CellTypes.Code, false), - instantiationService.createInstance(AddCellFromContextAction, 'codeAfter', localize('codeAfter', "Insert Code After"), CellTypes.Code, true), - instantiationService.createInstance(AddCellFromContextAction, 'markdownBefore', localize('markdownBefore', "Insert Text Before"), CellTypes.Markdown, false), - instantiationService.createInstance(AddCellFromContextAction, 'markdownAfter', localize('markdownAfter', "Insert Text After"), CellTypes.Markdown, true), instantiationService.createInstance(RunCellsAction, 'runAllBefore', localize('runAllBefore', "Run Cells Before"), false), instantiationService.createInstance(RunCellsAction, 'runAllAfter', localize('runAllAfter', "Run Cells After"), true), instantiationService.createInstance(ClearCellOutputAction, 'clear', localize('clear', "Clear Output")) @@ -64,34 +60,6 @@ export class CellToggleMoreActions { } } -export class AddCellFromContextAction extends CellActionBase { - constructor( - id: string, label: string, private cellType: CellType, private isAfter: boolean, - @INotificationService notificationService: INotificationService - ) { - super(id, label, undefined, notificationService); - } - - doRun(context: CellContext): Promise { - try { - let model = context.model; - let index = model.cells.findIndex((cell) => cell.id === context.cell.id); - if (index !== undefined && this.isAfter) { - index += 1; - } - model.addCell(this.cellType, index); - } catch (error) { - let message = getErrorMessage(error); - - this.notificationService.notify({ - severity: Severity.Error, - message: message - }); - } - return Promise.resolve(); - } -} - export class DeleteCellAction extends CellActionBase { constructor(id: string, label: string, @INotificationService notificationService: INotificationService diff --git a/src/sql/workbench/parts/notebook/browser/media/dark/add_code_inverse.svg b/src/sql/workbench/parts/notebook/browser/media/dark/add_code_inverse.svg new file mode 100644 index 0000000000..111f7d4625 --- /dev/null +++ b/src/sql/workbench/parts/notebook/browser/media/dark/add_code_inverse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/workbench/parts/notebook/browser/media/dark/add_text_inverse.svg b/src/sql/workbench/parts/notebook/browser/media/dark/add_text_inverse.svg new file mode 100644 index 0000000000..e9e910221d --- /dev/null +++ b/src/sql/workbench/parts/notebook/browser/media/dark/add_text_inverse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/workbench/parts/notebook/browser/media/light/add_code.svg b/src/sql/workbench/parts/notebook/browser/media/light/add_code.svg new file mode 100644 index 0000000000..b2aa37ee45 --- /dev/null +++ b/src/sql/workbench/parts/notebook/browser/media/light/add_code.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/workbench/parts/notebook/browser/media/light/add_text.svg b/src/sql/workbench/parts/notebook/browser/media/light/add_text.svg new file mode 100644 index 0000000000..f862c53252 --- /dev/null +++ b/src/sql/workbench/parts/notebook/browser/media/light/add_text.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/sql/workbench/parts/notebook/browser/notebook.component.html b/src/sql/workbench/parts/notebook/browser/notebook.component.html index b35b74c95c..e7de69e9c9 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.component.html +++ b/src/sql/workbench/parts/notebook/browser/notebook.component.html @@ -9,11 +9,35 @@
-
- - - - +
+ + + +
+
+
+ + + + +
+
+ + + +
diff --git a/src/sql/workbench/parts/notebook/browser/notebook.component.ts b/src/sql/workbench/parts/notebook/browser/notebook.component.ts index a33b8942af..e489677947 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.component.ts +++ b/src/sql/workbench/parts/notebook/browser/notebook.component.ts @@ -159,6 +159,14 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe return this._model ? this._model.cells : []; } + public get addCodeLabel(): string { + return localize('addCodeLabel', "Add code"); + } + + public get addTextLabel(): string { + return localize('addTextLabel', "Add text"); + } + private updateTheme(theme: IColorTheme): void { let toolbarEl = this.toolbar.nativeElement; toolbarEl.style.borderBottomColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString(); @@ -192,8 +200,8 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe } // Add cell based on cell type - public addCell(cellType: CellType) { - this._model.addCell(cellType); + public addCell(cellType: CellType, index?: number) { + this._model.addCell(cellType, index); } public onKeyDown(event) { diff --git a/src/sql/workbench/parts/notebook/browser/notebook.css b/src/sql/workbench/parts/notebook/browser/notebook.css index 8868d3e3cb..b5d79d0106 100644 --- a/src/sql/workbench/parts/notebook/browser/notebook.css +++ b/src/sql/workbench/parts/notebook/browser/notebook.css @@ -8,7 +8,7 @@ } .notebookEditor .notebook-cell { - margin: 10px 20px 10px; + margin: 1px 20px; border-width: 1px; border-style: solid; border-radius: 3px; @@ -136,4 +136,81 @@ .notebookEditor .book-nav .dialog-message-button { min-width: 100px; margin-right: 10px; -} \ No newline at end of file +} + +.notebookEditor .hoverButtonsContainer { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + width: 60%; + margin: 1px auto; +} + +.notebookEditor .hoverButtonsContainer .containerBackground { + position: absolute; + width: inherit; + height: 2px; + border-radius: 3px; + opacity: 0.4; + z-index: 0; + visibility: hidden; +} + +.notebookEditor .hoverButtonsContainer:hover .containerBackground { + visibility: visible; +} + +.notebookEditor .hoverButtonsContainer .hoverButton { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + margin: 3px; + padding: 4px 6px; + font-size: 10px; + box-sizing: border-box; + border-color: transparent; + border-width: 1px; + border-style: solid; + border-radius: 3px; + z-index: 1; + visibility: hidden; +} + +.notebookEditor .hoverButtonsContainer:hover .hoverButton { + visibility: visible; +} + +.notebookEditor .hoverButton:active { + transform:scale(1.05); +} + +.notebookEditor .hoverButton .addCodeIcon, +.notebookEditor .hoverButton .addTextIcon { + display: inline-block; + background-position: center center; + background-repeat: no-repeat; + width: 10px; + height: 10px; + background-size: contain; + margin-right: 4px; +} + +.notebookEditor .hoverButton .addCodeIcon { + background-image: url("./media/light/add_code.svg"); +} + +.vs-dark .notebookEditor .hoverButton .addCodeIcon, +.hc-black .notebookEditor .hoverButton .addCodeIcon { + background-image: url("./media/dark/add_code_inverse.svg"); +} + +.notebookEditor .hoverButton .addTextIcon { + background-image: url("./media/light/add_text.svg"); +} + +.vs-dark .notebookEditor .hoverButton .addTextIcon, +.hc-black .notebookEditor .hoverButton .addTextIcon { + background-image: url("./media/dark/add_text_inverse.svg"); +} diff --git a/src/sql/workbench/parts/notebook/browser/notebookStyles.ts b/src/sql/workbench/parts/notebook/browser/notebookStyles.ts index 44d09bf56a..2f1f267259 100644 --- a/src/sql/workbench/parts/notebook/browser/notebookStyles.ts +++ b/src/sql/workbench/parts/notebook/browser/notebookStyles.ts @@ -6,7 +6,7 @@ import 'vs/css!./notebook'; import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { SIDE_BAR_BACKGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, EDITOR_GROUP_HEADER_TABS_BACKGROUND } from 'vs/workbench/common/theme'; -import { activeContrastBorder, contrastBorder, buttonBackground, textLinkForeground, textLinkActiveForeground, textPreformatForeground, textBlockQuoteBackground, textBlockQuoteBorder, buttonForeground } from 'vs/platform/theme/common/colorRegistry'; +import { activeContrastBorder, contrastBorder, buttonBackground, textLinkForeground, textLinkActiveForeground, textPreformatForeground, textBlockQuoteBackground, textBlockQuoteBorder, buttonForeground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; import { editorLineHighlight, editorLineHighlightBorder } from 'vs/editor/common/view/editorColorRegistry'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -37,6 +37,15 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf `); } + const textColor = theme.getColor(editorForeground); + if (textColor) { + collector.addRule(` + .notebookEditor .hoverButtonsContainer .hoverButton { + color: ${textColor}; + } + `); + } + // Active border const activeBorder = theme.getColor(buttonBackground); if (activeBorder) { @@ -46,6 +55,16 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf border-width: 1px; } `); + + collector.addRule(` + .notebookEditor .hoverButton:active { + border-color: ${activeBorder}; + } + + .notebookEditor .hoverButtonsContainer .containerBackground { + background-color: ${activeBorder}; + } + `); } // Box shadow handling @@ -77,6 +96,18 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf .hc-black .notebookEditor .notebook-cell:hover:not(.active) { box-shadow: 0; } + + .notebookEditor .hoverButtonsContainer .hoverButton:hover { + box-shadow: ${lightBoxShadow}; + } + + .vs-dark .notebookEditor .hoverButtonsContainer .hoverButton:hover { + box-shadow: ${darkBoxShadow}; + } + + .hc-black .notebookEditor .hoverButtonsContainer .hoverButton:hover { + box-shadow: 0; + } `); const inactiveBorder = theme.getColor(SIDE_BAR_BACKGROUND); @@ -111,6 +142,13 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf { background-color: ${codeBackground}; }`); + + collector.addRule(` + .notebookEditor .hoverButtonsContainer .hoverButton { + background-color: ${codeBackground}; + } + `); + // Margin background will be the same (may override some styles) collector.addRule(`.notebook-cell:not(.active) code-component .monaco-editor .margin { background-color: ${codeBackground}; }`); addBorderToInactiveCodeCells = false; @@ -159,7 +197,6 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf } `); } - } // Sidebar and cell outline toolbar color set only when active @@ -191,6 +228,10 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf outline-width: 1px; outline-style: solid; } + .hc-black .notebookEditor .hoverButton:not(:active) { + border-color: ${hcOutline}; + border-radius: 0px; + } `); } @@ -270,4 +311,4 @@ export function registerNotebookThemes(overrideEditorThemeSetting: boolean, conf ${getBareResultsGridInfoStyles(rawOptions)} }`); }); -} \ No newline at end of file +}