Skip to content

Commit fb968f3

Browse files
committed
wip: update contribution 2
1 parent e3c4a2f commit fb968f3

7 files changed

Lines changed: 169 additions & 52 deletions

File tree

src/vs/workbench/browser/activity.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Registry } from 'vs/platform/platform';
7+
import { IAction } from 'vs/base/common/actions';
78
import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
89

910
export interface IActivity {
@@ -12,26 +13,30 @@ export interface IActivity {
1213
cssClass: string;
1314
}
1415

15-
export const ActivityExtensions = 'workbench.contributions.activities';
16+
export interface IGlobalActivity extends IActivity {
17+
getActions(): IAction[];
18+
}
19+
20+
export const GlobalActivityExtensions = 'workbench.contributions.globalActivities';
1621

17-
export interface IActivityRegistry {
18-
registerActivity(descriptor: IConstructorSignature0<IActivity>): void;
19-
getActivities(): IConstructorSignature0<IActivity>[];
22+
export interface IGlobalActivityRegistry {
23+
registerActivity(descriptor: IConstructorSignature0<IGlobalActivity>): void;
24+
getActivities(): IConstructorSignature0<IGlobalActivity>[];
2025
}
2126

22-
export class ActivityRegistry implements IActivityRegistry {
27+
export class GlobalActivityRegistry implements IGlobalActivityRegistry {
2328

24-
private activityDescriptors = new Set<IConstructorSignature0<IActivity>>();
29+
private activityDescriptors = new Set<IConstructorSignature0<IGlobalActivity>>();
2530

26-
registerActivity(descriptor: IConstructorSignature0<IActivity>): void {
31+
registerActivity(descriptor: IConstructorSignature0<IGlobalActivity>): void {
2732
this.activityDescriptors.add(descriptor);
2833
}
2934

30-
getActivities(): IConstructorSignature0<IActivity>[] {
31-
const result: IConstructorSignature0<IActivity>[] = [];
35+
getActivities(): IConstructorSignature0<IGlobalActivity>[] {
36+
const result: IConstructorSignature0<IGlobalActivity>[] = [];
3237
this.activityDescriptors.forEach(d => result.push(d));
3338
return result;
3439
}
3540
}
3641

37-
Registry.add(ActivityExtensions, new ActivityRegistry());
42+
Registry.add(GlobalActivityExtensions, new GlobalActivityRegistry());

src/vs/workbench/browser/parts/activitybar/activitybarActions.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Builder, $ } from 'vs/base/browser/builder';
1313
import { DelayedDragHandler } from 'vs/base/browser/dnd';
1414
import { Action } from 'vs/base/common/actions';
1515
import { BaseActionItem, Separator, IBaseActionItemOptions } from 'vs/base/browser/ui/actionbar/actionbar';
16-
import { IActivityBarService, ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge } from 'vs/workbench/services/activity/common/activityBarService';
16+
import { IActivityBarService, DotBadge, ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge } from 'vs/workbench/services/activity/common/activityBarService';
1717
import Event, { Emitter } from 'vs/base/common/event';
1818
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
1919
import { ICommandService } from 'vs/platform/commands/common/commands';
@@ -125,6 +125,7 @@ export class ActivityActionItem extends BaseActionItem {
125125
super(null, action, options);
126126

127127
this.themeService.onThemeChange(this.onThemeChange, this, this._callOnDispose);
128+
action.onDidChangeBadge(this.handleBadgeChangeEvenet, this, this._callOnDispose);
128129
}
129130

130131
protected updateStyles(): void {
@@ -155,13 +156,15 @@ export class ActivityActionItem extends BaseActionItem {
155156
public render(container: HTMLElement): void {
156157
super.render(container);
157158

159+
container.title = this.activity.name;
160+
158161
// Label
159162
this.$label = $('a.action-label').appendTo(this.builder);
160163
if (this.activity.cssClass) {
161164
this.$label.addClass(this.activity.cssClass);
162165
}
163166

164-
this.$badge = this.builder.div({ 'class': 'badge' }, (badge: Builder) => {
167+
this.$badge = this.builder.clone().div({ 'class': 'badge' }, (badge: Builder) => {
165168
this.$badgeContent = badge.div({ 'class': 'badge-content' });
166169
});
167170

@@ -203,6 +206,13 @@ export class ActivityActionItem extends BaseActionItem {
203206
this.$badge.show();
204207
}
205208

209+
// Dot
210+
else if (badge instanceof DotBadge) {
211+
this.$badge.addClass('dot-badge');
212+
this.$badge.title(badge.getDescription());
213+
this.$badge.show();
214+
}
215+
206216
// Progress
207217
else if (badge instanceof ProgressBadge) {
208218
this.$badge.show();
@@ -212,6 +222,13 @@ export class ActivityActionItem extends BaseActionItem {
212222
}
213223
}
214224

225+
private handleBadgeChangeEvenet(): void {
226+
const action = this.getAction();
227+
if (action instanceof ActivityAction) {
228+
this.updateBadge(action.getBadge());
229+
}
230+
}
231+
215232
public dispose(): void {
216233
super.dispose();
217234
this.$badge.destroy();
@@ -253,8 +270,6 @@ export class ViewletActionItem extends ActivityActionItem {
253270
if (!ViewletActionItem.toggleViewletPinnedAction) {
254271
ViewletActionItem.toggleViewletPinnedAction = instantiationService.createInstance(ToggleViewletPinnedAction, void 0);
255272
}
256-
257-
action.onDidChangeBadge(this.handleBadgeChangeEvenet, this, this._callOnDispose);
258273
}
259274

260275
private getKeybindingLabel(id: string): string {
@@ -444,13 +459,6 @@ export class ViewletActionItem extends ActivityActionItem {
444459
}
445460
}
446461

447-
private handleBadgeChangeEvenet(): void {
448-
const action = this.getAction();
449-
if (action instanceof ActivityAction) {
450-
this.updateBadge(action.getBadge());
451-
}
452-
}
453-
454462
protected _updateEnabled(): void {
455463
if (this.getAction().enabled) {
456464
this.builder.removeClass('disabled');

src/vs/workbench/browser/parts/activitybar/activitybarPart.ts

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import * as arrays from 'vs/base/common/arrays';
1313
import { illegalArgument } from 'vs/base/common/errors';
1414
import { Builder, $, Dimension } from 'vs/base/browser/builder';
1515
import { Action } from 'vs/base/common/actions';
16-
import { ActionsOrientation, ActionBar, IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
16+
import { ActionsOrientation, ActionBar, IActionItem, Separator, IBaseActionItemOptions } from 'vs/base/browser/ui/actionbar/actionbar';
1717
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
18-
import { IActivity, ActivityExtensions, IActivityRegistry } from 'vs/workbench/browser/activity';
18+
import { IGlobalActivity, GlobalActivityExtensions, IGlobalActivityRegistry } from 'vs/workbench/browser/activity';
1919
import { Registry } from 'vs/platform/platform';
2020
import { Part } from 'vs/workbench/browser/part';
2121
import { IViewlet } from 'vs/workbench/common/viewlet';
@@ -29,7 +29,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
2929
import { Scope as MementoScope } from 'vs/workbench/common/memento';
3030
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
3131
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
32-
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
32+
import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
3333
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
3434
import { IThemeService } from 'vs/platform/theme/common/themeService';
3535
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER } from 'vs/workbench/common/theme';
@@ -42,17 +42,36 @@ interface IViewletActivity {
4242

4343
class GlobalActivityAction extends ActivityAction {
4444

45-
constructor(activity: IActivity) {
45+
constructor(activity: IGlobalActivity) {
4646
super(activity);
4747
}
4848
}
4949

5050
class GlobalActivityActionItem extends ActivityActionItem {
5151

52-
onClick(event: Event): void {
53-
DOM.EventHelper.stop(event, true);
54-
console.log('hello world');
55-
// fire up native menu around this.builder.getHTMLElement()
52+
constructor(
53+
action: GlobalActivityAction,
54+
options: IBaseActionItemOptions,
55+
@IThemeService themeService: IThemeService,
56+
@IContextMenuService protected contextMenuService: IContextMenuService
57+
) {
58+
super(action, options, themeService);
59+
}
60+
61+
onClick(e: MouseEvent): void {
62+
const globalAction = this._action as GlobalActivityAction;
63+
const activity = globalAction.activity as IGlobalActivity;
64+
const actions = activity.getActions();
65+
66+
const event = new StandardMouseEvent(e);
67+
event.stopPropagation();
68+
event.preventDefault();
69+
70+
this.contextMenuService.showContextMenu({
71+
getAnchor: () => ({ x: event.posx, y: event.posy }),
72+
getActions: () => TPromise.as(actions),
73+
onHide: () => dispose(actions)
74+
});
5675
}
5776
}
5877

@@ -70,6 +89,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
7089
private viewletOverflowAction: ViewletOverflowActivityAction;
7190
private viewletOverflowActionItem: ViewletOverflowActivityActionItem;
7291

92+
private globalActivityIdToActions: { [globalActivityId: string]: GlobalActivityAction; };
7393
private viewletIdToActions: { [viewletId: string]: ActivityAction; };
7494
private viewletIdToActionItems: { [viewletId: string]: IActionItem; };
7595
private viewletIdToActivityStack: { [viewletId: string]: IViewletActivity[]; };
@@ -90,6 +110,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
90110
) {
91111
super(id, { hasTitle: false }, themeService);
92112

113+
this.globalActivityIdToActions = Object.create(null);
93114
this.viewletIdToActionItems = Object.create(null);
94115
this.viewletIdToActions = Object.create(null);
95116
this.viewletIdToActivityStack = Object.create(null);
@@ -142,6 +163,21 @@ export class ActivitybarPart extends Part implements IActivityBarService {
142163
}
143164
}
144165

166+
public showGlobalActivity(globalActivityId: string, badge: IBadge): IDisposable {
167+
if (!badge) {
168+
throw illegalArgument('badge');
169+
}
170+
171+
const action = this.globalActivityIdToActions[globalActivityId];
172+
173+
if (!action) {
174+
throw illegalArgument('globalActivityId');
175+
}
176+
177+
action.setBadge(badge);
178+
return toDisposable(() => action.setBadge(undefined));
179+
}
180+
145181
public showActivity(viewletId: string, badge: IBadge, clazz?: string): IDisposable {
146182
if (!badge) {
147183
throw illegalArgument('badge');
@@ -275,7 +311,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
275311
}
276312

277313
private createGlobalActivityActionBar(container: HTMLElement): void {
278-
const activityRegistry = Registry.as<IActivityRegistry>(ActivityExtensions);
314+
const activityRegistry = Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions);
279315
const descriptors = activityRegistry.getActivities();
280316
const actions = descriptors
281317
.map(d => this.instantiationService.createInstance(d))
@@ -288,13 +324,10 @@ export class ActivitybarPart extends Part implements IActivityBarService {
288324
animated: false
289325
});
290326

291-
actions.forEach(a => this.activityActionBar.push(a));
292-
293-
this.updateGlobalSwitcher();
294-
}
295-
296-
private updateGlobalSwitcher(): void {
297-
327+
actions.forEach(a => {
328+
this.globalActivityIdToActions[a.id] = a;
329+
this.activityActionBar.push(a);
330+
});
298331
}
299332

300333
private updateViewletSwitcher() {

src/vs/workbench/browser/parts/activitybar/media/activityaction.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@
6767
text-align: center;
6868
}
6969

70+
.monaco-workbench > .activitybar > .content .monaco-action-bar .badge.dot-badge .badge-content {
71+
box-sizing: border-box;
72+
content: '';
73+
top: 9px;
74+
width: 11px;
75+
height: 11px;
76+
min-width: inherit;
77+
padding: 0;
78+
}
79+
7080
/* Right aligned */
7181

7282
.monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-label {

src/vs/workbench/parts/update/electron-browser/update.contribution.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88
import * as nls from 'vs/nls';
99
import 'vs/css!./media/update.contribution';
1010
import { Registry } from 'vs/platform/platform';
11+
import { isMacintosh } from 'vs/base/common/platform';
1112
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
12-
import { ShowCurrentReleaseNotesAction, UpdateContribution } from 'vs/workbench/parts/update/electron-browser/update';
1313
import { ReleaseNotesEditor } from 'vs/workbench/parts/update/electron-browser/releaseNotesEditor';
1414
import { ReleaseNotesInput } from 'vs/workbench/parts/update/electron-browser/releaseNotesInput';
1515
import { EditorDescriptor } from 'vs/workbench/browser/parts/editor/baseEditor';
16-
import { IActivityRegistry, ActivityExtensions, IActivity } from 'vs/workbench/browser/activity';
16+
import { IGlobalActivityRegistry, GlobalActivityExtensions } from 'vs/workbench/browser/activity';
1717
import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/common/editor';
1818
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
1919
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actionRegistry';
2020
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
2121
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
22+
import { ShowCurrentReleaseNotesAction, UpdateContribution, UpdateContribution2 } from './update';
2223

2324
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
2425
.registerWorkbenchContribution(UpdateContribution);
@@ -34,9 +35,13 @@ const editorDescriptor = new EditorDescriptor(
3435
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
3536
.registerEditor(editorDescriptor, [new SyncDescriptor(ReleaseNotesInput)]);
3637

37-
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
38-
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Open Release Notes');
39-
38+
if (isMacintosh) {
39+
Registry.as<IGlobalActivityRegistry>(GlobalActivityExtensions)
40+
.registerActivity(UpdateContribution2);
41+
} else {
42+
Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions)
43+
.registerWorkbenchAction(new SyncActionDescriptor(ShowCurrentReleaseNotesAction, ShowCurrentReleaseNotesAction.ID, ShowCurrentReleaseNotesAction.LABEL), 'Open Release Notes');
44+
}
4045

4146
// Configuration: Update
4247
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigurationExtensions.Configuration);
@@ -54,12 +59,3 @@ configurationRegistry.registerConfiguration({
5459
}
5560
}
5661
});
57-
58-
class UpdateGlobalActivity implements IActivity {
59-
id: string = 'update.activity';
60-
name: string = 'Update';
61-
cssClass: string = 'update-activity';
62-
}
63-
64-
Registry.as<IActivityRegistry>(ActivityExtensions)
65-
.registerActivity(UpdateGlobalActivity);

0 commit comments

Comments
 (0)