提交 05d902ac 编写于 作者: B Benjamin Pasero

Allow to hide entries from activity bar (for #15155)

上级 be33bcdb
......@@ -45,5 +45,5 @@ export class ToggleActivityBarVisibilityAction extends Action {
}
}
let registry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleActivityBarVisibilityAction, ToggleActivityBarVisibilityAction.ID, ToggleActivityBarVisibilityAction.LABEL), 'View: Toggle Activity Bar Visibility', nls.localize('view', "View"));
\ No newline at end of file
......@@ -45,5 +45,5 @@ export class ToggleStatusbarVisibilityAction extends Action {
}
}
let registry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleStatusbarVisibilityAction, ToggleStatusbarVisibilityAction.ID, ToggleStatusbarVisibilityAction.LABEL), 'View: Toggle Status Bar Visibility', nls.localize('view', "View"));
\ No newline at end of file
......@@ -32,5 +32,5 @@ class ToggleZenMode extends Action {
}
}
let registry = <IWorkbenchActionRegistry>Registry.as(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleZenMode, ToggleZenMode.ID, ToggleZenMode.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_Z) }), 'View: Toggle Zen Mode', nls.localize('view', "View"));
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleZenMode, ToggleZenMode.ID, ToggleZenMode.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_Z) }), 'View: Toggle Zen Mode', nls.localize('view', "View"));
\ No newline at end of file
......@@ -13,8 +13,8 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { Builder, $ } from 'vs/base/browser/builder';
import { DelayedDragHandler } from 'vs/base/browser/dnd';
import { Action } from 'vs/base/common/actions';
import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge } from 'vs/workbench/services/activity/common/activityService';
import { BaseActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IActivityBarService, ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge } from 'vs/workbench/services/activity/common/activityBarService';
import Event, { Emitter } from 'vs/base/common/event';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { ICommandService } from 'vs/platform/commands/common/commands';
......@@ -22,7 +22,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IViewletService, } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
export class ActivityAction extends Action {
......@@ -105,7 +105,6 @@ export class ViewletActivityAction extends ActivityAction {
export class ViewletOverflowActivityAction extends ActivityAction {
constructor(
private viewlets: ViewletDescriptor[],
private showMenu: () => void
) {
super('activitybar.additionalViewlets.action', nls.localize('additionalViewlets', "Additional Viewlets"), 'toggle-more');
......@@ -126,7 +125,7 @@ export class ViewletOverflowActivityActionItem extends BaseActionItem {
constructor(
action: ActivityAction,
private viewlets: ViewletDescriptor[],
private getOverflowingViewlets: () => ViewletDescriptor[],
private getBadge: (viewlet: ViewletDescriptor) => IBadge,
@IInstantiationService private instantiationService: IInstantiationService,
@IViewletService private viewletService: IViewletService,
......@@ -136,7 +135,6 @@ export class ViewletOverflowActivityActionItem extends BaseActionItem {
this.cssClass = action.class;
this.name = action.label;
this.actions = viewlets.map(viewlet => this.instantiationService.createInstance(OpenViewletAction, viewlet));
}
public render(container: HTMLElement): void {
......@@ -151,18 +149,24 @@ export class ViewletOverflowActivityActionItem extends BaseActionItem {
}
public showMenu(): void {
this.updateActions();
if (this.actions) {
dispose(this.actions);
}
this.actions = this.getActions();
this.contextMenuService.showContextMenu({
getAnchor: () => this.builder.getHTMLElement(),
getActions: () => TPromise.as(this.actions)
getActions: () => TPromise.as(this.actions),
onHide: () => dispose(this.actions)
});
}
private updateActions(): void {
private getActions(): OpenViewletAction[] {
const activeViewlet = this.viewletService.getActiveViewlet();
this.actions.forEach(action => {
return this.getOverflowingViewlets().map(viewlet => {
const action = this.instantiationService.createInstance(OpenViewletAction, viewlet);
action.radio = activeViewlet && activeViewlet.getId() === action.id;
const badge = this.getBadge(action.viewlet);
......@@ -178,6 +182,8 @@ export class ViewletOverflowActivityActionItem extends BaseActionItem {
} else {
action.label = action.viewlet.name;
}
return action;
});
}
......@@ -188,8 +194,11 @@ export class ViewletOverflowActivityActionItem extends BaseActionItem {
}
}
let manageExtensionAction: ManageExtensionAction;
export class ActivityActionItem extends BaseActionItem {
private static manageExtensionAction: ManageExtensionAction;
private static toggleViewletPinnedAction: ToggleViewletPinnedAction;
private $e: Builder;
private name: string;
private _keybinding: string;
......@@ -202,6 +211,8 @@ export class ActivityActionItem extends BaseActionItem {
action: ActivityAction,
private viewlet: ViewletDescriptor,
@IContextMenuService private contextMenuService: IContextMenuService,
@IViewletService private viewletService: IViewletService,
@IActivityBarService private activityBarService: IActivityBarService,
@IKeybindingService private keybindingService: IKeybindingService,
@IInstantiationService instantiationService: IInstantiationService
) {
......@@ -212,8 +223,12 @@ export class ActivityActionItem extends BaseActionItem {
this._keybinding = this.getKeybindingLabel(viewlet.id);
action.onDidChangeBadge(this.handleBadgeChangeEvenet, this, this._callOnDispose);
if (!manageExtensionAction) {
manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
if (!ActivityActionItem.manageExtensionAction) {
ActivityActionItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction);
}
if (!ActivityActionItem.toggleViewletPinnedAction) {
ActivityActionItem.toggleViewletPinnedAction = instantiationService.createInstance(ToggleViewletPinnedAction, void 0);
}
}
......@@ -234,17 +249,11 @@ export class ActivityActionItem extends BaseActionItem {
role: 'button'
}).appendTo(this.builder);
if (this.viewlet.extensionId) {
$(container).on('contextmenu', e => {
DOM.EventHelper.stop(e, true);
this.contextMenuService.showContextMenu({
getAnchor: () => container,
getActionsContext: () => this.viewlet.extensionId,
getActions: () => TPromise.as([manageExtensionAction])
});
}, this.toDispose);
}
$(container).on('contextmenu', e => {
DOM.EventHelper.stop(e, true);
this.showContextMenu(container);
}, this.toDispose);
if (this.cssClass) {
this.$e.addClass(this.cssClass);
......@@ -266,6 +275,27 @@ export class ActivityActionItem extends BaseActionItem {
}));
}
private showContextMenu(container: HTMLElement): void {
const actions: Action[] = [ActivityActionItem.toggleViewletPinnedAction];
if (this.viewlet.extensionId) {
actions.push(new Separator());
actions.push(ActivityActionItem.manageExtensionAction);
}
const isPinned = this.activityBarService.isPinned(this.viewlet.id);
if (isPinned) {
ActivityActionItem.toggleViewletPinnedAction.label = nls.localize('removeFromActivityBar', "Remove from Activity Bar");
} else {
ActivityActionItem.toggleViewletPinnedAction.label = nls.localize('keepInActivityBar', "Keep in Activity Bar");
}
this.contextMenuService.showContextMenu({
getAnchor: () => container,
getActionsContext: () => this.viewlet,
getActions: () => TPromise.as(actions)
});
}
public focus(): void {
this.$e.domFocus();
}
......@@ -376,8 +406,8 @@ class ManageExtensionAction extends Action {
super('activitybar.manage.extension', nls.localize('manageExtension', "Manage Extension"));
}
public run(extensionId: string): TPromise<any> {
return this.commandService.executeCommand('_extensions.manage', extensionId);
public run(viewlet: ViewletDescriptor): TPromise<any> {
return this.commandService.executeCommand('_extensions.manage', viewlet.extensionId);
}
}
......@@ -402,6 +432,30 @@ class OpenViewletAction extends Action {
this.viewletService.openViewlet(this.viewlet.id, true).done(null, errors.onUnexpectedError);
}
return TPromise.as(true);
}
}
export class ToggleViewletPinnedAction extends Action {
constructor(
private viewlet: ViewletDescriptor,
@IActivityBarService private activityBarService: IActivityBarService
) {
super('activitybar.show.toggleViewletPinned', viewlet ? viewlet.name : nls.localize('toggle', "Toggle Viewlet Pinned"));
this.checked = this.viewlet && this.activityBarService.isPinned(this.viewlet.id);
}
public run(context?: ViewletDescriptor): TPromise<any> {
const viewlet = this.viewlet || context;
if (this.activityBarService.isPinned(viewlet.id)) {
this.activityBarService.unpin(viewlet.id);
} else {
this.activityBarService.pin(viewlet.id);
}
return TPromise.as(true);
}
}
\ No newline at end of file
......@@ -7,28 +7,38 @@
import 'vs/css!./media/activitybarpart';
import nls = require('vs/nls');
import { TPromise } from 'vs/base/common/winjs.base';
import DOM = require('vs/base/browser/dom');
import * as arrays from 'vs/base/common/arrays';
import { Builder, $, Dimension } from 'vs/base/browser/builder';
import { Action } from 'vs/base/common/actions';
import { ActionsOrientation, ActionBar, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IComposite } from 'vs/workbench/common/composite';
import { ActionsOrientation, ActionBar, IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
import { Part } from 'vs/workbench/browser/part';
import { ViewletActivityAction, ActivityAction, ActivityActionItem, ViewletOverflowActivityAction, ViewletOverflowActivityActionItem } from 'vs/workbench/browser/parts/activitybar/activityAction';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { ToggleViewletPinnedAction, ViewletActivityAction, ActivityAction, ActivityActionItem, ViewletOverflowActivityAction, ViewletOverflowActivityActionItem } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IActivityService, IBadge } from 'vs/workbench/services/activity/common/activityService';
import { IActivityBarService, IBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IPartService } from 'vs/workbench/services/part/common/partService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Scope as MementoScope } from 'vs/workbench/common/memento';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { dispose } from 'vs/base/common/lifecycle';
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
interface IViewletActivity {
badge: IBadge;
clazz: string;
}
export class ActivitybarPart extends Part implements IActivityService {
export class ActivitybarPart extends Part implements IActivityBarService {
private static ACTIVITY_ACTION_HEIGHT = 50;
private static readonly ACTIVITY_ACTION_HEIGHT = 50;
private static readonly UNPINNED_VIEWLETS = 'workbench.activity.unpinnedViewlets';
public _serviceBrand: any;
......@@ -42,11 +52,17 @@ export class ActivitybarPart extends Part implements IActivityService {
private viewletIdToActions: { [viewletId: string]: ActivityAction; };
private viewletIdToActivity: { [viewletId: string]: IViewletActivity; };
private memento: any;
private unpinnedViewlets: string[];
private activeUnpinnedViewlet: ViewletDescriptor;
constructor(
id: string,
@IViewletService private viewletService: IViewletService,
@IExtensionService private extensionService: IExtensionService,
@IKeybindingService private keybindingService: IKeybindingService,
@IStorageService private storageService: IStorageService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService
) {
......@@ -56,6 +72,9 @@ export class ActivitybarPart extends Part implements IActivityService {
this.viewletIdToActions = Object.create(null);
this.viewletIdToActivity = Object.create(null);
this.memento = this.getMemento(this.storageService, MementoScope.GLOBAL);
this.unpinnedViewlets = this.memento[ActivitybarPart.UNPINNED_VIEWLETS] || [];
// Update viewlet switcher when external viewlets become ready
this.extensionService.onReady().then(() => this.updateViewletSwitcher());
......@@ -65,21 +84,31 @@ export class ActivitybarPart extends Part implements IActivityService {
private registerListeners(): void {
// Activate viewlet action on opening of a viewlet
this.toUnbind.push(this.viewletService.onDidViewletOpen(viewlet => this.onActiveCompositeChanged(viewlet)));
this.toUnbind.push(this.viewletService.onDidViewletOpen(viewlet => this.onDidViewletOpen(viewlet)));
// Deactivate viewlet action on close
this.toUnbind.push(this.viewletService.onDidViewletClose(viewlet => this.onCompositeClosed(viewlet)));
this.toUnbind.push(this.viewletService.onDidViewletClose(viewlet => this.onDidViewletClose(viewlet)));
}
private onActiveCompositeChanged(composite: IComposite): void {
if (this.viewletIdToActions[composite.getId()]) {
this.viewletIdToActions[composite.getId()].activate();
private onDidViewletOpen(viewlet: IViewlet): void {
const id = viewlet.getId();
if (this.viewletIdToActions[id]) {
this.viewletIdToActions[id].activate();
}
const activeUnpinnedViewletShouldClose = this.activeUnpinnedViewlet && this.activeUnpinnedViewlet.id !== viewlet.getId();
const activeUnpinnedViewletShouldShow = !this.getPinnedViewlets().some(v => v.id === viewlet.getId());
if (activeUnpinnedViewletShouldShow || activeUnpinnedViewletShouldClose) {
this.updateViewletSwitcher();
}
}
private onCompositeClosed(composite: IComposite): void {
if (this.viewletIdToActions[composite.getId()]) {
this.viewletIdToActions[composite.getId()].deactivate();
private onDidViewletClose(viewlet: IViewlet): void {
const id = viewlet.getId();
if (this.viewletIdToActions[id]) {
this.viewletIdToActions[id].deactivate();
}
}
......@@ -113,9 +142,30 @@ export class ActivitybarPart extends Part implements IActivityService {
// Top Actionbar with action items for each viewlet action
this.createViewletSwitcher($result.clone());
// Contextmenu for viewlets
$(parent).on('contextmenu', (e: MouseEvent) => {
DOM.EventHelper.stop(e, true);
this.showContextMenu(e);
}, this.toUnbind);
return $result;
}
private showContextMenu(e: MouseEvent): void {
const event = new StandardMouseEvent(e);
const actions: Action[] = this.viewletService.getViewlets().map(viewlet => this.instantiationService.createInstance(ToggleViewletPinnedAction, viewlet));
actions.push(new Separator());
actions.push(this.instantiationService.createInstance(ToggleActivityBarVisibilityAction, ToggleActivityBarVisibilityAction.ID, nls.localize('hideActivitBar', "Hide Activity Bar")));
this.contextMenuService.showContextMenu({
getAnchor: () => { return { x: event.posx + 1, y: event.posy }; },
getActions: () => TPromise.as(actions),
onHide: () => dispose(actions)
});
}
private createViewletSwitcher(div: Builder): void {
this.viewletSwitcherBar = new ActionBar(div, {
actionItemProvider: (action: Action) => action instanceof ViewletOverflowActivityAction ? this.viewletOverflowActionItem : this.activityActionItems[action.id],
......@@ -128,22 +178,30 @@ export class ActivitybarPart extends Part implements IActivityService {
}
private updateViewletSwitcher() {
let viewlets = this.viewletService.getViewlets();
let viewletsToShow = viewlets;
let viewletsToShow = this.getPinnedViewlets();
// Always show the active viewlet even if it is marked to be hidden
const activeViewlet = this.viewletService.getActiveViewlet();
if (activeViewlet && !viewletsToShow.some(v => v.id === activeViewlet.getId())) {
this.activeUnpinnedViewlet = this.viewletService.getViewlet(activeViewlet.getId());
viewletsToShow.push(this.activeUnpinnedViewlet);
} else {
this.activeUnpinnedViewlet = void 0;
}
// Ensure we are not showing more viewlets than we have height for
let overflows = false;
if (this.dimension) {
const maxVisible = Math.floor(this.dimension.height / ActivitybarPart.ACTIVITY_ACTION_HEIGHT);
overflows = viewlets.length > maxVisible;
overflows = viewletsToShow.length > maxVisible;
if (overflows) {
viewletsToShow = viewlets.slice(0, maxVisible - 1 /* make room for overflow action */);
viewletsToShow = viewletsToShow.slice(0, maxVisible - 1 /* make room for overflow action */);
}
}
const visibleViewlets = Object.keys(this.viewletIdToActions);
const visibleViewletsChange = (viewletsToShow.length !== visibleViewlets.length);
const visibleViewletsChange = !arrays.equals(viewletsToShow.map(v => v.id), visibleViewlets);
// Pull out overflow action if there is a viewlet change so that we can add it to the end later
if (this.viewletOverflowAction && visibleViewletsChange) {
......@@ -156,7 +214,7 @@ export class ActivitybarPart extends Part implements IActivityService {
this.viewletOverflowActionItem = null;
}
// Pull out viewlets that overflow
// Pull out viewlets that overflow or got hidden
const viewletIdsToShow = viewletsToShow.map(v => v.id);
visibleViewlets.forEach(viewletId => {
if (viewletIdsToShow.indexOf(viewletId) === -1) {
......@@ -197,15 +255,34 @@ export class ActivitybarPart extends Part implements IActivityService {
// Add overflow action as needed
if (visibleViewletsChange && overflows) {
const viewletsOverflowing = viewlets.slice(viewletsToShow.length);
this.viewletOverflowAction = this.instantiationService.createInstance(ViewletOverflowActivityAction, viewletsOverflowing, () => this.viewletOverflowActionItem.showMenu());
this.viewletOverflowActionItem = this.instantiationService.createInstance(ViewletOverflowActivityActionItem, this.viewletOverflowAction, viewletsOverflowing, viewlet => this.viewletIdToActivity[viewlet.id] && this.viewletIdToActivity[viewlet.id].badge);
this.viewletOverflowAction = this.instantiationService.createInstance(ViewletOverflowActivityAction, () => this.viewletOverflowActionItem.showMenu());
this.viewletOverflowActionItem = this.instantiationService.createInstance(ViewletOverflowActivityActionItem, this.viewletOverflowAction, () => this.getOverflowingViewlets(), viewlet => this.viewletIdToActivity[viewlet.id] && this.viewletIdToActivity[viewlet.id].badge);
this.viewletSwitcherBar.push(this.viewletOverflowAction, { label: true, icon: true });
}
}
private getOverflowingViewlets(): ViewletDescriptor[] {
const viewlets = this.getPinnedViewlets();
if (this.activeUnpinnedViewlet) {
viewlets.push(this.activeUnpinnedViewlet);
}
const visibleViewlets = Object.keys(this.viewletIdToActions);
return viewlets.filter(viewlet => visibleViewlets.indexOf(viewlet.id) === -1);
}
private getVisibleViewlets(): ViewletDescriptor[] {
const viewlets = this.viewletService.getViewlets();
const visibleViewlets = Object.keys(this.viewletIdToActions);
return viewlets.filter(viewlet => visibleViewlets.indexOf(viewlet.id) >= 0);
}
private getPinnedViewlets(): ViewletDescriptor[] {
return this.viewletService.getViewlets().filter(viewlet => this.isPinned(viewlet.id));
}
private pullViewlet(viewletId: string): void {
const index = Object.keys(this.viewletIdToActions).indexOf(viewletId);
this.viewletSwitcherBar.pull(index);
......@@ -228,6 +305,71 @@ export class ActivitybarPart extends Part implements IActivityService {
return action;
}
public unpin(viewletId: string): void {
if (!this.isPinned(viewletId)) {
return;
}
const activeViewlet = this.viewletService.getActiveViewlet();
const defaultViewletId = this.viewletService.getDefaultViewletId();
const visibleViewlets = this.getVisibleViewlets();
let unpinPromise: TPromise<any>;
// Case: viewlet is not the active one or the active one is a different one
// Solv: we do nothing
if (!activeViewlet || activeViewlet.getId() !== viewletId) {
unpinPromise = TPromise.as(null);
}
// Case: viewlet is not the default viewlet and default viewlet is still showing
// Solv: we open the default viewlet
else if (defaultViewletId !== viewletId && this.isPinned(defaultViewletId)) {
unpinPromise = this.viewletService.openViewlet(defaultViewletId, true);
}
// Case: we closed the last visible viewlet
// Solv: we hide the sidebar
else if (visibleViewlets.length === 1) {
unpinPromise = TPromise.as(this.partService.setSideBarHidden(true));
}
// Case: we closed the default viewlet
// Solv: we open the next visible viewlet from top
else {
unpinPromise = this.viewletService.openViewlet(visibleViewlets.filter(viewlet => viewlet.id !== viewletId)[0].id, true);
}
unpinPromise.then(() => {
// then add to unpinned and update switcher
this.unpinnedViewlets.push(viewletId);
this.unpinnedViewlets = arrays.distinct(this.unpinnedViewlets);
this.updateViewletSwitcher();
});
}
public isPinned(viewletId: string): boolean {
return this.unpinnedViewlets.indexOf(viewletId) === -1;
}
public pin(viewletId: string): void {
if (this.isPinned(viewletId)) {
return;
}
// first open that viewlet
this.viewletService.openViewlet(viewletId, true).then(() => {
// then update
const index = this.unpinnedViewlets.indexOf(viewletId);
this.unpinnedViewlets.splice(index, 1);
this.updateViewletSwitcher();
});
}
/**
* Layout title, content and status area in the given dimension.
*/
......@@ -252,4 +394,13 @@ export class ActivitybarPart extends Part implements IActivityService {
super.dispose();
}
public shutdown(): void {
// Persist Hidden State
this.memento[ActivitybarPart.UNPINNED_VIEWLETS] = this.unpinnedViewlets;
// Pass to super
super.shutdown();
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ import { Action, IAction } from 'vs/base/common/actions';
import Event from 'vs/base/common/event';
import { Builder } from 'vs/base/browser/builder';
import { Registry } from 'vs/platform/platform';
import { ActivityAction } from 'vs/workbench/browser/parts/activitybar/activityAction';
import { ActivityAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
import { Scope } from 'vs/workbench/browser/actionBarRegistry';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/actionRegistry';
......
......@@ -39,7 +39,6 @@ import { StatusbarPart } from 'vs/workbench/browser/parts/statusbar/statusbarPar
import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
import { WorkbenchLayout } from 'vs/workbench/browser/layout';
import { IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actionBarRegistry';
import { ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet';
import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel';
import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickOpenController';
import { DiffEditorInput, toDiffLabel } from 'vs/workbench/common/editor/diffEditorInput';
......@@ -57,7 +56,7 @@ import { ConfigurationEditingService } from 'vs/workbench/services/configuration
import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr, RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IActivityService } from 'vs/workbench/services/activity/common/activityService';
import { IActivityBarService } from 'vs/workbench/services/activity/common/activityBarService';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { ViewletService } from 'vs/workbench/services/viewlet/browser/viewletService';
import { FileService } from 'vs/workbench/services/files/electron-browser/fileService';
......@@ -273,7 +272,7 @@ export class Workbench implements IPartService {
}
if (!viewletIdToRestore) {
viewletIdToRestore = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).getDefaultViewletId();
viewletIdToRestore = this.viewletService.getDefaultViewletId();
}
viewletRestoreStopWatch = StopWatch.create();
......@@ -440,7 +439,7 @@ export class Workbench implements IPartService {
this.activitybarPart = this.instantiationService.createInstance(ActivitybarPart, Identifiers.ACTIVITYBAR_PART);
this.toDispose.push(this.activitybarPart);
this.toShutdown.push(this.activitybarPart);
serviceCollection.set(IActivityService, this.activitybarPart);
serviceCollection.set(IActivityBarService, this.activitybarPart);
// Editor service (editor part)
this.editorPart = this.instantiationService.createInstance(EditorPart, Identifiers.EDITOR_PART, !this.hasFilesToCreateOpenOrDiff);
......@@ -507,11 +506,6 @@ export class Workbench implements IPartService {
this.sideBarHidden = true; // we hide sidebar in single-file-mode
}
const viewletRegistry = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets);
if (!viewletRegistry.getDefaultViewletId()) {
this.sideBarHidden = true; // can only hide sidebar if we dont have a default Viewlet id
}
// Panel part visibility
const panelRegistry = Registry.as<PanelRegistry>(PanelExtensions.Panels);
this.panelHidden = this.storageService.getBoolean(Workbench.panelHiddenSettingKey, StorageScope.WORKSPACE, true);
......@@ -702,8 +696,7 @@ export class Workbench implements IPartService {
// If sidebar becomes visible, show last active Viewlet or default viewlet
else if (!hidden && !this.sidebarPart.getActiveViewlet()) {
const registry = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets);
const viewletToOpen = this.sidebarPart.getLastActiveViewletId() || registry.getDefaultViewletId();
const viewletToOpen = this.sidebarPart.getLastActiveViewletId() || this.viewletService.getDefaultViewletId();
if (viewletToOpen) {
this.sidebarPart.openViewlet(viewletToOpen, true).done(null, errors.onUnexpectedError);
}
......
......@@ -13,7 +13,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TreeExplorerView } from 'vs/workbench/parts/explorers/browser/views/treeExplorerView';
import { TreeExplorerViewletState } from 'vs/workbench/parts/explorers/browser/views/treeExplorerViewer';
import { IActivityService } from 'vs/workbench/services/activity/common/activityService';
export class TreeExplorerViewlet extends Viewlet {
......@@ -27,8 +26,7 @@ export class TreeExplorerViewlet extends Viewlet {
constructor(
viewletId: string,
@ITelemetryService telemetryService: ITelemetryService,
@IInstantiationService private instantiationService: IInstantiationService,
@IActivityService private activityService: IActivityService
@IInstantiationService private instantiationService: IInstantiationService
) {
super(viewletId, telemetryService);
......
......@@ -44,7 +44,7 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { IMessageService, CloseAction } from 'vs/platform/message/common/message';
import Severity from 'vs/base/common/severity';
import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activityService';
import { IActivityBarService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
interface SearchInputEvent extends Event {
......@@ -421,7 +421,7 @@ export class StatusUpdater implements IWorkbenchContribution {
private disposables: IDisposable[];
constructor(
@IActivityService private activityService: IActivityService,
@IActivityBarService private activityBarService: IActivityBarService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
) {
extensionsWorkbenchService.onChange(this.onServiceChange, this, this.disposables);
......@@ -433,16 +433,16 @@ export class StatusUpdater implements IWorkbenchContribution {
private onServiceChange(): void {
if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) {
this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', 'Extensions')), 'extensions-badge progress-badge');
this.activityBarService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', 'Extensions')), 'extensions-badge progress-badge');
return;
}
const outdated = this.extensionsWorkbenchService.local.reduce((r, e) => r + (e.outdated ? 1 : 0), 0);
if (outdated > 0) {
const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n));
this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
this.activityBarService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge');
} else {
this.activityService.showActivity(VIEWLET_ID, null, 'extensions-badge');
this.activityBarService.showActivity(VIEWLET_ID, null, 'extensions-badge');
}
}
......
......@@ -19,7 +19,7 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import URI from 'vs/base/common/uri';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activityService';
import { IActivityBarService, NumberBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import arrays = require('vs/base/common/arrays');
......@@ -38,7 +38,7 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
@ILifecycleService private lifecycleService: ILifecycleService,
@IEditorGroupService editorGroupService: IEditorGroupService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IActivityService private activityService: IActivityService,
@IActivityBarService private activityBarService: IActivityBarService,
@IWindowService private windowService: IWindowService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService
) {
......@@ -148,9 +148,9 @@ export class DirtyFilesTracker implements IWorkbenchContribution {
const dirtyCount = this.textFileService.getDirty().length;
this.lastDirtyCount = dirtyCount;
if (dirtyCount > 0) {
this.activityService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label');
this.activityBarService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label');
} else {
this.activityService.clearActivity(VIEWLET_ID);
this.activityBarService.clearActivity(VIEWLET_ID);
}
}
......
......@@ -23,7 +23,7 @@ import confregistry = require('vs/platform/configuration/common/configurationReg
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import quickopen = require('vs/workbench/browser/quickopen');
import 'vs/workbench/parts/git/browser/gitEditorContributions';
import { IActivityService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activityService';
import { IActivityBarService, ProgressBadge, NumberBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IEventService } from 'vs/platform/event/common/event';
import { IMessageService } from 'vs/platform/message/common/message';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
......@@ -37,7 +37,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
private gitService: IGitService;
private eventService: IEventService;
private activityService: IActivityService;
private activityBarService: IActivityBarService;
private messageService: IMessageService;
private configurationService: IConfigurationService;
private progressBadgeDelayer: async.Delayer<void>;
......@@ -46,13 +46,13 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
constructor(
@IGitService gitService: IGitService,
@IEventService eventService: IEventService,
@IActivityService activityService: IActivityService,
@IActivityBarService activityBarService: IActivityBarService,
@IMessageService messageService: IMessageService,
@IConfigurationService configurationService: IConfigurationService
) {
this.gitService = gitService;
this.eventService = eventService;
this.activityService = activityService;
this.activityBarService = activityBarService;
this.messageService = messageService;
this.configurationService = configurationService;
......@@ -66,12 +66,12 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
private onGitServiceChange(): void {
if (this.gitService.getState() !== git.ServiceState.OK) {
this.progressBadgeDelayer.cancel();
this.activityService.showActivity('workbench.view.git', null, 'git-viewlet-label');
this.activityBarService.showActivity('workbench.view.git', null, 'git-viewlet-label');
} else if (this.gitService.isIdle()) {
this.showChangesBadge();
} else {
this.progressBadgeDelayer.trigger(() => {
this.activityService.showActivity('workbench.view.git', new ProgressBadge(() => nls.localize('gitProgressBadge', 'Running git status')), 'git-viewlet-label-progress');
this.activityBarService.showActivity('workbench.view.git', new ProgressBadge(() => nls.localize('gitProgressBadge', 'Running git status')), 'git-viewlet-label-progress');
});
}
}
......@@ -95,7 +95,7 @@ export class StatusUpdater implements ext.IWorkbenchContribution {
.filter(filter);
const badge = new NumberBadge(statuses.length, num => nls.localize('gitPendingChangesBadge', '{0} pending changes', num));
this.activityService.showActivity('workbench.view.git', badge, 'git-viewlet-label');
this.activityBarService.showActivity('workbench.view.git', badge, 'git-viewlet-label');
}
public getId(): string {
......
......@@ -11,7 +11,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import * as platform from 'vs/platform/platform';
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activityService';
import { IActivityBarService, NumberBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
import * as panel from 'vs/workbench/browser/panel';
......@@ -25,7 +25,7 @@ class StatusUpdater implements IWorkbenchContribution {
constructor(
@IMarkerService private markerService: IMarkerService,
@IActivityService private activityService: IActivityService
@IActivityBarService private activityBarService: IActivityBarService
) {
this.toDispose = [];
......@@ -37,9 +37,9 @@ class StatusUpdater implements IWorkbenchContribution {
const problemCount = stats.errors + stats.warnings + stats.infos + stats.unknowns;
if (problemCount > 0) {
const badge = new NumberBadge(problemCount, n => localize({ comment: ['Argument represents count (number) of errors and warnings.'], key: 'errorsAndWarnings' }, '{0} Errors and Warnings', n));
this.activityService.showActivity(Constants.MARKERS_PANEL_ID, badge);
this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, badge);
} else {
this.activityService.showActivity(Constants.MARKERS_PANEL_ID, null);
this.activityBarService.showActivity(Constants.MARKERS_PANEL_ID, null);
}
}
......
......@@ -56,18 +56,33 @@ export class IconBadge extends BaseBadge {
export class ProgressBadge extends BaseBadge {
}
export const IActivityService = createDecorator<IActivityService>('activityService');
export const IActivityBarService = createDecorator<IActivityBarService>('activityBarService');
export interface IActivityService {
export interface IActivityBarService {
_serviceBrand: any;
/**
* Show activity in the activitybar for the given viewlet or panel.
* Show activity in the activitybar for the given viewlet.
*/
showActivity(compositeId: string, badge: IBadge, clazz?: string): void;
showActivity(viewletId: string, badge: IBadge, clazz?: string): void;
/**
* Clears activity shown in the activitybar for the given viewlet or panel.
* Clears activity shown in the activitybar for the given viewlet.
*/
clearActivity(compositeId: string): void;
clearActivity(viewletId: string): void;
/**
* Unpins a viewlet from the activitybar.
*/
unpin(viewletId: string): void;
/**
* Pin a viewlet inside the activity bar.
*/
pin(viewletId: string): void;
/**
* Find out if a viewlet is pinned in the activity bar.
*/
isPinned(viewletId: string): boolean;
}
\ No newline at end of file
......@@ -28,6 +28,16 @@ export interface IViewletService {
*/
getActiveViewlet(): IViewlet;
/**
* Returns the id of the default viewlet.
*/
getDefaultViewletId(): string;
/**
* Returns the viewlet by id.
*/
getViewlet(id: string): ViewletDescriptor;
/**
* Returns all registered viewlets
*/
......
......@@ -72,7 +72,7 @@ export class ViewletService implements IViewletService {
}
// Fallback to default viewlet if extension viewlet is still not found (e.g. uninstalled)
return this.sidebarPart.openViewlet(this.viewletRegistry.getDefaultViewletId(), focus);
return this.sidebarPart.openViewlet(this.getDefaultViewletId(), focus);
});
}
......@@ -91,4 +91,12 @@ export class ViewletService implements IViewletService {
.filter(viewlet => !viewlet.extensionId)
.sort((v1, v2) => v1.order - v2.order);
}
public getDefaultViewletId(): string {
return this.viewletRegistry.getDefaultViewletId();
}
public getViewlet(id: string): ViewletDescriptor {
return this.getViewlets().filter(viewlet => viewlet.id === id)[0];
}
}
\ No newline at end of file
......@@ -118,6 +118,14 @@ class TestViewletService implements IViewletService {
public dispose() {
}
public getDefaultViewletId(): string {
return 'workbench.view.explorer';
}
public getViewlet(id: string): ViewletDescriptor {
return null;
}
}
class TestPanelService implements IPanelService {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册