Skip to content

Commit

Permalink
#26948 Remember the view collapsible state and size
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed May 22, 2017
1 parent e5983e6 commit 6e43693
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 19 deletions.
5 changes: 5 additions & 0 deletions src/vs/base/browser/ui/splitview/splitview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,11 @@ export class SplitView implements
throw new Error('Initial weight must be a positive number.');
}

/**
* Reset size to null. This will layout newly added viees to initial weights.
*/
this.size = null;

let viewCount = this.views.length;

// Create view container
Expand Down
6 changes: 4 additions & 2 deletions src/vs/workbench/browser/viewlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ export class CollapseAction extends Action {
}

export interface IViewletView extends IView, IThemable {
id?: string;
create(): TPromise<void>;
setVisible(visible: boolean): TPromise<void>;
getActions(): IAction[];
Expand Down Expand Up @@ -449,10 +450,11 @@ export abstract class CollapsibleViewletView extends CollapsibleView implements
protected messageService: IMessageService,
protected keybindingService: IKeybindingService,
protected contextMenuService: IContextMenuService,
headerSize?: number
headerSize?: number,
minimumSize?: number
) {
super({
minimumSize: 5 * 22,
minimumSize: minimumSize === void 0 ? 5 * 22 : minimumSize,
initialState: collapsed ? CollapsibleState.COLLAPSED : CollapsibleState.EXPANDED,
ariaHeaderLabel: viewName,
headerSize
Expand Down
46 changes: 39 additions & 7 deletions src/vs/workbench/parts/files/browser/explorerViewlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { ActionRunner, FileViewletState } from 'vs/workbench/parts/files/browser
import { ExplorerView } from 'vs/workbench/parts/files/browser/views/explorerView';
import { EmptyView } from 'vs/workbench/parts/files/browser/views/emptyView';
import { OpenEditorsView } from 'vs/workbench/parts/files/browser/views/openEditorsView';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
Expand All @@ -34,7 +34,15 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { attachHeaderViewStyler } from 'vs/platform/theme/common/styler';
import { ViewsRegistry, ViewLocation, IViewDescriptor } from 'vs/workbench/parts/views/browser/views';

interface IViewState {
collapsed: boolean;
size: number;
}

export class ExplorerViewlet extends Viewlet {

private static EXPLORER_VIEWS_STATE = 'workbench.explorer.views.state';

private viewletContainer: Builder;
private splitView: SplitView;
private views: IViewletView[];
Expand Down Expand Up @@ -119,21 +127,24 @@ export class ExplorerViewlet extends Viewlet {
this.views.push(this.openEditorsView);
}

const viewsState = JSON.parse(this.storageService.get(ExplorerViewlet.EXPLORER_VIEWS_STATE, this.contextService.hasWorkspace() ? StorageScope.WORKSPACE : StorageScope.GLOBAL, '{}'));

// Explorer view
this.views.push(this.createExplorerOrEmptyView());
this.views.push(this.createExplorerOrEmptyView(viewsState));

// custom views
for (const view of customViews) {
this.views.push(this.instantiationService.createInstance(view.ctor, view.id, {
name: view.name,
actionRunner: this.getActionRunner(),
collapsed: viewsState[view.id] ? (<IViewState>viewsState[view.id]).collapsed : true
}));
}

for (let i = 0; i < this.views.length; i++) {
const view = this.views[i];
attachHeaderViewStyler(view, this.themeService, { noContrastBorder: i === 0 });
this.splitView.addView(view);
this.splitView.addView(view, viewsState[view.id] ? (<IViewState>viewsState[view.id]).size : void 0);
}

this.lastFocusedView = this.explorerView;
Expand Down Expand Up @@ -195,15 +206,17 @@ export class ExplorerViewlet extends Viewlet {
}
const views = [];

const viewsState = JSON.parse(this.storageService.get(ExplorerViewlet.EXPLORER_VIEWS_STATE, this.contextService.hasWorkspace() ? StorageScope.WORKSPACE : StorageScope.GLOBAL, '{}'));
for (const viewDescrirptor of viewDescriptors) {
const view = this.instantiationService.createInstance(viewDescrirptor.ctor, viewDescrirptor.id, {
name: viewDescrirptor.name,
actionRunner: this.getActionRunner(),
collapsed: viewsState[viewDescrirptor.id] ? (<IViewState>viewsState[viewDescrirptor.id]).collapsed : true
});
views.push(view);
this.views.push(view);
attachHeaderViewStyler(view, this.themeService);
this.splitView.addView(view);
this.splitView.addView(view, viewsState[view.id] ? (<IViewState>viewsState[view.id]).size : void 0);
}

TPromise.join(views.map(view => view.create())).then(() => void 0).then(() => {
Expand All @@ -227,7 +240,7 @@ export class ExplorerViewlet extends Viewlet {
}
}

private createExplorerOrEmptyView(): IViewletView {
private createExplorerOrEmptyView(viewsState: any): IViewletView {
let explorerOrEmptyView: ExplorerView | EmptyView;

// With a Workspace
Expand Down Expand Up @@ -264,12 +277,18 @@ export class ExplorerViewlet extends Viewlet {
});

const explorerInstantiator = this.instantiationService.createChild(new ServiceCollection([IWorkbenchEditorService, delegatingEditorService]));
this.explorerView = explorerOrEmptyView = explorerInstantiator.createInstance(ExplorerView, this.viewletState, this.getActionRunner(), this.viewletSettings, void 0);
this.explorerView = explorerOrEmptyView = explorerInstantiator.createInstance(ExplorerView, this.viewletState, {
collapsed: viewsState[ExplorerView.ID] ? (<IViewState>viewsState[ExplorerView.ID]).collapsed : false,
actionRunner: this.getActionRunner()
}, this.viewletSettings, void 0);
}

// No workspace
else {
this.emptyView = explorerOrEmptyView = this.instantiationService.createInstance(EmptyView, this.getActionRunner());
this.emptyView = explorerOrEmptyView = this.instantiationService.createInstance(EmptyView, {
collapsed: viewsState[EmptyView.ID] ? (<IViewState>viewsState[EmptyView.ID]).collapsed : false,
actionRunner: this.getActionRunner()
});
}

return explorerOrEmptyView;
Expand Down Expand Up @@ -376,11 +395,24 @@ export class ExplorerViewlet extends Viewlet {
}

public shutdown(): void {
const viewletState = this.views.reduce((result, view) => {
result[view.id] = this.getViewState(view);
return result;
}, {});
this.storageService.store(ExplorerViewlet.EXPLORER_VIEWS_STATE, JSON.stringify(viewletState), this.contextService.hasWorkspace() ? StorageScope.WORKSPACE : StorageScope.GLOBAL);

this.views.forEach((view) => view.shutdown());

super.shutdown();
}

private getViewState(view: IViewletView): IViewState {
return {
collapsed: !view.isExpanded(),
size: view.size > 0 ? view.size : void 0
};
}

public dispose(): void {

for (const view of this.views) {
Expand Down
18 changes: 13 additions & 5 deletions src/vs/workbench/parts/files/browser/views/emptyView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,32 @@ import { IActionRunner, IAction } from 'vs/base/common/actions';
import { Button } from 'vs/base/browser/ui/button/button';
import { $ } from 'vs/base/browser/builder';
import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { CollapsibleView } from 'vs/base/browser/ui/splitview/splitview';
import { CollapsibleView, CollapsibleState } from 'vs/base/browser/ui/splitview/splitview';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IViewOptions } from 'vs/workbench/parts/views/browser/views';

export class EmptyView extends CollapsibleView {
private openFolderButton: Button;

public static ID: string = 'workbench.explorer.emptyView';

public readonly id: string = EmptyView.ID;

private openFolderButton: Button;
private actionRunner: IActionRunner;
constructor(
private actionRunner: IActionRunner,
options: IViewOptions,
@IThemeService private themeService: IThemeService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super({
minimumSize: 2 * 22,
ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section")
minimumSize: 5 * 22,
ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section"),
initialState: options.collapsed ? CollapsibleState.COLLAPSED : CollapsibleState.EXPANDED
});
this.actionRunner = options.actionRunner;
}

public renderHeader(container: HTMLElement): void {
Expand Down
12 changes: 8 additions & 4 deletions src/vs/workbench/parts/files/browser/views/explorerView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ThrottledDelayer } from 'vs/base/common/async';
import errors = require('vs/base/common/errors');
import labels = require('vs/base/common/labels');
import paths = require('vs/base/common/paths');
import { Action, IActionRunner, IAction } from 'vs/base/common/actions';
import { Action, IAction } from 'vs/base/common/actions';
import { prepareActions } from 'vs/workbench/browser/actionBarRegistry';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
Expand Down Expand Up @@ -43,9 +43,11 @@ import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/th
import { isLinux } from 'vs/base/common/platform';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { attachListStyler } from 'vs/platform/theme/common/styler';
import { IViewOptions } from 'vs/workbench/parts/views/browser/views';

export class ExplorerView extends CollapsibleViewletView {

public static ID: string = 'workbench.explorer.fileView';
private static EXPLORER_FILE_CHANGES_REACT_DELAY = 500; // delay in ms to react to file changes to give our internal events a chance to react first
private static EXPLORER_FILE_CHANGES_REFRESH_DELAY = 100; // delay in ms to refresh the explorer from disk file changes
private static EXPLORER_IMPORT_REFRESH_DELAY = 300; // delay in ms to refresh the explorer from imports
Expand All @@ -55,6 +57,8 @@ export class ExplorerView extends CollapsibleViewletView {

private static COMMON_SCM_FOLDERS = ['.git', '.svn', '.hg'];

public readonly id: string = ExplorerView.ID;

private explorerViewer: ITree;
private filter: FileFilter;
private viewletState: FileViewletState;
Expand All @@ -76,7 +80,7 @@ export class ExplorerView extends CollapsibleViewletView {

constructor(
viewletState: FileViewletState,
actionRunner: IActionRunner,
options: IViewOptions,
settings: any,
headerSize: number,
@IMessageService messageService: IMessageService,
Expand All @@ -95,11 +99,11 @@ export class ExplorerView extends CollapsibleViewletView {
@IWorkbenchThemeService private themeService: IWorkbenchThemeService,
@IEnvironmentService private environmentService: IEnvironmentService
) {
super(actionRunner, false, nls.localize('explorerSection', "Files Explorer Section"), messageService, keybindingService, contextMenuService, headerSize);
super(options.actionRunner, options.collapsed, nls.localize('explorerSection', "Files Explorer Section"), messageService, keybindingService, contextMenuService, headerSize);

this.settings = settings;
this.viewletState = viewletState;
this.actionRunner = actionRunner;
this.actionRunner = options.actionRunner;
this.autoReveal = true;

this.explorerRefreshDelayer = new ThrottledDelayer<void>(ExplorerView.EXPLORER_FILE_CHANGES_REFRESH_DELAY);
Expand Down
2 changes: 2 additions & 0 deletions src/vs/workbench/parts/files/browser/views/openEditorsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export class OpenEditorsView extends AdaptiveCollapsibleViewletView {
private static DEFAULT_VISIBLE_OPEN_EDITORS = 9;
private static DEFAULT_DYNAMIC_HEIGHT = true;

readonly id: string = 'workbench.explorer.openEditorsView';

private settings: any;
private visibleOpenEditors: number;
private dynamicHeight: boolean;
Expand Down
5 changes: 4 additions & 1 deletion src/vs/workbench/parts/views/browser/treeView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ export class TreeView extends CollapsibleViewletView {
@IExtensionService private extensionService: IExtensionService,
@ICommandService private commandService: ICommandService
) {
super(options.actionRunner, true, options.name, messageService, keybindingService, contextMenuService);
super(options.actionRunner, options.collapsed, options.name, messageService, keybindingService, contextMenuService);
this.menus = this.instantiationService.createInstance(Menus, this.id);
this.viewFocusContext = this.contextKeyService.createKey<boolean>(this.id, void 0);
this.menus.onDidChangeTitle(() => this.updateActions(), this, this.disposables);
this.themeService.onThemeChange(() => this.tree.refresh() /* soft refresh */, this, this.disposables);
if (!options.collapsed) {
this.triggerActivation();
}
}

public renderHeader(container: HTMLElement): void {
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/parts/views/browser/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum TreeItemCollapsibleState {
export interface IViewOptions {
name: string;
actionRunner: IActionRunner;
collapsed: boolean;
}

export interface IViewConstructorSignature {
Expand Down

0 comments on commit 6e43693

Please sign in to comment.