mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-14 12:11:43 +01:00
@@ -415,7 +415,7 @@
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .notebook-folding-indicator.mouseover .codicon.codicon-notebook-expanded {
|
||||
opacity: 0;
|
||||
transition: opacity 0.s;
|
||||
transition: opacity 0.1 s;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .markdown-cell-hover .notebook-folding-indicator.mouseover .codicon.codicon-notebook-expanded {
|
||||
@@ -851,6 +851,15 @@
|
||||
padding: 4px 4px 4px 4px;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folded-hint {
|
||||
position: absolute;
|
||||
font-size: var(--notebook-cell-output-font-size);
|
||||
font-family: var(--monaco-monospace-font);
|
||||
font-style: italic;
|
||||
opacity: 0.7;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/** Theming */
|
||||
|
||||
.monaco-action-bar .action-item.verticalSeparator {
|
||||
|
||||
@@ -237,6 +237,7 @@ export interface MarkdownCellLayoutInfo {
|
||||
readonly bottomToolbarOffset: number;
|
||||
readonly totalHeight: number;
|
||||
readonly layoutState: CellLayoutState;
|
||||
readonly foldHintHeight: number;
|
||||
}
|
||||
|
||||
export interface MarkdownCellLayoutChangeEvent {
|
||||
|
||||
@@ -867,6 +867,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
|
||||
|
||||
styleSheets.push(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.markdown { padding-left: ${cellRunGutter}px; }`);
|
||||
styleSheets.push(`.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folding-indicator { left: ${(markdownCellGutter - 20) / 2 + markdownCellLeftMargin}px; }`);
|
||||
styleSheets.push(`.notebookOverlay > .cell-list-container .notebook-folded-hint { left: ${markdownCellGutter + markdownCellLeftMargin + 8}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 { width: ${codeCellLeftMargin + cellRunGutter}px; }`);
|
||||
|
||||
@@ -8,6 +8,7 @@ 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 { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel';
|
||||
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
|
||||
export class CellFocusIndicator extends CellPart {
|
||||
@@ -50,7 +51,7 @@ export class CellFocusIndicator extends CellPart {
|
||||
updateInternalLayoutNow(element: ICellViewModel): void {
|
||||
if (element.cellKind === CellKind.Markup) {
|
||||
// markdown cell
|
||||
const indicatorPostion = this.notebookEditor.notebookOptions.computeIndicatorPosition(element.layoutInfo.totalHeight, this.notebookEditor.textModel?.viewType);
|
||||
const indicatorPostion = this.notebookEditor.notebookOptions.computeIndicatorPosition(element.layoutInfo.totalHeight, (element as MarkupCellViewModel).layoutInfo.foldHintHeight, this.notebookEditor.textModel?.viewType);
|
||||
this.bottom.domNode.style.transform = `translateY(${indicatorPostion.bottomIndicatorTop}px)`;
|
||||
this.left.setHeight(indicatorPostion.verticalIndicatorHeight);
|
||||
this.right.setHeight(indicatorPostion.verticalIndicatorHeight);
|
||||
|
||||
@@ -27,6 +27,7 @@ import { ILanguageService } from 'vs/editor/common/services/language';
|
||||
import { CellEditorOptions } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellEditorOptions';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
|
||||
export class StatefulMarkdownCell extends Disposable {
|
||||
@@ -75,7 +76,7 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
this.updateForHover();
|
||||
this.updateForFocusModeChange();
|
||||
this.foldingState = viewCell.foldingState;
|
||||
this.setFoldingIndicator();
|
||||
this.layoutFoldingIndicator();
|
||||
this.updateFoldingIconShowClass();
|
||||
|
||||
// the markdown preview's height might already be updated after the renderer calls `element.getHeight()`
|
||||
@@ -138,7 +139,7 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
|
||||
if (foldingState !== this.foldingState) {
|
||||
this.foldingState = foldingState;
|
||||
this.setFoldingIndicator();
|
||||
this.layoutFoldingIndicator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,6 +416,7 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
|
||||
relayoutCell(): void {
|
||||
this.notebookEditor.layoutNotebookCell(this.viewCell, this.viewCell.layoutInfo.totalHeight);
|
||||
this.layoutFoldingIndicator();
|
||||
}
|
||||
|
||||
updateEditorOptions(newValue: IEditorOptions): void {
|
||||
@@ -424,16 +426,33 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
setFoldingIndicator() {
|
||||
private layoutFoldingIndicator() {
|
||||
switch (this.foldingState) {
|
||||
case CellFoldingState.None:
|
||||
this.templateData.foldingIndicator.innerText = '';
|
||||
DOM.hide(this.templateData.foldedContentHint);
|
||||
break;
|
||||
case CellFoldingState.Collapsed:
|
||||
DOM.reset(this.templateData.foldingIndicator, renderIcon(collapsedIcon));
|
||||
break;
|
||||
{
|
||||
DOM.reset(this.templateData.foldingIndicator, renderIcon(collapsedIcon));
|
||||
|
||||
if (this.viewCell.isInputCollapsed) {
|
||||
DOM.hide(this.templateData.foldedContentHint);
|
||||
} else {
|
||||
const idx = this.notebookEditor._getViewModel().getCellIndex(this.viewCell);
|
||||
const length = this.notebookEditor._getViewModel().getFoldedLength(idx);
|
||||
DOM.reset(this.templateData.foldedContentHint, this.getHiddenCellsLabel(length));
|
||||
DOM.show(this.templateData.foldedContentHint);
|
||||
|
||||
const { bottomToolbarGap } = this.notebookEditor.notebookOptions.computeBottomToolbarDimensions(this.viewCell.viewType);
|
||||
const foldHintTop = this.viewCell.layoutInfo.totalHeight - bottomToolbarGap - this.viewCell.layoutInfo.foldHintHeight;
|
||||
this.templateData.foldedContentHint.style.top = `${foldHintTop}px`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CellFoldingState.Expanded:
|
||||
DOM.reset(this.templateData.foldingIndicator, renderIcon(expandedIcon));
|
||||
DOM.hide(this.templateData.foldedContentHint);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -441,6 +460,14 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private getHiddenCellsLabel(num: number): string {
|
||||
if (num === 1) {
|
||||
return localize('hiddenCellsLabel', "1 cell hidden...");
|
||||
} else {
|
||||
return localize('hiddenCellsLabelPlural', "{0} cells hidden...", num);
|
||||
}
|
||||
}
|
||||
|
||||
private bindEditorListeners(editor: CodeEditorWidget) {
|
||||
|
||||
this.localDisposables.clear();
|
||||
|
||||
@@ -116,6 +116,7 @@ export interface BaseCellRenderTemplate {
|
||||
export interface MarkdownCellRenderTemplate extends BaseCellRenderTemplate {
|
||||
editorContainer: HTMLElement;
|
||||
foldingIndicator: HTMLElement;
|
||||
foldedContentHint: HTMLElement;
|
||||
currentEditor?: ICodeEditor;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
|
||||
const focusIndicatorLeft = new FastDomNode(DOM.append(container, DOM.$('.cell-focus-indicator.cell-focus-indicator-side.cell-focus-indicator-left')));
|
||||
const foldingIndicator = DOM.append(focusIndicatorLeft.domNode, DOM.$('.notebook-folding-indicator'));
|
||||
const focusIndicatorRight = new FastDomNode(DOM.append(container, DOM.$('.cell-focus-indicator.cell-focus-indicator-side.cell-focus-indicator-right')));
|
||||
const foldedContentHint = DOM.append(container, $('.notebook-folded-hint'));
|
||||
|
||||
const codeInnerContent = DOM.append(container, $('.cell.code'));
|
||||
const editorPart = DOM.append(codeInnerContent, $('.cell-editor-part'));
|
||||
@@ -196,6 +197,7 @@ export class MarkupCellRenderer extends AbstractCellRenderer implements IListRen
|
||||
betweenCellToolbar,
|
||||
titleToolbar,
|
||||
statusBar,
|
||||
foldedContentHint,
|
||||
toJSON: () => { return {}; }
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Emitter, Event } from 'vs/base/common/event';
|
||||
import * as UUID from 'vs/base/common/uuid';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
|
||||
import { CellFoldingState, EditorFoldingStateDelegate } from 'vs/workbench/contrib/notebook/browser/contrib/fold/foldingModel';
|
||||
import { CellEditState, CellFindMatch, CellLayoutState, ICellOutputViewModel, ICellViewModel, MarkdownCellLayoutChangeEvent, MarkdownCellLayoutInfo, NotebookCellStateChangedEvent, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { BaseCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/baseCellViewModel';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
@@ -40,25 +40,14 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
private _previewHeight = 0;
|
||||
|
||||
set renderedMarkdownHeight(newHeight: number) {
|
||||
if (this.getEditState() === CellEditState.Preview) {
|
||||
this._previewHeight = newHeight;
|
||||
const { bottomToolbarGap } = this.viewContext.notebookOptions.computeBottomToolbarDimensions(this.viewType);
|
||||
|
||||
this._updateTotalHeight(this._previewHeight + bottomToolbarGap);
|
||||
}
|
||||
this._previewHeight = newHeight;
|
||||
this._updateTotalHeight(this._computeTotalHeight());
|
||||
}
|
||||
|
||||
private _editorHeight = 0;
|
||||
set editorHeight(newHeight: number) {
|
||||
this._editorHeight = newHeight;
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
const { bottomToolbarGap } = this.viewContext.notebookOptions.computeBottomToolbarDimensions(this.viewType);
|
||||
|
||||
this._updateTotalHeight(this._editorHeight
|
||||
+ layoutConfiguration.markdownCellTopMargin // MARKDOWN_CELL_TOP_MARGIN
|
||||
+ layoutConfiguration.markdownCellBottomMargin // MARKDOWN_CELL_BOTTOM_MARGIN
|
||||
+ bottomToolbarGap // BOTTOM_CELL_TOOLBAR_GAP
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight());
|
||||
this._updateTotalHeight(this._computeTotalHeight());
|
||||
}
|
||||
|
||||
get editorHeight() {
|
||||
@@ -125,32 +114,48 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
: 0,
|
||||
bottomToolbarOffset: bottomToolbarGap,
|
||||
totalHeight: 100,
|
||||
layoutState: CellLayoutState.Uninitialized
|
||||
layoutState: CellLayoutState.Uninitialized,
|
||||
foldHintHeight: 0
|
||||
};
|
||||
|
||||
this._register(this.onDidChangeState(e => {
|
||||
this.viewContext.eventDispatcher.emit([new NotebookCellStateChangedEvent(e, this)]);
|
||||
|
||||
if (e.foldingStateChanged) {
|
||||
this._updateTotalHeight(this._computeTotalHeight());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private _computeTotalHeight(): number {
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
const { bottomToolbarGap } = this.viewContext.notebookOptions.computeBottomToolbarDimensions(this.viewType);
|
||||
const foldHintHeight = this._computeFoldHintHeight();
|
||||
|
||||
if (this.getEditState() === CellEditState.Editing) {
|
||||
return this._editorHeight
|
||||
+ layoutConfiguration.markdownCellTopMargin
|
||||
+ layoutConfiguration.markdownCellBottomMargin
|
||||
+ bottomToolbarGap
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight()
|
||||
+ foldHintHeight;
|
||||
} else {
|
||||
// @rebornix
|
||||
// On file open, the previewHeight + bottomToolbarGap for a cell out of viewport can be 0
|
||||
// When it's 0, the list view will never try to render it anymore even if we scroll the cell into view.
|
||||
// Thus we make sure it's greater than 0
|
||||
return Math.max(1, this._previewHeight + bottomToolbarGap + foldHintHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private _computeFoldHintHeight(): number {
|
||||
return this.foldingState === CellFoldingState.Collapsed ?
|
||||
this.viewContext.notebookOptions.getLayoutConfiguration().markdownFoldHintHeight : 0;
|
||||
}
|
||||
|
||||
updateOptions(e: NotebookOptionsChangeEvent) {
|
||||
if (e.cellStatusBarVisibility || e.insertToolbarPosition || e.cellToolbarLocation) {
|
||||
const layoutConfiguration = this.viewContext.notebookOptions.getLayoutConfiguration();
|
||||
const { bottomToolbarGap } = this.viewContext.notebookOptions.computeBottomToolbarDimensions(this.viewType);
|
||||
|
||||
if (this.getEditState() === CellEditState.Editing) {
|
||||
this._updateTotalHeight(this._editorHeight
|
||||
+ layoutConfiguration.markdownCellTopMargin
|
||||
+ layoutConfiguration.markdownCellBottomMargin
|
||||
+ bottomToolbarGap
|
||||
+ this.viewContext.notebookOptions.computeStatusBarHeight());
|
||||
} else {
|
||||
// @rebornix
|
||||
// On file open, the previewHeight + bottomToolbarGap for a cell out of viewport can be 0
|
||||
// When it's 0, the list view will never try to render it anymore even if we scroll the cell into view.
|
||||
// Thus we make sure it's greater than 0
|
||||
this._updateTotalHeight(Math.max(1, this._previewHeight + bottomToolbarGap));
|
||||
}
|
||||
this._updateTotalHeight(this._computeTotalHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +171,7 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
// throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
triggerfoldingStateChange() {
|
||||
triggerFoldingStateChange() {
|
||||
this._onDidChangeState.fire({ foldingStateChanged: true });
|
||||
}
|
||||
|
||||
@@ -178,6 +183,7 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
|
||||
layoutChange(state: MarkdownCellLayoutChangeEvent) {
|
||||
// recompute
|
||||
const foldHintHeight = this._computeFoldHintHeight();
|
||||
if (!this.isInputCollapsed) {
|
||||
const editorWidth = state.outerWidth !== undefined
|
||||
? this.viewContext.notebookOptions.computeMarkdownCellEditorWidth(state.outerWidth)
|
||||
@@ -194,7 +200,8 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
editorHeight: this._editorHeight,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight, this.viewType),
|
||||
totalHeight,
|
||||
layoutState: CellLayoutState.Measured
|
||||
layoutState: CellLayoutState.Measured,
|
||||
foldHintHeight
|
||||
};
|
||||
} else {
|
||||
const editorWidth = state.outerWidth !== undefined
|
||||
@@ -211,7 +218,8 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
previewHeight: this._previewHeight,
|
||||
bottomToolbarOffset: this.viewContext.notebookOptions.computeBottomToolbarOffset(totalHeight, this.viewType),
|
||||
totalHeight,
|
||||
layoutState: CellLayoutState.Measured
|
||||
layoutState: CellLayoutState.Measured,
|
||||
foldHintHeight: 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -229,7 +237,8 @@ export class MarkupCellViewModel extends BaseCellViewModel implements ICellViewM
|
||||
bottomToolbarOffset: this._layoutInfo.bottomToolbarOffset,
|
||||
totalHeight: totalHeight,
|
||||
editorHeight: this._editorHeight,
|
||||
layoutState: CellLayoutState.FromCache
|
||||
layoutState: CellLayoutState.FromCache,
|
||||
foldHintHeight: this._layoutInfo.foldHintHeight
|
||||
};
|
||||
this.layoutChange({});
|
||||
}
|
||||
|
||||
@@ -455,6 +455,18 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
||||
return this._foldingRanges.isCollapsed(range) ? CellFoldingState.Collapsed : CellFoldingState.Expanded;
|
||||
}
|
||||
|
||||
getFoldedLength(index: number): number {
|
||||
if (!this._foldingRanges) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const range = this._foldingRanges.findRange(index + 1);
|
||||
const startIndex = this._foldingRanges.getStartLineNumber(range) - 1;
|
||||
const endIndex = this._foldingRanges.getEndLineNumber(range) - 1;
|
||||
|
||||
return endIndex - startIndex;
|
||||
}
|
||||
|
||||
updateFoldingRanges(ranges: FoldingRegions) {
|
||||
this._foldingRanges = ranges;
|
||||
let updateHiddenAreas = false;
|
||||
@@ -496,7 +508,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
||||
|
||||
this._viewCells.forEach(cell => {
|
||||
if (cell.cellKind === CellKind.Markup) {
|
||||
cell.triggerfoldingStateChange();
|
||||
cell.triggerFoldingStateChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ export interface NotebookLayoutConfiguration {
|
||||
markdownCellTopMargin: number;
|
||||
markdownCellBottomMargin: number;
|
||||
markdownPreviewPadding: number;
|
||||
markdownFoldHintHeight: number;
|
||||
// bottomToolbarGap: number;
|
||||
// bottomToolbarHeight: number;
|
||||
editorToolbarHeight: number;
|
||||
@@ -168,7 +169,8 @@ export class NotebookOptions extends Disposable {
|
||||
markupFontSize,
|
||||
editorOptionsCustomizations,
|
||||
focusIndicatorGap: 3,
|
||||
interactiveWindowCollapseCodeCells
|
||||
interactiveWindowCollapseCodeCells,
|
||||
markdownFoldHintHeight: 22
|
||||
};
|
||||
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
@@ -519,12 +521,12 @@ export class NotebookOptions extends Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
computeIndicatorPosition(totalHeight: number, viewType?: string) {
|
||||
computeIndicatorPosition(totalHeight: number, foldHintHeight: number, viewType?: string) {
|
||||
const { bottomToolbarGap } = this.computeBottomToolbarDimensions(viewType);
|
||||
|
||||
return {
|
||||
bottomIndicatorTop: totalHeight - bottomToolbarGap - this._layoutConfiguration.cellBottomMargin,
|
||||
verticalIndicatorHeight: totalHeight - bottomToolbarGap
|
||||
bottomIndicatorTop: totalHeight - bottomToolbarGap - this._layoutConfiguration.cellBottomMargin - foldHintHeight,
|
||||
verticalIndicatorHeight: totalHeight - bottomToolbarGap - foldHintHeight
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user