diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index e5c6aa533e6387b79f96c331952aaf32e2ed1c09..45053f14f6222a53fe1fb86d4199042c346e375a 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -12,7 +12,7 @@ import {Builder, $} from 'vs/base/browser/builder'; import {Action} from 'vs/base/common/actions'; import errors = require('vs/base/common/errors'); import {ActionsOrientation, ActionBar, IActionItem} from 'vs/base/browser/ui/actionbar/actionbar'; -import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; +import {CONTEXT, ToolBar} from 'vs/base/browser/ui/toolbar/toolbar'; import {Registry} from 'vs/platform/platform'; import {IViewlet} from 'vs/workbench/common/viewlet'; import {ViewletDescriptor, ViewletRegistry, Extensions as ViewletExtensions} from 'vs/workbench/browser/viewlet'; @@ -26,10 +26,15 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat import {IMessageService} from 'vs/platform/message/common/message'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybinding'; +import {Scope, IActionBarRegistry, Extensions as ActionBarExtensions, prepareActions} from 'vs/workbench/browser/actionBarRegistry'; +import Severity from 'vs/base/common/severity'; +import {IAction} from 'vs/base/common/actions'; +import events = require('vs/base/common/events'); export class ActivitybarPart extends Part implements IActivityService { public _serviceBrand: any; private viewletSwitcherBar: ActionBar; + private globalViewletSwitcherBar: ActionBar; private globalToolBar: ToolBar; private activityActionItems: { [actionId: string]: IActionItem; }; private viewletIdToActions: { [viewletId: string]: ActivityAction; }; @@ -100,6 +105,9 @@ export class ActivitybarPart extends Part implements IActivityService { // Top Actionbar with action items for each viewlet action this.createViewletSwitcher($result.clone()); + // Bottom Toolbar with action items for global actions + this.createGlobalToolBarArea($result.clone()); // not used currently + return $result; } @@ -113,6 +121,14 @@ export class ActivitybarPart extends Part implements IActivityService { }); this.viewletSwitcherBar.getContainer().addClass('position-top'); + // Global viewlet switcher is right below + this.globalViewletSwitcherBar = new ActionBar(div, { + actionItemProvider: (action: Action) => this.activityActionItems[action.id], + orientation: ActionsOrientation.VERTICAL, + ariaLabel: nls.localize('globalActivityBarAriaLabel', "Active Global View Switcher") + }); + this.globalViewletSwitcherBar.getContainer().addClass('position-bottom'); + // Build Viewlet Actions in correct order const activeViewlet = this.viewletService.getActiveViewlet(); const registry = (Registry.as(ViewletExtensions.Viewlets)); @@ -145,6 +161,83 @@ export class ActivitybarPart extends Part implements IActivityService { .sort((v1, v2) => v1.order - v2.order) .map(toAction) , actionOptions); + + // Add to viewlet switcher + this.globalViewletSwitcherBar.push(allViewletActions + .filter(v => v.isGlobal) + .sort((v1, v2) => v1.order - v2.order) + .map(toAction), + actionOptions); + } + + private createGlobalToolBarArea(div: Builder): void { + + // Global action bar is on the bottom + this.globalToolBar = new ToolBar(div.getHTMLElement(), this.contextMenuService, { + actionItemProvider: (action: Action) => this.activityActionItems[action.id], + orientation: ActionsOrientation.VERTICAL + }); + this.globalToolBar.getContainer().addClass('global'); + + this.globalToolBar.actionRunner.addListener2(events.EventType.RUN, (e: any) => { + + // Check for Error + if (e.error && !errors.isPromiseCanceledError(e.error)) { + this.messageService.show(Severity.Error, e.error); + } + + // Log in telemetry + if (this.telemetryService) { + this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'activityBar' }); + } + }); + + // Build Global Actions in correct order + let primaryActions = this.getGlobalActions(true); + let secondaryActions = this.getGlobalActions(false); + + if (primaryActions.length + secondaryActions.length > 0) { + this.globalToolBar.getContainer().addClass('position-bottom'); + } + + // Add to global action bar + this.globalToolBar.setActions(prepareActions(primaryActions), prepareActions(secondaryActions))(); + } + + private getGlobalActions(primary: boolean): IAction[] { + let actionBarRegistry = Registry.as(ActionBarExtensions.Actionbar); + + // Collect actions from actionbar contributor + let actions: IAction[]; + if (primary) { + actions = actionBarRegistry.getActionBarActionsForContext(Scope.GLOBAL, CONTEXT); + } else { + actions = actionBarRegistry.getSecondaryActionBarActionsForContext(Scope.GLOBAL, CONTEXT); + } + + return actions.map((action: ActivityAction) => { + if (primary) { + let keybinding: string = null; + let keys = this.keybindingService.lookupKeybindings(action.id).map(k => this.keybindingService.getLabelFor(k)); + if (keys && keys.length) { + keybinding = keys[0]; + } + + let actionItem = actionBarRegistry.getActionItemForContext(Scope.GLOBAL, CONTEXT, action); + + if (!actionItem) { + actionItem = new ActivityActionItem(action, action.label, keybinding); + } + + if (actionItem instanceof ActivityActionItem) { + (actionItem).keybinding = keybinding; + } + + this.activityActionItems[action.id] = actionItem; + } + + return action; + }); } public dispose(): void {