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

Centered editor layout #52064

Merged
merged 12 commits into from
Jun 19, 2018
95 changes: 95 additions & 0 deletions src/vs/base/browser/ui/centered/centeredViewLayout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { SplitView, Sizing, Orientation, ISplitViewStyles, IView as ISplitViewView } from 'vs/base/browser/ui/splitview/splitview';
import { $ } from 'vs/base/browser/dom';
import { Event } from 'vs/base/common/event';
import { IView } from 'vs/base/browser/ui/grid/gridview';

export class CenteredViewLayout {

private splitView: SplitView;
private element: HTMLElement;
private height: number;
private style: ISplitViewStyles;

constructor(private container: HTMLElement, private view: IView) {
this.container.appendChild(this.view.element);
}

layout(width: number, height: number): void {
this.height = height;
if (this.splitView) {
this.splitView.layout(width);
} else {
this.view.layout(width, height);
}
}

isActive(): boolean {
return !!this.splitView;
}

styles(style: ISplitViewStyles): void {
this.style = style;
if (this.splitView) {
this.splitView.style(this.style);
}
}

resetView(view: IView): void {
this.view = view;
if (this.splitView) {
this.splitView.removeView(1);
this.splitView.addView(this.getView(), Sizing.Distribute, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is splitview.distributeViewSizes().

}
}

private getView(): ISplitViewView {
return {
element: this.view.element,
maximumSize: this.view.maximumWidth,
minimumSize: this.view.minimumWidth,
onDidChange: Event.None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should expose this.view.onDidChange here.

layout: size => this.view.layout(size, this.height)
};
}

activate(active: boolean): void {
if (active) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should still make a if (active === !!this.splitview) { return; }, so you don't get any NPEs.

this.element = $('.centered-view-layout');
this.container.removeChild(this.view.element);
this.container.appendChild(this.element);
this.splitView = new SplitView(this.element, {
inverseAltBehavior: true,
orientation: Orientation.HORIZONTAL,
styles: this.style
});

const getEmptyView = () => ({
element: $('.centered-layout-margin'),
layout: () => undefined,
minimumSize: 20,
maximumSize: Number.POSITIVE_INFINITY,
onDidChange: Event.None
});

this.splitView.addView(getEmptyView(), Sizing.Distribute);
this.splitView.addView(this.getView(), Sizing.Distribute);
this.splitView.addView(getEmptyView(), Sizing.Distribute);
} else {
this.splitView.dispose();
this.splitView = undefined;
this.container.removeChild(this.element);
this.container.appendChild(this.view.element);
}
}

dispose(): void {
if (this.splitView) {
this.splitView.dispose();
}
}
}
37 changes: 33 additions & 4 deletions src/vs/workbench/browser/parts/editor/editorPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/
import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTarget';
import { localize } from 'vs/nls';
import { Color } from 'vs/base/common/color';
import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout';
import { IView } from 'vs/base/browser/ui/grid/gridview';

