From 4140affee2cd98cd0d12f779c83f7072d368b421 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 23 Dec 2020 17:18:47 +0100 Subject: [PATCH] breadcrumbs picker must restore view state when being dismissed --- .../parts/editor/breadcrumbsControl.ts | 40 +++++-------------- .../browser/parts/editor/breadcrumbsPicker.ts | 5 +++ .../browser/outline/documentSymbolsOutline.ts | 14 +++++-- .../contrib/outline/notebookOutline.ts | 12 +++++- .../services/outline/browser/outline.ts | 1 + 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index f4012f58c25..07e91264dee 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -13,9 +13,7 @@ import { combinedDisposable, DisposableStore, toDisposable } from 'vs/base/commo import { extUri } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/breadcrumbscontrol'; -import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; import { Range } from 'vs/editor/common/core/range'; -import { ICodeEditorViewState } from 'vs/editor/common/editorCommon'; import { OutlineElement, OutlineModel } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { localize } from 'vs/nls'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; @@ -313,7 +311,7 @@ export class BreadcrumbsControl { this._breadcrumbsDisposables.add({ dispose: () => { if (this._breadcrumbsPickerShowing) { - this._contextViewService.hideContextView(this); + this._contextViewService.hideContextView({ source: this }); } } }); @@ -321,20 +319,6 @@ export class BreadcrumbsControl { return true; } - private _getActiveCodeEditor(): ICodeEditor | undefined { - if (!this._editorGroup.activeEditorPane) { - return undefined; - } - let control = this._editorGroup.activeEditorPane.getControl(); - let editor: ICodeEditor | undefined; - if (isCodeEditor(control)) { - editor = control as ICodeEditor; - } else if (isDiffEditor(control)) { - editor = control.getModifiedEditor(); - } - return editor; - } - private _onFocusEvent(event: IBreadcrumbsItemEvent): void { if (event.item && this._breadcrumbsPickerShowing) { this._breadcrumbsPickerIgnoreOnceItem = undefined; @@ -381,9 +365,8 @@ export class BreadcrumbsControl { // show picker let picker: BreadcrumbsPicker; let pickerAnchor: { x: number; y: number }; - let editor = this._getActiveCodeEditor(); - let editorDecorations: string[] = []; - let editorViewState: ICodeEditorViewState | undefined; + + interface IHideData { didPick?: boolean, source?: BreadcrumbsControl } this._contextViewService.showContextView({ render: (parent: HTMLElement) => { @@ -393,13 +376,13 @@ export class BreadcrumbsControl { picker = this._instantiationService.createInstance(BreadcrumbsOutlinePicker, parent, event.item.model.resource); } - let selectListener = picker.onDidPickElement(() => this._contextViewService.hideContextView(this)); - let zoomListener = onDidChangeZoomLevel(() => this._contextViewService.hideContextView(this)); + let selectListener = picker.onDidPickElement(() => this._contextViewService.hideContextView({ source: this, didPick: true })); + let zoomListener = onDidChangeZoomLevel(() => this._contextViewService.hideContextView({ source: this })); let focusTracker = dom.trackFocus(parent); let blurListener = focusTracker.onDidBlur(() => { this._breadcrumbsPickerIgnoreOnceItem = this._widget.isDOMFocused() ? event.item : undefined; - this._contextViewService.hideContextView(this); + this._contextViewService.hideContextView({ source: this }); }); this._breadcrumbsPickerShowing = true; @@ -446,16 +429,13 @@ export class BreadcrumbsControl { } return pickerAnchor; }, - onHide: (data) => { - if (editor) { - editor.deltaDecorations(editorDecorations, []); - if (editorViewState) { - editor.restoreViewState(editorViewState); - } + onHide: (data?: IHideData) => { + if (!data?.didPick) { + picker.restoreViewState(); } this._breadcrumbsPickerShowing = false; this._updateCkBreadcrumbsActive(); - if (data === this) { + if (data?.source === this) { this._widget.setFocused(undefined); this._widget.setSelection(undefined); } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 821b64e0ff8..47379b83dc2 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -149,6 +149,8 @@ export abstract class BreadcrumbsPicker { this._tree.layout(treeHeight, this._layoutInfo.width); } + restoreViewState(): void { } + protected abstract _setInput(element: FileElement | OutlineElement2): Promise; protected abstract _createTree(container: HTMLElement, input: any): Tree; protected abstract _previewElement(element: any): IDisposable; @@ -493,6 +495,9 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { protected _setInput(input: OutlineElement2): Promise { + const viewState = input.outline.captureViewState(); + this.restoreViewState = () => { viewState.dispose(); }; + const tree = this._tree as WorkbenchDataTree, any, FuzzyScore>; tree.setInput(input.outline); diff --git a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts index 105e6a544f4..d5ca15d2b42 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts @@ -265,10 +265,7 @@ class DocumentSymbolsOutline implements IOutline { if (!(entry instanceof OutlineElement)) { return Disposable.None; } - // todo@jrieken - // if (!editorViewState) { - // editorViewState = withNullAsUndefined(editor.saveViewState()); - // } + const { symbol } = entry; this._editor.revealRangeInCenterIfOutsideViewport(symbol.range, ScrollType.Smooth); const ids = this._editor.deltaDecorations([], [{ @@ -281,6 +278,15 @@ class DocumentSymbolsOutline implements IOutline { return toDisposable(() => this._editor.deltaDecorations(ids, [])); } + captureViewState(): IDisposable { + const viewState = this._editor.saveViewState(); + return toDisposable(() => { + if (viewState) { + this._editor.restoreViewState(viewState); + } + }); + } + private async _createOutline(contentChangeEvent?: IModelContentChangedEvent): Promise { this._outlineDisposables.clear(); diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts index 65ab863017d..1af4d10838f 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts @@ -482,9 +482,17 @@ class NotebookCellOutline implements IOutline { } - getParent(_entry: OutlineEntry): OutlineEntry | undefined { - return undefined; + captureViewState(): IDisposable { + const widget = this._editor.getControl(); + let viewState = widget?.getEditorViewState(); + return toDisposable(() => { + if (viewState) { + widget?.restoreListViewState(viewState); + + } + }); } + } class NotebookOutlineCreator implements IOutlineCreator { diff --git a/src/vs/workbench/services/outline/browser/outline.ts b/src/vs/workbench/services/outline/browser/outline.ts index 70869b095e5..2aad1e9abd9 100644 --- a/src/vs/workbench/services/outline/browser/outline.ts +++ b/src/vs/workbench/services/outline/browser/outline.ts @@ -82,5 +82,6 @@ export interface IOutline { reveal(entry: E, options: IEditorOptions, sideBySide: boolean): Promise | void; preview(entry: E): IDisposable; + captureViewState(): IDisposable; dispose(): void; } -- GitLab