Make cell toolbar sticky scroll as well

pull/142883/head
Rob Lourens 2022-02-11 10:27:47 -08:00
parent 56c8ff832d
commit 06528bf65d
3 changed files with 44 additions and 25 deletions

View File

@ -23,6 +23,7 @@ import { ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/no
import { CellViewModelStateChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents';
import { CodiconActionViewItem } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellActionView';
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
import { registerStickyScroll } from 'vs/workbench/contrib/notebook/browser/view/cellParts/stickyScroll';
import { BaseCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon';
export class BetweenCellToolbar extends CellPart {
@ -112,12 +113,14 @@ export class CellTitleToolbarPart extends CellPart {
private readonly _onDidUpdateActions: Emitter<void> = this._register(new Emitter<void>());
readonly onDidUpdateActions: Event<void> = this._onDidUpdateActions.event;
private cellDisposable = this._register(new DisposableStore());
get hasActions(): boolean {
return this._hasActions;
}
constructor(
toolbarContainer: HTMLElement,
private readonly toolbarContainer: HTMLElement,
private readonly _rootClassDelegate: ICssClassDelegate,
toolbarId: MenuId,
private readonly _notebookEditor: INotebookEditorDelegate,
@ -139,6 +142,9 @@ export class CellTitleToolbarPart extends CellPart {
}
renderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void {
this.cellDisposable.clear();
this.cellDisposable.add(registerStickyScroll(this._notebookEditor, element, this.toolbarContainer, { extraOffset: 4, min: -14 }));
this.updateContext(<INotebookCellActionContext>{
ui: true,
cell: element,

View File

@ -7,7 +7,6 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { Action, IAction } from 'vs/base/common/actions';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { MarshalledId } from 'vs/base/common/marshalling';
import { clamp } from 'vs/base/common/numbers';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { localize } from 'vs/nls';
import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
@ -22,13 +21,14 @@ import { INotebookCellActionContext } from 'vs/workbench/contrib/notebook/browse
import { ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { CellViewModelStateChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents';
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
import { registerStickyScroll } from 'vs/workbench/contrib/notebook/browser/view/cellParts/stickyScroll';
import { BaseCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon';
import { NOTEBOOK_CELL_EXECUTION_STATE, NOTEBOOK_CELL_LIST_FOCUSED, NOTEBOOK_CELL_TYPE, NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/common/notebookContextKeys';
export class RunToolbar extends CellPart {
private toolbar!: ToolBar;
private currentElement: ICellViewModel | undefined;
private cellDisposable = this._register(new DisposableStore());
constructor(
readonly notebookEditor: INotebookEditorDelegate,
@ -42,8 +42,6 @@ export class RunToolbar extends CellPart {
) {
super();
this.notebookEditor.onDidScroll(() => this.updateForScroll());
const menu = this._register(menuService.createMenu(this.notebookEditor.creationOptions.menuIds.cellExecutePrimary!, contextKeyService));
this.createRunCellToolbar(runButtonContainer, cellContainer, contextKeyService);
const updateActions = () => {
@ -56,27 +54,10 @@ export class RunToolbar extends CellPart {
this._register(this.notebookEditor.notebookOptions.onDidChangeOptions(updateActions));
}
private updateForScroll() {
if (this.currentElement) {
if (this.currentElement.isInputCollapsed) {
this.runButtonContainer.style.top = '';
} else {
const scrollTop = this.notebookEditor.scrollTop;
const elementTop = this.notebookEditor.getAbsoluteTopOfElement(this.currentElement);
const scrollPadding = this.notebookEditor.notebookOptions.computeTopInsertToolbarHeight(this.notebookEditor.textModel?.viewType);
const diff = scrollTop - scrollPadding - elementTop;
const maxTop = this.currentElement.layoutInfo.editorHeight + this.currentElement.layoutInfo.statusBarHeight - 45; // subtract roughly the height of the execution order label plus padding
const top = maxTop > 20 ? // Don't move the run button if it can only move a very short distance
clamp(0, diff, maxTop) :
0;
this.runButtonContainer.style.top = `${top}px`;
}
}
}
renderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void {
this.currentElement = element;
this.updateForScroll();
this.cellDisposable.clear();
this.cellDisposable.add(registerStickyScroll(this.notebookEditor, element, this.runButtonContainer));
this.toolbar.context = <INotebookCellActionContext>{
ui: true,
cell: element,

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import { clamp } from 'vs/base/common/numbers';
import { ICellViewModel, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
export function registerStickyScroll(notebookEditor: INotebookEditor, cell: ICellViewModel, element: HTMLElement, opts?: { extraOffset?: number; min?: number }): IDisposable {
const extraOffset = opts?.extraOffset ?? 0;
const min = opts?.min ?? 0;
const updateForScroll = () => {
if (cell.isInputCollapsed) {
element.style.top = '';
} else {
const scrollPadding = notebookEditor.notebookOptions.computeTopInsertToolbarHeight(notebookEditor.textModel?.viewType);
const scrollTop = notebookEditor.scrollTop - scrollPadding;
const elementTop = notebookEditor.getAbsoluteTopOfElement(cell);
const diff = scrollTop - elementTop + extraOffset;
const maxTop = cell.layoutInfo.editorHeight + cell.layoutInfo.statusBarHeight - 45; // subtract roughly the height of the execution order label plus padding
const top = maxTop > 20 ? // Don't move the run button if it can only move a very short distance
clamp(min, diff, maxTop) :
0;
element.style.top = `${top}px`;
}
};
updateForScroll();
return notebookEditor.onDidScroll(() => updateForScroll());
}