interface IEditorPartUIState {
serializedGrid: ISerializedGrid;
Expand Down Expand Up @@ -90,6 +92,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
private whenRestoredComplete: TValueCallback<void>;

private previousUIState: IEditorPartUIState;
private centeredViewLayout: CenteredViewLayout;

constructor(
id: string,
Expand Down Expand Up @@ -699,7 +702,9 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
protected updateStyles(): void {
this.container.style.backgroundColor = this.getColor(editorBackground);

this.gridWidget.style({ separatorBorder: this.gridSeparatorBorder });
const separatorBorderStyle = { separatorBorder: this.gridSeparatorBorder };
this.gridWidget.style(separatorBorderStyle);
this.centeredViewLayout.styles(separatorBorderStyle);
}

createContentArea(parent: HTMLElement): HTMLElement {
Expand All @@ -709,15 +714,36 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
addClass(this.container, 'content');
parent.appendChild(this.container);

// Grid control
// Grid control with center layout
this.doCreateGridControl();
this.centeredViewLayout = new CenteredViewLayout(this.container, this.getGridAsView());

// Drop support
this._register(this.instantiationService.createInstance(EditorDropTarget, this, this.container));

return this.container;
}

private getGridAsView(): IView {
return {
element: this.gridWidget.element,
layout: (width, height) => this.gridWidget.layout(width, height),
minimumWidth: this.gridWidget.minimumWidth,
maximumWidth: this.gridWidget.maximumWidth,
minimumHeight: this.gridWidget.minimumHeight,
maximumHeight: this.gridWidget.minimumHeight,
onDidChange: Event.None
};
}

centerLayout(active: boolean): void {
this.centeredViewLayout.activate(active);
}

isLayoutCentered(): boolean {
return this.centeredViewLayout.isActive();
}

private doCreateGridControl(): void {

// Grid Widget (with previous UI state)
Expand Down Expand Up @@ -809,7 +835,9 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
this.gridWidget = gridWidget;

if (gridWidget) {
this.container.appendChild(gridWidget.element);
if (this.centeredViewLayout) {
this.centeredViewLayout.resetView(this.getGridAsView());
}
this._onDidSizeConstraintsChange.input = gridWidget.onDidChange;
}

Expand Down Expand Up @@ -967,7 +995,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor

// Layout Grid
try {
this.gridWidget.layout(this.dimension.width, this.dimension.height);
this.centeredViewLayout.layout(this.dimension.width, this.dimension.height);
} catch (error) {
this.gridError(error);
}
Expand Down Expand Up @@ -1009,6 +1037,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
if (this.gridWidget) {
this.gridWidget.dispose();
}
this.centeredViewLayout.dispose();

super.dispose();
}
Expand Down
41 changes: 6 additions & 35 deletions src/vs/workbench/electron-browser/workbench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { PreferencesService } from 'vs/workbench/services/preferences/browser/preferencesService';
import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService, GroupDirection, preferredSideBySideGroupDirection, GroupOrientation } from 'vs/workbench/services/group/common/editorGroupsService';
import { IEditorGroupsService, GroupDirection, preferredSideBySideGroupDirection } from 'vs/workbench/services/group/common/editorGroupsService';
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IExtensionUrlHandler, ExtensionUrlHandler } from 'vs/platform/url/electron-browser/inactiveExtensionUrlHandler';
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
Expand Down Expand Up @@ -227,7 +227,6 @@ export class Workbench extends Disposable implements IPartService {
private panelHidden: boolean;
private menubarHidden: boolean;
private zenMode: IZenMode;
private centeredEditorLayoutActive: boolean;
private fontAliasing: FontAliasingOption;
private hasInitialFilesToOpen: boolean;

Expand Down Expand Up @@ -714,7 +713,7 @@ export class Workbench extends Disposable implements IPartService {

// Restore Forced Editor Center Mode
if (this.storageService.getBoolean(Workbench.centeredEditorLayoutActiveStorageKey, StorageScope.WORKSPACE, false)) {
this.centeredEditorLayoutActive = true;
this.centerEditorLayout(true);
}

const onRestored = (error?: Error): IWorkbenchStartedInfo => {
Expand Down Expand Up @@ -872,9 +871,6 @@ export class Workbench extends Disposable implements IPartService {
wasPanelVisible: false,
transitionDisposeables: []
};

// Centered Editor Layout
this.centeredEditorLayoutActive = false;
}

private setPanelPositionFromStorageOrConfig() {
Expand Down Expand Up @@ -1293,39 +1289,14 @@ export class Workbench extends Disposable implements IPartService {
}

isEditorLayoutCentered(): boolean {
return this.centeredEditorLayoutActive;
return this.editorPart.isLayoutCentered();
}

// TODO@ben support centered editor layout using empty groups or not? functionality missing:
// - resize sashes left and right in sync
// - IEditorInput.supportsCenteredEditorLayout() no longer supported
// - should we just allow to enter layout even if groups > 1? what does it then mean to be
// actively in centered editor layout though?
centerEditorLayout(active: boolean, skipLayout?: boolean): void {
this.centeredEditorLayoutActive = active;
this.storageService.store(Workbench.centeredEditorLayoutActiveStorageKey, this.centeredEditorLayoutActive, StorageScope.WORKSPACE);
this.storageService.store(Workbench.centeredEditorLayoutActiveStorageKey, active, StorageScope.WORKSPACE);

// Enter Centered Editor Layout
if (active) {
if (this.editorGroupService.count === 1) {
const activeGroup = this.editorGroupService.activeGroup;
this.editorGroupService.addGroup(activeGroup, GroupDirection.LEFT);
this.editorGroupService.addGroup(activeGroup, GroupDirection.RIGHT);

this.editorGroupService.applyLayout({ groups: [{ size: 0.2 }, { size: 0.6 }, { size: 0.2 }], orientation: GroupOrientation.HORIZONTAL });
}
}

// Leave Centered Editor Layout
else {
if (this.editorGroupService.count === 3) {
this.editorGroupService.groups.forEach(group => {
if (group.count === 0) {
this.editorGroupService.removeGroup(group);
}
});
}
}
this.editorPart.centerLayout(active);

if (!skipLayout) {
this.layout();
Expand Down Expand Up @@ -1514,4 +1485,4 @@ export class Workbench extends Disposable implements IPartService {
}

//#endregion
}
}