Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try passing offset to editors on layout #164287

Merged
merged 3 commits into from
Nov 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/vs/base/browser/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,12 @@ export class Dimension implements IDimension {
}
}

export function getTopLeftOffset(element: HTMLElement): { left: number; top: number } {
export interface IDomPosition {
readonly left: number;
readonly top: number;
}

export function getTopLeftOffset(element: HTMLElement): IDomPosition {
// Adapted from WinJS.Utilities.getPosition
// and added borders to the mix

Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/browser/composite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IComposite, ICompositeControl } from 'vs/workbench/common/composite';
import { Event, Emitter } from 'vs/base/common/event';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IConstructorSignature, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { trackFocus, Dimension } from 'vs/base/browser/dom';
import { trackFocus, Dimension, IDomPosition } from 'vs/base/browser/dom';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Disposable } from 'vs/base/common/lifecycle';
import { assertIsDefined } from 'vs/base/common/types';
Expand Down Expand Up @@ -153,7 +153,7 @@ export abstract class Composite extends Component implements IComposite {
/**
* Layout the contents of this composite using the provided dimensions.
*/
abstract layout(dimension: Dimension): void;
abstract layout(dimension: Dimension, position?: IDomPosition): void;

/**
* Update the styles of the contents of this composite.
Expand Down
18 changes: 9 additions & 9 deletions src/vs/workbench/browser/parts/editor/editorGroupView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
import { Emitter, Relay } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor, asCSSUrl } from 'vs/base/browser/dom';
import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor, asCSSUrl, IDomNodePagePosition } from 'vs/base/browser/dom';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
Expand Down Expand Up @@ -111,7 +111,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private readonly model: EditorGroupModel;

private active: boolean | undefined;
private dimension: Dimension | undefined;
private lastLayout: IDomNodePagePosition | undefined;

private readonly scopedInstantiationService: IInstantiationService;

Expand Down Expand Up @@ -1891,25 +1891,25 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private _onDidChange = this._register(new Relay<{ width: number; height: number } | undefined>());
readonly onDidChange = this._onDidChange.event;

layout(width: number, height: number): void {
this.dimension = new Dimension(width, height);
layout(width: number, height: number, top: number, left: number): void {
this.lastLayout = { width, height, top, left };

// Layout the title area first to receive the size it occupies
const titleAreaSize = this.titleAreaControl.layout({
container: this.dimension,
container: new Dimension(width, height),
available: new Dimension(width, height - this.editorPane.minimumHeight)
});

// Pass the container width and remaining height to the editor layout
const editorHeight = Math.max(0, height - titleAreaSize.height);
this.editorContainer.style.height = `${editorHeight}px`;
this.editorPane.layout(new Dimension(width, editorHeight));
this.editorPane.layout({ width, height: editorHeight, top: top + titleAreaSize.height, left });
}

relayout(): void {
if (this.dimension) {
const { width, height } = this.dimension;
this.layout(width, height);
if (this.lastLayout) {
const { width, height, top, left } = this.lastLayout;
this.layout(width, height, top, left);
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/vs/workbench/browser/parts/editor/editorPanes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Severity from 'vs/base/common/severity';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { EditorExtensions, EditorInputCapabilities, IEditorOpenContext, IVisibleEditorPane } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { Dimension, show, hide } from 'vs/base/browser/dom';
import { Dimension, show, hide, IDomNodePagePosition } from 'vs/base/browser/dom';
import { Registry } from 'vs/platform/registry/common/platform';
import { IEditorPaneRegistry, IEditorPaneDescriptor } from 'vs/workbench/browser/editor';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
Expand Down Expand Up @@ -84,7 +84,7 @@ export class EditorPanes extends Disposable {
private readonly editorPanes: EditorPane[] = [];

private readonly activeEditorPaneDisposables = this._register(new DisposableStore());
private dimension: Dimension | undefined;
private pagePosition: IDomNodePagePosition | undefined;
private readonly editorOperation = this._register(new LongRunningOperation(this.editorProgressService));
private readonly editorPanesRegistry = Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane);

Expand Down Expand Up @@ -269,8 +269,8 @@ export class EditorPanes extends Disposable {
editorPane.setVisible(true, this.groupView);

// Layout
if (this.dimension) {
editorPane.layout(this.dimension);
if (this.pagePosition) {
editorPane.layout(new Dimension(this.pagePosition.width, this.pagePosition.height), { top: this.pagePosition.top, left: this.pagePosition.left });
}

return editorPane;
Expand Down Expand Up @@ -397,9 +397,9 @@ export class EditorPanes extends Disposable {
this._activeEditorPane?.setVisible(visible, this.groupView);
}

layout(dimension: Dimension): void {
this.dimension = dimension;
layout(pagePosition: IDomNodePagePosition): void {
this.pagePosition = pagePosition;

this._activeEditorPane?.layout(dimension);
this._activeEditorPane?.layout(new Dimension(pagePosition.width, pagePosition.height), pagePosition);
}
}
14 changes: 7 additions & 7 deletions src/vs/workbench/contrib/notebook/browser/notebookEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti
private readonly _widgetDisposableStore: DisposableStore = this._register(new DisposableStore());
private _widget: IBorrowValue<NotebookEditorWidget> = { value: undefined };
private _rootElement!: HTMLElement;
private _dimension?: DOM.Dimension;
private _pagePosition?: { readonly dimension: DOM.Dimension; readonly position: DOM.IDomPosition };

private readonly _inputListener = this._register(new MutableDisposable());

Expand Down Expand Up @@ -180,7 +180,7 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti
// we need to hide it before getting a new widget
this._widget.value?.onWillHide();

this._widget = <IBorrowValue<NotebookEditorWidget>>this._instantiationService.invokeFunction(this._notebookWidgetService.retrieveWidget, group, input, undefined, this._dimension);
this._widget = <IBorrowValue<NotebookEditorWidget>>this._instantiationService.invokeFunction(this._notebookWidgetService.retrieveWidget, group, input, undefined, this._pagePosition?.dimension);

if (this._rootElement && this._widget.value!.getDomNode()) {
this._rootElement.setAttribute('aria-flowto', this._widget.value!.getDomNode().id || '');
Expand All @@ -190,8 +190,8 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti
this._widgetDisposableStore.add(this._widget.value!.onDidChangeModel(() => this._onDidChangeModel.fire()));
this._widgetDisposableStore.add(this._widget.value!.onDidChangeActiveCell(() => this._onDidChangeSelection.fire({ reason: EditorPaneSelectionChangeReason.USER })));

if (this._dimension) {
this._widget.value!.layout(this._dimension, this._rootElement);
if (this._pagePosition) {
this._widget.value!.layout(this._pagePosition.dimension, this._rootElement, this._pagePosition.position);
}

// only now `setInput` and yield/await. this is AFTER the actual widget is ready. This is very important
Expand Down Expand Up @@ -395,10 +395,10 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti
return;
}

layout(dimension: DOM.Dimension): void {
layout(dimension: DOM.Dimension, position: DOM.IDomPosition): void {
this._rootElement.classList.toggle('mid-width', dimension.width < 1000 && dimension.width >= 600);
this._rootElement.classList.toggle('narrow-width', dimension.width < 600);
this._dimension = dimension;
this._pagePosition = { dimension, position };

if (!this._widget.value || !(this._input instanceof NotebookEditorInput)) {
return;
Expand All @@ -414,7 +414,7 @@ export class NotebookEditor extends EditorPane implements IEditorPaneWithSelecti
return;
}

this._widget.value.layout(this._dimension, this._rootElement);
this._widget.value.layout(dimension, this._rootElement, position);
}

//#endregion
Expand Down
48 changes: 33 additions & 15 deletions src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import { NotebookPerfMarks } from 'vs/workbench/contrib/notebook/common/notebook
import { BaseCellEditorOptions } from 'vs/workbench/contrib/notebook/browser/viewModel/cellEditorOptions';
import { ILogService } from 'vs/platform/log/common/log';
import { FloatingClickMenu } from 'vs/workbench/browser/codeeditor';
import { IDimension } from 'vs/editor/common/core/dimension';

const $ = DOM.$;

Expand Down Expand Up @@ -323,12 +324,12 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
}
}));

this._register(editorGroupsService.onDidScroll(() => {
this._register(editorGroupsService.onDidScroll(e => {
if (!this._shadowElement || !this._isVisible) {
return;
}

this.updateShadowElement(this._shadowElement);
this.updateShadowElement(this._shadowElement, this._dimension);
this.layoutContainerOverShadowElement(this._dimension);
}));

Expand Down Expand Up @@ -1691,7 +1692,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
return this._scrollBeyondLastLine && !this.isEmbedded;
}

layout(dimension: DOM.Dimension, shadowElement?: HTMLElement): void {
layout(dimension: DOM.Dimension, shadowElement?: HTMLElement, position?: DOM.IDomPosition): void {
if (!shadowElement && this._shadowElementViewInfo === null) {
this._dimension = dimension;
return;
Expand All @@ -1703,7 +1704,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
}

if (shadowElement) {
this.updateShadowElement(shadowElement);
this.updateShadowElement(shadowElement, dimension, position);
}

if (this._shadowElementViewInfo && this._shadowElementViewInfo.width <= 0 && this._shadowElementViewInfo.height <= 0) {
Expand Down Expand Up @@ -1732,7 +1733,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
this._overlayContainer.style.position = 'absolute';
this._overlayContainer.style.overflow = 'hidden';

this.layoutContainerOverShadowElement(dimension);
this.layoutContainerOverShadowElement(dimension, position);

if (this._webviewTransparentCover) {
this._webviewTransparentCover.style.height = `${dimension.height}px`;
Expand All @@ -1745,19 +1746,36 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
this._viewContext?.eventDispatcher.emit([new NotebookLayoutChangedEvent({ width: true, fontInfo: true }, this.getLayoutInfo())]);
}

private updateShadowElement(shadowElement: HTMLElement) {
const containerRect = shadowElement.getBoundingClientRect();

private updateShadowElement(shadowElement: HTMLElement, dimension?: IDimension, position?: DOM.IDomPosition) {
this._shadowElement = shadowElement;
this._shadowElementViewInfo = {
height: containerRect.height,
width: containerRect.width,
top: containerRect.top,
left: containerRect.left
};
if (dimension && position) {
this._shadowElementViewInfo = {
height: dimension.height,
width: dimension.width,
top: position.top,
left: position.left,
};
} else {
// We have to recompute position and size ourselves (which is slow)
const containerRect = shadowElement.getBoundingClientRect();
this._shadowElementViewInfo = {
height: containerRect.height,
width: containerRect.width,
top: containerRect.top,
left: containerRect.left
};
}
}

private layoutContainerOverShadowElement(dimension?: DOM.Dimension | null): void {
private layoutContainerOverShadowElement(dimension?: DOM.Dimension, position?: DOM.IDomPosition): void {
if (dimension && position) {
this._overlayContainer.style.top = `${position.top}px`;
this._overlayContainer.style.left = `${position.left}px`;
this._overlayContainer.style.width = `${dimension.width}px`;
this._overlayContainer.style.height = `${dimension.height}px`;
return;
}

if (!this._shadowElementViewInfo) {
return;
}
Expand Down