提交 0722ad47 编写于 作者: J Joao Moreno

wip: update contribution 2

上级 3b769612
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Registry } from 'vs/platform/platform';
import { IAction } from 'vs/base/common/actions';
import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
export interface IActivity {
......@@ -12,26 +13,30 @@ export interface IActivity {
cssClass: string;
}
export const ActivityExtensions = 'workbench.contributions.activities';
export interface IGlobalActivity extends IActivity {
getActions(): IAction[];
}
export const GlobalActivityExtensions = 'workbench.contributions.globalActivities';
export interface IActivityRegistry {
registerActivity(descriptor: IConstructorSignature0<IActivity>): void;
getActivities(): IConstructorSignature0<IActivity>[];
export interface IGlobalActivityRegistry {
registerActivity(descriptor: IConstructorSignature0<IGlobalActivity>): void;
getActivities(): IConstructorSignature0<IGlobalActivity>[];
}
export class ActivityRegistry implements IActivityRegistry {
export class GlobalActivityRegistry implements IGlobalActivityRegistry {
private activityDescriptors = new Set<IConstructorSignature0<IActivity>>();
private activityDescriptors = new Set<IConstructorSignature0<IGlobalActivity>>();
registerActivity(descriptor: IConstructorSignature0<IActivity>): void {
registerActivity(descriptor: IConstructorSignature0<IGlobalActivity>): void {
this.activityDescriptors.add(descriptor);
}
getActivities(): IConstructorSignature0<IActivity>[] {
const result: IConstructorSignature0<IActivity>[] = [];
getActivities(): IConstructorSignature0<IGlobalActivity>[] {
const result: IConstructorSignature0<IGlobalActivity>[] = [];
this.activityDescriptors.forEach(d => result.push(d));
return result;
}
}
Registry.add(ActivityExtensions, new ActivityRegistry());
\ No newline at end of file
Registry.add(GlobalActivityExtensions, new GlobalActivityRegistry());
\ No newline at end of file
......@@ -13,7 +13,7 @@ import { Builder, $ } from 'vs/base/browser/builder';
import { DelayedDragHandler } from 'vs/base/browser/dnd';
import { Action } from 'vs/base/common/actions';
import { BaseActionItem, Separator, IBaseActionItemOptions } from 'vs/base/browser/ui/actionbar/actionbar';
import { IActivityBarService, ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IActivityBarService, DotBadge, 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';
......@@ -125,6 +125,7 @@ export class ActivityActionItem extends BaseActionItem {
super(null, action, options);
this.themeService.onThemeChange(this.onThemeChange, this, this._callOnDispose);
action.onDidChangeBadge(this.handleBadgeChangeEvenet, this, this._callOnDispose);
}
protected updateStyles(): void {
......@@ -155,13 +156,15 @@ export class ActivityActionItem extends BaseActionItem {
public render(container: HTMLElement): void {
super.render(container);
container.title = this.activity.name;
// Label
this.$label = $('a.action-label').appendTo(this.builder);
if (this.activity.cssClass) {
this.$label.addClass(this.activity.cssClass);
}
this.$badge = this.builder.div({ 'class': 'badge' }, (badge: Builder) => {
this.$badge = this.builder.clone().div({ 'class': 'badge' }, (badge: Builder) => {
this.$badgeContent = badge.div({ 'class': 'badge-content' });
});
......@@ -203,6 +206,13 @@ export class ActivityActionItem extends BaseActionItem {
this.$badge.show();
}
// Dot
else if (badge instanceof DotBadge) {
this.$badge.addClass('dot-badge');
this.$badge.title(badge.getDescription());
this.$badge.show();
}
// Progress
else if (badge instanceof ProgressBadge) {
this.$badge.show();
......@@ -212,6 +222,13 @@ export class ActivityActionItem extends BaseActionItem {
}
}
private handleBadgeChangeEvenet(): void {
const action = this.getAction();
if (action instanceof ActivityAction) {
this.updateBadge(action.getBadge());
}
}
public dispose(): void {
super.dispose();
this.$badge.destroy();
......@@ -253,8 +270,6 @@ export class ViewletActionItem extends ActivityActionItem {
if (!ViewletActionItem.toggleViewletPinnedAction) {
ViewletActionItem.toggleViewletPinnedAction = instantiationService.createInstance(ToggleViewletPinnedAction, void 0);
}
action.onDidChangeBadge(this.handleBadgeChangeEvenet, this, this._callOnDispose);
}
private getKeybindingLabel(id: string): string {
......@@ -444,13 +459,6 @@ export class ViewletActionItem extends ActivityActionItem {
}
}
private handleBadgeChangeEvenet(): void {
const action = this.getAction();
if (action instanceof ActivityAction) {
this.updateBadge(action.getBadge());
}
}
protected _updateEnabled(): void {
if (this.getAction().enabled) {
this.builder.removeClass('disabled');
......
......@@ -13,9 +13,9 @@ import * as arrays from 'vs/base/common/arrays';
import { illegalArgument } from 'vs/base/common/errors';
import { Builder, $, Dimension } from 'vs/base/browser/builder';
import { Action } from 'vs/base/common/actions';
import { ActionsOrientation, ActionBar, IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionsOrientation, ActionBar, IActionItem, Separator, IBaseActionItemOptions } from 'vs/base/browser/ui/actionbar/actionbar';
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
import { IActivity, ActivityExtensions, IActivityRegistry } from 'vs/workbench/browser/activity';
import { IGlobalActivity, GlobalActivityExtensions, IGlobalActivityRegistry } from 'vs/workbench/browser/activity';
import { Registry } from 'vs/platform/platform';
import { Part } from 'vs/workbench/browser/part';
import { IViewlet } from 'vs/workbench/common/viewlet';
......@@ -29,7 +29,7 @@ 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, IDisposable } from 'vs/base/common/lifecycle';
import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER } from 'vs/workbench/common/theme';
......@@ -42,17 +42,36 @@ interface IViewletActivity {
class GlobalActivityAction extends ActivityAction {
constructor(activity: IActivity) {
constructor(activity: IGlobalActivity) {
super(activity);
}
}
class GlobalActivityActionItem extends ActivityActionItem {
onClick(event: Event): void {
DOM.EventHelper.stop(event, true);
console.log('hello world');
// fire up native menu around this.builder.getHTMLElement()
constructor(
action: GlobalActivityAction,
options: IBaseActionItemOptions,
@IThemeService themeService: IThemeService,
@IContextMenuService protected contextMenuService: IContextMenuService
) {
super(action, options, themeService);
}
onClick(e: MouseEvent): void {
const globalAction = this._action as GlobalActivityAction;
const activity = globalAction.activity as IGlobalActivity;
const actions = activity.getActions();
const event = new StandardMouseEvent(e);
event.stopPropagation();
event.preventDefault();
this.contextMenuService.showContextMenu({
getAnchor: () => ({ x: event.posx, y: event.posy }),
getActions: () => TPromise.as(actions),
onHide: () => dispose(actions)
});
}
}
......@@ -70,6 +89,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
private viewletOverflowAction: ViewletOverflowActivityAction;
private viewletOverflowActionItem: ViewletOverflowActivityActionItem;
private globalActivityIdToActions: { [globalActivityId: string]: GlobalActivityAction; };
private viewletIdToActions: { [viewletId: string]: ActivityAction; };
private viewletIdToActionItems: { [viewletId: string]: IActionItem; };
private viewletIdToActivityStack: { [viewletId: string]: IViewletActivity[]; };
......@@ -90,6 +110,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
) {
super(id, { hasTitle: false }, themeService);
this.globalActivityIdToActions = Object.create(null);
this.viewletIdToActionItems = Object.create(null);
this.viewletIdToActions = Object.create(null);
this.viewletIdToActivityStack = Object.create(null);
......@@ -142,6 +163,21 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
}
public showGlobalActivity(globalActivityId: string, badge: IBadge): IDisposable {
if (!badge) {
throw illegalArgument('badge');
}
const action = this.globalActivityIdToActions[globalActivityId];
if (!action) {
throw illegalArgument('globalActivityId');
}
action.setBadge(badge);
return toDisposable(() => action.setBadge(undefined));
}
public showActivity(viewletId: string, badge: IBadge, clazz?: string): IDisposable {
if (!badge) {
throw illegalArgument('badge');
......@@ -275,7 +311,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
}
private createGlobalActivityActionBar(container: HTMLElement): void {
const activityRegistry = Registry.as<IActivityRegistry>(ActivityExtensions);
const activityRegistry = Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions);
const descriptors = activityRegistry.getActivities();
const actions = descriptors
.map(d => this.instantiationService.createInstance(d))
......@@ -288,13 +324,10 @@ export class ActivitybarPart extends Part implements IActivityBarService {
animated: false
});
actions.forEach(a => this.activityActionBar.push(a));
this.updateGlobalSwitcher();
}
private updateGlobalSwitcher(): void {
actions.forEach(a => {
this.globalActivityIdToActions[a.id] = a;
this.activityActionBar.push(a);
});
}
private updateViewletSwitcher() {
......
......@@ -67,6 +67,16 @@
text-align: center;
}
.monaco-workbench > .activitybar > .content .monaco-action-bar .badge.dot-badge .badge-content {
box-sizing: border-box;
content: '';
top: 9px;
width: 11px;
height: 11px;
min-width: inherit;
padding: 0;
}
/* Right aligned */
.monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-label {
......
......@@ -8,17 +8,18 @@
import * as nls from 'vs/nls';
import 'vs/css!./media/update.contribution';
import { Registry } from 'vs/platform/platform';
import { isMacintosh } from 'vs/base/common/platform';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ShowCurrentReleaseNotesAction, UpdateContribution } from 'vs/workbench/parts/update/electron-browser/update';
import { ReleaseNotesEditor } from 'vs/workbench/parts/update/electron-browser/releaseNotesEditor';
import { ReleaseNotesInput } from 'vs/workbench/parts/update/electron-browser/releaseNotesInput';
import { EditorDescriptor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { IActivityRegistry, ActivityExtensions, IActivity } from 'vs/workbench/browser/activity';
import { IGlobalActivityRegistry, GlobalActivityExtensions } from 'vs/workbench/browser/activity';
import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { ShowCurrentReleaseNotesAction, UpdateContribution, UpdateContribution2 } from './update';
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(UpdateContribution);
......@@ -34,9 +35,13 @@ const editorDescriptor = new EditorDescriptor(
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
.registerEditor(editorDescriptor, [new SyncDescriptor(ReleaseNotesInput)]);
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Open Release Notes');
if (isMacintosh) {
Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions)
.registerActivity(UpdateContribution2);
} else {
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Open Release Notes');
}
// Configuration: Update
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
......@@ -54,12 +59,3 @@ configurationRegistry.registerConfiguration({
}
}
});
class UpdateGlobalActivity implements IActivity {
id: string = 'update.activity';
name: string = 'Update';
cssClass: string = 'update-activity';
}
Registry.as<IActivityRegistry>(ActivityExtensions)
.registerActivity(UpdateGlobalActivity);
......@@ -8,14 +8,16 @@
import nls = require('vs/nls');
import severity from 'vs/base/common/severity';
import { TPromise } from 'vs/base/common/winjs.base';
import { Action } from 'vs/base/common/actions';
import { IAction, Action } from 'vs/base/common/actions';
import { IMessageService, CloseAction, Severity } from 'vs/platform/message/common/message';
import pkg from 'vs/platform/node/package';
import product from 'vs/platform/node/product';
import URI from 'vs/base/common/uri';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IActivityBarService, DotBadge } from 'vs/workbench/services/activity/common/activityBarService';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ReleaseNotesInput } from 'vs/workbench/parts/update/electron-browser/releaseNotesInput';
import { IGlobalActivity } from 'vs/workbench/browser/activity';
import { IRequestService } from 'vs/platform/request/node/request';
import { asText } from 'vs/base/node/request';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
......@@ -262,4 +264,60 @@ export class UpdateContribution implements IWorkbenchContribution {
updateService.onError(err => messageService.show(severity.Error, err));
}
}
export class UpdateContribution2 implements IGlobalActivity {
get id() { return 'vs.update'; }
get name() { return 'VS Code'; }
get cssClass() { return 'update-activity'; }
constructor(
@IStorageService storageService: IStorageService,
@IInstantiationService instantiationService: IInstantiationService,
@IMessageService messageService: IMessageService,
@IUpdateService updateService: IUpdateService,
@IWorkbenchEditorService editorService: IWorkbenchEditorService,
@IActivityBarService activityBarService: IActivityBarService
) {
// updateService.onUpdateReady(update => {
// const applyUpdateAction = instantiationService.createInstance(ApplyUpdateAction);
// const releaseNotesAction = instantiationService.createInstance(ShowReleaseNotesAction, false, update.version);
// messageService.show(severity.Info, {
// message: nls.localize('updateAvailable', "{0} will be updated after it restarts.", product.nameLong),
// actions: [applyUpdateAction, NotNowAction, releaseNotesAction]
// });
// });
// updateService.onUpdateAvailable(update => {
setTimeout(() => {
const badge = new DotBadge(() => 'UPDATE AVAILABLE');
activityBarService.showGlobalActivity(this.id, badge);
}, 0);
// });
// updateService.onUpdateNotAvailable(explicit => {
// if (!explicit) {
// return;
// }
// messageService.show(severity.Info, nls.localize('noUpdatesAvailable', "There are no updates currently available."));
// });
updateService.onError(err => messageService.show(severity.Error, err));
}
getActions(): IAction[] {
return [
new Action('foo', 'FOO'),
new Action('bar', 'BAR'),
new Action('foo', 'FOO'),
new Action('bar', 'BAR'),
new Action('foo', 'FOO'),
new Action('bar', 'BAR'),
new Action('foo', 'FOO'),
new Action('bar', 'BAR')
];
}
}
\ No newline at end of file
......@@ -24,6 +24,8 @@ export class BaseBadge implements IBadge {
}
}
export class DotBadge extends BaseBadge { }
export class NumberBadge extends BaseBadge {
public number: number;
......@@ -63,6 +65,11 @@ export const IActivityBarService = createDecorator<IActivityBarService>('activit
export interface IActivityBarService {
_serviceBrand: any;
/**
* Show activity in the activitybar for the given global activity.
*/
showGlobalActivity(globalActivityId: string, badge: IBadge): IDisposable;
/**
* Show activity in the activitybar for the given viewlet.
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册