Skip to content

Commit

Permalink
Make cell gutter line interactive and clickable to collapse cell parts
Browse files Browse the repository at this point in the history
  • Loading branch information
roblourens committed Jan 11, 2022
1 parent f9fe61d commit 53b5b8a
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 95 deletions.
16 changes: 6 additions & 10 deletions src/vs/workbench/contrib/notebook/browser/media/notebook.css
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,6 @@
padding: 12px 16px;
}

.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-drag-image .cell-drag-handle {
display: none;
}

.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-drag-image.code-cell-row .cell-focus-indicator-side {
height: 44px !important;
}
Expand Down Expand Up @@ -687,14 +683,14 @@
border-color: var(--notebook-focused-cell-border-color) !important;
}

.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-drag-handle {
position: absolute;
top: 0px;
z-index: var(--z-index-cell-drag-handle);
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-left .codeOutput-focus-indicator {
position: relative;
width: 0px;
cursor: pointer;
}

.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-drag-handle:hover,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-inner-container:hover {
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-left,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-inner-container {
cursor: grab;
}

Expand Down
3 changes: 2 additions & 1 deletion src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,10 @@ export interface CodeCellLayoutInfo {
readonly outputTotalHeight: number;
readonly outputShowMoreContainerHeight: number;
readonly outputShowMoreContainerOffset: number;
readonly indicatorHeight: number;
readonly bottomToolbarOffset: number;
readonly layoutState: CellLayoutState;
readonly codeIndicatorHeight: number;
readonly outputIndicatorHeight: number;
}

export interface CodeCellLayoutChangeEvent {
Expand Down
54 changes: 22 additions & 32 deletions src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,8 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
insertToolbarPosition,
insertToolbarAlignment,
fontSize,
focusIndicatorLeftMargin
focusIndicatorLeftMargin,
focusIndicatorGap
} = this._notebookOptions.getLayoutConfiguration();

const { bottomToolbarGap, bottomToolbarHeight } = this._notebookOptions.computeBottomToolbarDimensions(this.viewModel?.viewType);
Expand Down Expand Up @@ -756,45 +757,36 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
top: -${cellTopMargin}px; height: calc(100% + ${cellTopMargin + cellBottomMargin}px)
}`);
} else {
// gutter
styleSheets.push(`
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-left:before,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-right:before {
content: "";
position: absolute;
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-left .codeOutput-focus-indicator,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.selected .cell-focus-indicator-left .codeOutput-focus-indicator {
border-left: 3px solid transparent;
border-radius: 4px;
margin-left: ${focusIndicatorLeftMargin}px;
width: 0px;
height: 100%;
z-index: 10;
}
`);

// left and right border margins
styleSheets.push(`
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.focused .cell-focus-indicator-left:before,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.focused .cell-focus-indicator-right:before,
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-left:before,
.monaco-workbench .notebookOverlay .monaco-list.selection-multiple .monaco-list-row.code-cell-row.selected .cell-focus-indicator-right:before {
top: 0px; height: 100%;
}`);
styleSheets.push(`
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-left:before,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.selected .cell-focus-indicator-left:before {
border-left: 3px solid transparent;
border-radius: 2px;
margin-left: ${focusIndicatorLeftMargin}px;
}`);
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-focus-indicator-left .codeOutput-focus-indicator:hover,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.selected .cell-focus-indicator-left .codeOutput-focus-indicator:hover {
border-left: 5px solid transparent;
margin-left: ${focusIndicatorLeftMargin - 1}px;
}
`);

// boder should always show
styleSheets.push(`
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-inner-container.cell-output-focus .cell-focus-indicator-left:before,
.monaco-workbench .notebookOverlay .monaco-list:focus-within .monaco-list-row.focused .cell-inner-container .cell-focus-indicator-left:before {
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-inner-container.cell-output-focus .cell-focus-indicator-left .codeOutput-focus-indicator,
.monaco-workbench .notebookOverlay .monaco-list:focus-within .monaco-list-row.focused .cell-inner-container .cell-focus-indicator-left .codeOutput-focus-indicator {
border-color: var(--notebook-focused-cell-border-color) !important;
}
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-inner-container .cell-focus-indicator-left:before {
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-inner-container .cell-focus-indicator-left .code-focus-indicator,
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-inner-container .cell-focus-indicator-left .output-focus-indicator {
border-color: var(--notebook-inactive-focused-cell-border-color) !important;
}
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.focused .cell-inner-container .cell-focus-indicator-left .output-focus-indicator {
margin-top: ${focusIndicatorGap}px;
}
`);
}

