Skip to content

Commit

Permalink
editors - add action to toggle editor group maximize (fix #72968)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Aug 9, 2019
1 parent b092c9a commit 642d3a0
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/vs/workbench/browser/parts/editor/editor.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
SplitEditorUpAction, SplitEditorDownAction, MoveEditorToLeftGroupAction, MoveEditorToRightGroupAction, MoveEditorToAboveGroupAction, MoveEditorToBelowGroupAction, CloseAllEditorGroupsAction,
JoinAllGroupsAction, FocusLeftGroup, FocusAboveGroup, FocusRightGroup, FocusBelowGroup, EditorLayoutSingleAction, EditorLayoutTwoColumnsAction, EditorLayoutThreeColumnsAction, EditorLayoutTwoByTwoGridAction,
EditorLayoutTwoRowsAction, EditorLayoutThreeRowsAction, EditorLayoutTwoColumnsBottomAction, EditorLayoutTwoRowsRightAction, NewEditorGroupLeftAction, NewEditorGroupRightAction,
NewEditorGroupAboveAction, NewEditorGroupBelowAction, SplitEditorOrthogonalAction, CloseEditorInAllGroupsAction, NavigateToLastEditLocationAction
NewEditorGroupAboveAction, NewEditorGroupBelowAction, SplitEditorOrthogonalAction, CloseEditorInAllGroupsAction, NavigateToLastEditLocationAction, ToggleGroupSizesAction
} from 'vs/workbench/browser/parts/editor/editorActions';
import * as editorCommands from 'vs/workbench/browser/parts/editor/editorCommands';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
Expand Down Expand Up @@ -334,6 +334,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(JoinTwoGroupsAction, J
registry.registerWorkbenchAction(new SyncActionDescriptor(JoinAllGroupsAction, JoinAllGroupsAction.ID, JoinAllGroupsAction.LABEL), 'View: Join All Editor Groups', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(NavigateBetweenGroupsAction, NavigateBetweenGroupsAction.ID, NavigateBetweenGroupsAction.LABEL), 'View: Navigate Between Editor Groups', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ResetGroupSizesAction, ResetGroupSizesAction.ID, ResetGroupSizesAction.LABEL), 'View: Reset Editor Group Sizes', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleGroupSizesAction, ToggleGroupSizesAction.ID, ToggleGroupSizesAction.LABEL), 'View: Toggle Editor Group Sizes', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(MaximizeGroupAction, MaximizeGroupAction.ID, MaximizeGroupAction.LABEL), 'View: Maximize Editor Group and Hide Side Bar', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(MinimizeOtherGroupsAction, MinimizeOtherGroupsAction.ID, MinimizeOtherGroupsAction.LABEL), 'View: Maximize Editor Group', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(MoveEditorLeftInGroupAction, MoveEditorLeftInGroupAction.ID, MoveEditorLeftInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageUp, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow) } }), 'View: Move Editor Left', category);
Expand Down
4 changes: 3 additions & 1 deletion src/vs/workbench/browser/parts/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,16 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito
readonly whenRestored: Promise<void>;
readonly disposed: boolean;

readonly isEmpty: boolean;
readonly isMinimized: boolean;

readonly onDidFocus: Event<void>;
readonly onWillDispose: Event<void>;
readonly onWillOpenEditor: Event<IEditorOpeningEvent>;
readonly onDidOpenEditorFail: Event<IEditorInput>;
readonly onWillCloseEditor: Event<IEditorCloseEvent>;
readonly onDidCloseEditor: Event<IEditorCloseEvent>;

isEmpty(): boolean;
setActive(isActive: boolean): void;

notifyIndexChanged(newIndex: number): void;
Expand Down
16 changes: 16 additions & 0 deletions src/vs/workbench/browser/parts/editor/editorActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,22 @@ export class ResetGroupSizesAction extends Action {
}
}

export class ToggleGroupSizesAction extends Action {

static readonly ID = 'workbench.action.toggleEditorWidths';
static readonly LABEL = nls.localize('toggleEditorWidths', "Toggle Editor Group Sizes");

constructor(id: string, label: string, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService) {
super(id, label);
}

run(): Promise<any> {
this.editorGroupService.arrangeGroups(GroupsArrangement.TOGGLE);

return Promise.resolve(false);
}
}

