mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-26 04:34:32 +00:00
Folded cells run-in-section (#205315)
* initial functionality, needs css tweaks * update button css + add executing spinner * mutable disposable to avoid leaking listeners
This commit is contained in:
@@ -46,6 +46,8 @@
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folded-hint {
|
||||
position: absolute;
|
||||
user-select: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folded-hint-label {
|
||||
@@ -55,6 +57,22 @@
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container .folded-cell-run-section-button {
|
||||
position: relative;
|
||||
left: 0px;
|
||||
padding: 2px;
|
||||
border-radius: 5px;
|
||||
margin-right: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
z-index: var(--z-index-notebook-cell-expand-part-button);
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container .folded-cell-run-section-button:hover {
|
||||
background-color: var(--vscode-editorStickyScrollHover-background);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .cell-editor-container .monaco-editor .margin-view-overlays .codicon-folding-expanded,
|
||||
.monaco-workbench .notebookOverlay .cell-editor-container .monaco-editor .margin-view-overlays .codicon-folding-collapsed {
|
||||
margin-left: 0;
|
||||
|
||||
@@ -11,12 +11,21 @@ import { FoldingController } from 'vs/workbench/contrib/notebook/browser/control
|
||||
import { CellEditState, CellFoldingState, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellContentPart } from 'vs/workbench/contrib/notebook/browser/view/cellPart';
|
||||
import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel';
|
||||
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { executingStateIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
|
||||
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||
import { NotebookCellExecutionState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class FoldedCellHint extends CellContentPart {
|
||||
|
||||
private readonly _runButtonListener = this._register(new MutableDisposable());
|
||||
private readonly _cellExecutionListener = this._register(new MutableDisposable());
|
||||
|
||||
constructor(
|
||||
private readonly _notebookEditor: INotebookEditor,
|
||||
private readonly _container: HTMLElement,
|
||||
@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -27,20 +36,27 @@ export class FoldedCellHint extends CellContentPart {
|
||||
|
||||
private update(element: MarkupCellViewModel) {
|
||||
if (!this._notebookEditor.hasModel()) {
|
||||
this._cellExecutionListener.clear();
|
||||
this._runButtonListener.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (element.isInputCollapsed || element.getEditState() === CellEditState.Editing) {
|
||||
this._cellExecutionListener.clear();
|
||||
this._runButtonListener.clear();
|
||||
DOM.hide(this._container);
|
||||
} else if (element.foldingState === CellFoldingState.Collapsed) {
|
||||
const idx = this._notebookEditor.getViewModel().getCellIndex(element);
|
||||
const length = this._notebookEditor.getViewModel().getFoldedLength(idx);
|
||||
DOM.reset(this._container, this.getHiddenCellsLabel(length), this.getHiddenCellHintButton(element));
|
||||
|
||||
DOM.reset(this._container, this.getRunFoldedSectionButton({ start: idx, end: idx + length }), this.getHiddenCellsLabel(length), this.getHiddenCellHintButton(element));
|
||||
DOM.show(this._container);
|
||||
|
||||
const foldHintTop = element.layoutInfo.previewHeight;
|
||||
this._container.style.top = `${foldHintTop}px`;
|
||||
} else {
|
||||
this._cellExecutionListener.clear();
|
||||
this._runButtonListener.clear();
|
||||
DOM.hide(this._container);
|
||||
}
|
||||
}
|
||||
@@ -67,6 +83,40 @@ export class FoldedCellHint extends CellContentPart {
|
||||
return expandIcon;
|
||||
}
|
||||
|
||||
private getRunFoldedSectionButton(range: ICellRange): HTMLElement {
|
||||
const runAllContainer = DOM.$('span.folded-cell-run-section-button');
|
||||
const cells = this._notebookEditor.getCellsInRange(range);
|
||||
|
||||
const isRunning = cells.some(cell => {
|
||||
const cellExecution = this._notebookExecutionStateService.getCellExecution(cell.uri);
|
||||
return cellExecution && cellExecution.state === NotebookCellExecutionState.Executing;
|
||||
});
|
||||
|
||||
const runAllIcon = isRunning ?
|
||||
ThemeIcon.modify(executingStateIcon, 'spin') :
|
||||
Codicon.play;
|
||||
runAllContainer.classList.add(...ThemeIcon.asClassNameArray(runAllIcon));
|
||||
|
||||
this._runButtonListener.value = DOM.addDisposableListener(runAllContainer, DOM.EventType.CLICK, () => {
|
||||
this._notebookEditor.executeNotebookCells(cells);
|
||||
});
|
||||
|
||||
this._cellExecutionListener.value = this._notebookExecutionStateService.onDidChangeExecution(() => {
|
||||
const isRunning = cells.some(cell => {
|
||||
const cellExecution = this._notebookExecutionStateService.getCellExecution(cell.uri);
|
||||
return cellExecution && cellExecution.state === NotebookCellExecutionState.Executing;
|
||||
});
|
||||
|
||||
const runAllIcon = isRunning ?
|
||||
ThemeIcon.modify(executingStateIcon, 'spin') :
|
||||
Codicon.play;
|
||||
runAllContainer.className = '';
|
||||
runAllContainer.classList.add('folded-cell-run-section-button', ...ThemeIcon.asClassNameArray(runAllIcon));
|
||||
});
|
||||
|
||||
return runAllContainer;
|
||||
}
|
||||
|
||||
override updateInternalLayoutNow(element: MarkupCellViewModel) {
|
||||
this.update(element);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ 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/notebookViewModelImpl';
|
||||
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -109,6 +110,8 @@ abstract class AbstractCellRenderer {
|
||||
export class MarkupCellRenderer extends AbstractCellRenderer implements IListRenderer<MarkupCellViewModel, MarkdownCellRenderTemplate> {
|
||||
static readonly TEMPLATE_ID = 'markdown_cell';
|
||||
|
||||
private _notebookExecutionStateService: INotebookExecutionStateService;
|
||||
|
||||
constructor(
|
||||
notebookEditor: INotebookEditorDelegate,
|
||||
dndController: CellDragAndDropController,
|
||||
@@ -120,8 +123,10 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
|
||||
@IMenuService menuService: IMenuService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@INotebookExecutionStateService notebookExecutionStateService: INotebookExecutionStateService
|
||||
) {
|
||||
super(instantiationService, notebookEditor, contextMenuService, menuService, configurationService, keybindingService, notificationService, contextKeyServiceProvider, 'markdown', dndController);
|
||||
this._notebookExecutionStateService = notebookExecutionStateService;
|
||||
}
|
||||
|
||||
get templateId() {
|
||||
@@ -169,7 +174,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
|
||||
templateDisposables.add(scopedInstaService.createInstance(CellChatPart, this.notebookEditor, cellChatPart)),
|
||||
templateDisposables.add(scopedInstaService.createInstance(CellEditorStatusBar, this.notebookEditor, container, editorPart, undefined)),
|
||||
templateDisposables.add(new CellFocusIndicator(this.notebookEditor, titleToolbar, focusIndicatorTop, focusIndicatorLeft, focusIndicatorRight, focusIndicatorBottom)),
|
||||
templateDisposables.add(new FoldedCellHint(this.notebookEditor, DOM.append(container, $('.notebook-folded-hint')))),
|
||||
templateDisposables.add(new FoldedCellHint(this.notebookEditor, DOM.append(container, $('.notebook-folded-hint')), this._notebookExecutionStateService)),
|
||||
templateDisposables.add(new CellDecorations(rootContainer, decorationContainer)),
|
||||
templateDisposables.add(scopedInstaService.createInstance(CellComments, this.notebookEditor, cellCommentPartContainer)),
|
||||
templateDisposables.add(new CollapsedCellInput(this.notebookEditor, cellInputCollapsedContainer)),
|
||||
|
||||
Reference in New Issue
Block a user