Expand Down Expand Up @@ -877,8 +869,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator { left: ${(markdownCellGutter - 20) / 2 + markdownCellLeftMargin}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row :not(.webview-backed-markdown-cell) .cell-focus-indicator-top { height: ${cellTopMargin}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-side { bottom: ${bottomToolbarGap}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left,
.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-drag-handle { width: ${codeCellLeftMargin + cellRunGutter}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.code-cell-row .cell-focus-indicator-left { width: ${codeCellLeftMargin + cellRunGutter}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-focus-indicator-left { width: ${codeCellLeftMargin}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator.cell-focus-indicator-right { width: ${cellRightMargin}px; }`);
styleSheets.push(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-bottom { height: ${cellBottomMargin}px; }`);
Expand Down Expand Up @@ -2927,7 +2918,6 @@ registerZIndex(ZIndex.Base, 10, 'notebook-list-insertion-indicator');
registerZIndex(ZIndex.Base, 20, 'notebook-cell-editor-outline');
registerZIndex(ZIndex.Base, 25, 'notebook-scrollbar');
registerZIndex(ZIndex.Base, 26, 'notebook-cell-status');
registerZIndex(ZIndex.Base, 26, 'notebook-cell-drag-handle');
registerZIndex(ZIndex.Base, 26, 'notebook-folding-indicator');
registerZIndex(ZIndex.Base, 27, 'notebook-output');
registerZIndex(ZIndex.Base, 28, 'notebook-cell-bottom-toolbar-container');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
*--------------------------------------------------------------------------------------------*/

import * as DOM from 'vs/base/browser/dom';
import { FastDomNode } from 'vs/base/browser/fastDomNode';
import { Delayer } from 'vs/base/common/async';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import { CellViewModelStateChangeEvent, expandCellRangesWithHiddenCells, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
import { expandCellRangesWithHiddenCells, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { BaseCellRenderTemplate, INotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon';
import { cloneNotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { CellEditType, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
Expand Down Expand Up @@ -417,27 +415,3 @@ export class CellDragAndDropController extends Disposable {
return this.getDropInsertDirection(dragPosRatio);
}
}

export class DragPart extends CellPart {
get domNode() {
return this.dragHandle.domNode;
}

constructor(
readonly notebookEditor: INotebookEditorDelegate,
readonly dragHandle: FastDomNode<HTMLElement>
) {
super();
}

renderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void { }
prepareLayout(): void { }
updateInternalLayoutNow(element: ICellViewModel): void {
const bottomToolbarDimensions = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType);
this.dragHandle.setHeight(element.layoutInfo.totalHeight - bottomToolbarDimensions.bottomToolbarGap);
}
updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// import * as DOM from 'vs/base/browser/dom';
import * as DOM from 'vs/base/browser/dom';
import { FastDomNode } from 'vs/base/browser/fastDomNode';
import { CellViewModelStateChangeEvent, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';

export class CellFocusIndicator extends CellPart {
private codeFocusIndicator: FastDomNode<HTMLElement>;
private outputFocusIndicator: FastDomNode<HTMLElement>;

private currentElement: ICellViewModel | undefined;

constructor(
readonly notebookEditor: INotebookEditorDelegate,
readonly top: FastDomNode<HTMLElement>,
Expand All @@ -19,10 +24,23 @@ export class CellFocusIndicator extends CellPart {
readonly bottom: FastDomNode<HTMLElement>
) {
super();

this.codeFocusIndicator = new FastDomNode(DOM.append(this.left.domNode, DOM.$('.codeOutput-focus-indicator.code-focus-indicator')));
this.outputFocusIndicator = new FastDomNode(DOM.append(this.left.domNode, DOM.$('.codeOutput-focus-indicator.output-focus-indicator')));
this._register(DOM.addDisposableListener(this.codeFocusIndicator.domNode, DOM.EventType.CLICK, () => {
if (this.currentElement) {
this.currentElement.isInputCollapsed = !this.currentElement.isInputCollapsed;
}
}));
this._register(DOM.addDisposableListener(this.outputFocusIndicator.domNode, DOM.EventType.CLICK, () => {
if (this.currentElement) {
this.currentElement.isOutputCollapsed = !this.currentElement.isOutputCollapsed;
}
}));
}

renderCell(element: ICellViewModel): void {
// no op
this.currentElement = element;
}

prepareLayout(): void {
Expand All @@ -36,13 +54,17 @@ export class CellFocusIndicator extends CellPart {
this.bottom.domNode.style.transform = `translateY(${indicatorPostion.bottomIndicatorTop}px)`;
this.left.setHeight(indicatorPostion.verticalIndicatorHeight);
this.right.setHeight(indicatorPostion.verticalIndicatorHeight);
this.codeFocusIndicator.setHeight(indicatorPostion.verticalIndicatorHeight);
} else {
// code cell
const cell = element as CodeCellViewModel;
const layoutInfo = this.notebookEditor.notebookOptions.getLayoutConfiguration();
const bottomToolbarDimensions = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.notebookEditor.textModel?.viewType);
this.left.setHeight(cell.layoutInfo.indicatorHeight);
this.right.setHeight(cell.layoutInfo.indicatorHeight);
const indicatorHeight = cell.layoutInfo.codeIndicatorHeight + cell.layoutInfo.outputIndicatorHeight;
this.left.setHeight(indicatorHeight);
this.right.setHeight(indicatorHeight);
this.codeFocusIndicator.setHeight(cell.layoutInfo.codeIndicatorHeight);
this.outputFocusIndicator.setHeight(Math.max(cell.layoutInfo.outputIndicatorHeight - cell.viewContext.notebookOptions.getLayoutConfiguration().focusIndicatorGap, 0));
this.bottom.domNode.style.transform = `translateY(${cell.layoutInfo.totalHeight - bottomToolbarDimensions.bottomToolbarGap - layoutInfo.cellBottomMargin}px)`;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { Range } from 'vs/editor/common/core/range';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICellOutputViewModel, ICellViewModel, IGenericCellViewModel, INotebookCellOutputLayoutInfo, INotebookEditorCreationOptions, IRenderOutput, RenderOutputType } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { DragPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd';
import { CellExecutionPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution';
import { CellFocusIndicator } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator';
import { CellProgressBar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar';
Expand Down Expand Up @@ -128,7 +127,6 @@ export interface CodeCellRenderTemplate extends BaseCellRenderTemplate {
focusSinkElement: HTMLElement;
editor: ICodeEditor;
progressBar: CellProgressBar;
dragHandle: DragPart;
cellExecution: CellExecutionPart;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import { EditorOption, IEditorOptions } from 'vs/editor/common/config/editorOpti
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
import { Range } from 'vs/editor/common/core/range';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { ITextModel } from 'vs/editor/common/model';
import * as modes from 'vs/editor/common/languages';
import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry';
import { tokenizeLineToHTML } from 'vs/editor/common/languages/textToHtmlTokenizer';
import { ITextModel } from 'vs/editor/common/model';
import { localize } from 'vs/nls';
import { IMenuService } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
Expand All @@ -32,13 +33,13 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { CodeCellLayoutInfo, EXPAND_CELL_OUTPUT_COMMAND_ID, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellContextKeyManager } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellContextKeys';
import { CellDecorations } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellDecorations';
import { CellDragAndDropController, DragPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd';
import { CellDragAndDropController } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd';
import { CellEditorOptions } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions';
import { CellExecutionPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellExecution';
import { CellFocusIndicator } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellFocusIndicator';
import { CellProgressBar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellProgressBar';
import { BetweenCellToolbar, CellTitleToolbarPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars';
import { CellEditorStatusBar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellStatusPart';
import { BetweenCellToolbar, CellTitleToolbarPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellToolbars';
import { CodeCell } from 'vs/workbench/contrib/notebook/browser/view/cellParts/codeCell';
import { RunToolbar } from 'vs/workbench/contrib/notebook/browser/view/cellParts/codeCellRunToolbar';
import { StatefulMarkdownCell } from 'vs/workbench/contrib/notebook/browser/view/cellParts/markdownCell';
Expand All @@ -47,7 +48,6 @@ import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewMod
import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel';
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry';

const $ = DOM.$;

Expand Down Expand Up @@ -377,7 +377,6 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
const focusIndicatorTop = new FastDomNode(DOM.append(container, $('.cell-focus-indicator.cell-focus-indicator-top')));
const titleToolbarContainer = DOM.append(container, $('.cell-title-toolbar'));
const focusIndicatorLeft = new FastDomNode(DOM.append(container, DOM.$('.cell-focus-indicator.cell-focus-indicator-side.cell-focus-indicator-left')));
const dragHandle = new DragPart(this.notebookEditor, new FastDomNode(DOM.append(container, DOM.$('.cell-drag-handle'))));

const cellContainer = DOM.append(container, $('.cell.code'));
const runButtonContainer = DOM.append(cellContainer, $('.run-button-container'));
Expand Down Expand Up @@ -457,13 +456,12 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
editor,
templateDisposables,
elementDisposables: new DisposableStore(),
dragHandle,
toJSON: () => { return {}; }
};

this.setupOutputCollapsedPart(templateData);

this.dndController?.registerDragHandle(templateData, rootContainer, dragHandle.domNode, () => new CodeCellDragImageRenderer().getDragImage(templateData, templateData.editor, 'code'));
this.dndController?.registerDragHandle(templateData, rootContainer, focusIndicatorLeft.domNode, () => new CodeCellDragImageRenderer().getDragImage(templateData, templateData.editor, 'code'));

templateDisposables.add(this.addCollapseClickCollapseHandler(templateData));
templateDisposables.add(DOM.addDisposableListener(focusSinkElement, DOM.EventType.FOCUS, () => {
Expand Down Expand Up @@ -518,7 +516,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
}

private addCollapseClickCollapseHandler(templateData: CodeCellRenderTemplate): IDisposable {
const dragHandleListener = DOM.addDisposableListener(templateData.dragHandle.domNode, DOM.EventType.DBLCLICK, e => {
const dragHandleListener = DOM.addDisposableListener(templateData.focusIndicator.left.domNode, DOM.EventType.DBLCLICK, e => {
const cell = templateData.currentRenderedCell;
if (!cell || !this.notebookEditor.hasModel()) {
return;
Expand Down Expand Up @@ -587,8 +585,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
templateData.progressBar,
templateData.titleToolbar,
templateData.runToolbar,
templateData.cellExecution,
templateData.dragHandle
templateData.cellExecution
]));

this.renderedEditors.set(element, templateData.editor);
Expand Down
Loading

0 comments on commit 53b5b8a

Please sign in to comment.