export class MaximizeGroupAction extends Action {

static readonly ID = 'workbench.action.maximizeEditor';
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/editor/editorDropTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ class DropOverlay extends Themable {
}

private getOverlayOffsetHeight(): number {
if (!this.groupView.isEmpty() && this.accessor.partOptions.showTabs) {
if (!this.groupView.isEmpty && this.accessor.partOptions.showTabs) {
return EDITOR_TITLE_HEIGHT; // show overlay below title if group shows tabs
}

Expand Down
32 changes: 20 additions & 12 deletions src/vs/workbench/browser/parts/editor/editorGroupView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {

// Open new file via doubleclick on empty container
this._register(addDisposableListener(this.element, EventType.DBLCLICK, e => {
if (this.isEmpty()) {
if (this.isEmpty) {
EventHelper.stop(e);

this.openEditor(this.untitledEditorService.createOrGet(), EditorOptions.create({ pinned: true }));
Expand All @@ -259,7 +259,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {

// Close empty editor group via middle mouse click
this._register(addDisposableListener(this.element, EventType.MOUSE_UP, e => {
if (this.isEmpty() && e.button === 1 /* Middle Button */) {
if (this.isEmpty && e.button === 1 /* Middle Button */) {
EventHelper.stop(e);

this.accessor.removeGroup(this);
Expand Down Expand Up @@ -308,7 +308,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
}

private onShowContainerContextMenu(menu: IMenu, e?: MouseEvent): void {
if (!this.isEmpty()) {
if (!this.isEmpty) {
return; // only for empty editor groups
}

Expand Down Expand Up @@ -339,7 +339,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
// Container
const containerFocusTracker = this._register(trackFocus(this.element));
this._register(containerFocusTracker.onDidFocus(() => {
if (this.isEmpty()) {
if (this.isEmpty) {
this._onDidFocus.fire(); // only when empty to prevent accident focus
}
}));
Expand Down Expand Up @@ -381,7 +381,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private updateContainer(): void {

// Empty Container: add some empty container attributes
if (this.isEmpty()) {
if (this.isEmpty) {
addClass(this.element, 'empty');
this.element.tabIndex = 0;
this.element.setAttribute('aria-label', localize('emptyEditorGroup', "{0} (empty)", this.label));
Expand Down Expand Up @@ -672,6 +672,18 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
return this._whenRestored;
}

get isEmpty(): boolean {
return this._group.count === 0;
}

get isMinimized(): boolean {
if (!this.dimension) {
return false;
}

return this.dimension.width === this.minimumWidth || this.dimension.height === this.minimumHeight;
}

notifyIndexChanged(newIndex: number): void {
if (this._index !== newIndex) {
this._index = newIndex;
Expand All @@ -696,10 +708,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_ACTIVE });
}

isEmpty(): boolean {
return this._group.count === 0;
}

//#endregion

//#region IEditorGroup
Expand Down Expand Up @@ -1224,7 +1232,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
//#region closeEditors()

async closeEditors(args: EditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise<void> {
if (this.isEmpty()) {
if (this.isEmpty) {
return;
}

Expand Down Expand Up @@ -1296,7 +1304,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
//#region closeAllEditors()

async closeAllEditors(): Promise<void> {
if (this.isEmpty()) {
if (this.isEmpty) {

// If the group is empty and the request is to close all editors, we still close
// the editor group is the related setting to close empty groups is enabled for
Expand Down Expand Up @@ -1408,7 +1416,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
//#region Themable

protected updateStyles(): void {
const isEmpty = this.isEmpty();
const isEmpty = this.isEmpty;

// Container
if (isEmpty) {
Expand Down
41 changes: 31 additions & 10 deletions src/vs/workbench/browser/parts/editor/editorPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,15 +346,36 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
return; // we have not been created yet
}

// Even all group sizes
if (arrangement === GroupsArrangement.EVEN) {
this.gridWidget.distributeViewSizes();
switch (arrangement) {
case GroupsArrangement.EVEN:
this.gridWidget.distributeViewSizes();
break;
case GroupsArrangement.MINIMIZE_OTHERS:
this.gridWidget.maximizeViewSize(this.activeGroup);
break;
case GroupsArrangement.TOGGLE:
if (this.isGroupMaximized(this.activeGroup)) {
this.arrangeGroups(GroupsArrangement.EVEN);
} else {
this.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS);
}

break;
}
}

// Maximize the current active group
else {
this.gridWidget.maximizeViewSize(this.activeGroup);
private isGroupMaximized(targetGroup: IEditorGroupView): boolean {
for (const group of this.groups) {
if (group === targetGroup) {
continue; // ignore target group
}

if (!group.isMinimized) {
return false; // target cannot be maximized if one group is not minimized
}
}

return true;
}

setGroupOrientation(orientation: GroupOrientation): void {
Expand Down Expand Up @@ -604,7 +625,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
}

// Remove empty group
if (groupView.isEmpty()) {
if (groupView.isEmpty) {
return this.doRemoveEmptyGroup(groupView);
}

Expand Down Expand Up @@ -722,7 +743,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
});

// Remove source if the view is now empty and not already removed
if (sourceView.isEmpty() && !sourceView.disposed /* could have been disposed already via workbench.editor.closeEmptyGroups setting */) {
if (sourceView.isEmpty && !sourceView.disposed /* could have been disposed already via workbench.editor.closeEmptyGroups setting */) {
this.removeGroup(sourceView);
}

Expand Down Expand Up @@ -925,7 +946,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
}

private isEmpty(): boolean {
return this.groupViews.size === 1 && this._activeGroup.isEmpty();
return this.groupViews.size === 1 && this._activeGroup.isEmpty;
}

layout(width: number, height: number): void {
Expand Down Expand Up @@ -957,7 +978,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
mostRecentActiveGroups: this.mostRecentActiveGroups
};

if (this.isEmpty()) {
if (this.isEmpty) {
delete this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY];
} else {
this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY] = uiState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ export const enum GroupsArrangement {
/**
* Size all groups evenly.
*/
EVEN
EVEN,

/**
* Will behave like MINIMIZE_OTHERS if the active
* group is not already maximized and EVEN otherwise
*/
TOGGLE
}

export interface GroupLayoutArgument {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ suite('EditorGroupsService', () => {
test('editor basics', async function () {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

await part.whenRestored;

Expand Down Expand Up @@ -437,7 +437,7 @@ suite('EditorGroupsService', () => {
assert.equal(group.isActive(inputInactive), false);
assert.equal(group.isOpened(input), true);
assert.equal(group.isOpened(inputInactive), true);
assert.equal(group.isEmpty(), false);
assert.equal(group.isEmpty, false);
assert.equal(group.count, 2);
assert.equal(editorWillOpenCounter, 2);
assert.equal(editorDidOpenCounter, 2);
Expand Down Expand Up @@ -486,7 +486,7 @@ suite('EditorGroupsService', () => {
test('openEditors / closeEditors', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input = new TestEditorInput(URI.file('foo/bar'));
const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive'));
Expand All @@ -497,14 +497,14 @@ suite('EditorGroupsService', () => {
assert.equal(group.getEditor(1), inputInactive);

await group.closeEditors([input, inputInactive]);
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);
part.dispose();
});

test('closeEditors (except one)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input1 = new TestEditorInput(URI.file('foo/bar1'));
const input2 = new TestEditorInput(URI.file('foo/bar2'));
Expand All @@ -525,7 +525,7 @@ suite('EditorGroupsService', () => {
test('closeEditors (saved only)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input1 = new TestEditorInput(URI.file('foo/bar1'));
const input2 = new TestEditorInput(URI.file('foo/bar2'));
Expand All @@ -545,7 +545,7 @@ suite('EditorGroupsService', () => {
test('closeEditors (direction: right)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input1 = new TestEditorInput(URI.file('foo/bar1'));
const input2 = new TestEditorInput(URI.file('foo/bar2'));
Expand All @@ -567,7 +567,7 @@ suite('EditorGroupsService', () => {
test('closeEditors (direction: left)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input1 = new TestEditorInput(URI.file('foo/bar1'));
const input2 = new TestEditorInput(URI.file('foo/bar2'));
Expand All @@ -589,7 +589,7 @@ suite('EditorGroupsService', () => {
test('closeAllEditors', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input = new TestEditorInput(URI.file('foo/bar'));
const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive'));
Expand All @@ -600,14 +600,14 @@ suite('EditorGroupsService', () => {
assert.equal(group.getEditor(1), inputInactive);

await group.closeAllEditors();
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);
part.dispose();
});

test('moveEditor (same group)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input = new TestEditorInput(URI.file('foo/bar'));
const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive'));
Expand Down Expand Up @@ -635,7 +635,7 @@ suite('EditorGroupsService', () => {
test('moveEditor (across groups)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const rightGroup = part.addGroup(group, GroupDirection.RIGHT);

Expand All @@ -657,7 +657,7 @@ suite('EditorGroupsService', () => {
test('copyEditor (across groups)', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const rightGroup = part.addGroup(group, GroupDirection.RIGHT);

Expand All @@ -680,7 +680,7 @@ suite('EditorGroupsService', () => {
test('replaceEditors', async () => {
const part = createPart();
const group = part.activeGroup;
assert.equal(group.isEmpty(), true);
assert.equal(group.isEmpty, true);

const input = new TestEditorInput(URI.file('foo/bar'));
const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive'));
Expand Down

0 comments on commit 642d3a0

Please sign in to comment.