提交 054d4777 编写于 作者: S Sandeep Somavarapu

Placeholder icons for custom viewlets

上级 88217ad4
...@@ -172,7 +172,8 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { ...@@ -172,7 +172,8 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
id, id,
descriptor.title, descriptor.title,
cssClass, cssClass,
order order,
descriptor.icon
); );
viewletRegistry.registerViewlet(viewletDescriptor); viewletRegistry.registerViewlet(viewletDescriptor);
......
...@@ -10,7 +10,7 @@ import * as nls from 'vs/nls'; ...@@ -10,7 +10,7 @@ import * as nls from 'vs/nls';
import { illegalArgument } from 'vs/base/common/errors'; import { illegalArgument } from 'vs/base/common/errors';
import { $ } from 'vs/base/browser/builder'; import { $ } from 'vs/base/browser/builder';
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { GlobalActivityExtensions, IGlobalActivityRegistry } from 'vs/workbench/common/activity'; import { GlobalActivityExtensions, IGlobalActivityRegistry, IActivity } from 'vs/workbench/common/activity';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { Part } from 'vs/workbench/browser/part'; import { Part } from 'vs/workbench/browser/part';
import { GlobalActivityActionItem, GlobalActivityAction, ViewletActivityAction, ToggleViewletAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions'; import { GlobalActivityActionItem, GlobalActivityAction, ViewletActivityAction, ToggleViewletAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
...@@ -24,14 +24,23 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; ...@@ -24,14 +24,23 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar'; import { CompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBar';
import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; import { ToggleCompositePinnedAction, ICompositeBar } from 'vs/workbench/browser/parts/compositebar/compositeBarActions';
import { ViewLocation, ViewsRegistry } from 'vs/workbench/common/views'; import { ViewLocation, ViewsRegistry } from 'vs/workbench/common/views';
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet'; import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
import { Dimension } from 'vs/base/browser/dom'; import { Dimension, createCSSRule } from 'vs/base/browser/dom';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
interface IPlaceholderComposite {
id: string;
iconUrl: string;
}
export class ActivitybarPart extends Part { export class ActivitybarPart extends Part {
private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets'; private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets';
private static readonly PLACEHOLDER_VIEWLETS = 'workbench.activity.placeholderViewlets';
private static readonly COLORS = { private static readonly COLORS = {
backgroundColor: ACTIVITY_BAR_FOREGROUND, backgroundColor: ACTIVITY_BAR_FOREGROUND,
badgeBackground: ACTIVITY_BAR_BADGE_BACKGROUND, badgeBackground: ACTIVITY_BAR_BADGE_BACKGROUND,
...@@ -47,6 +56,8 @@ export class ActivitybarPart extends Part { ...@@ -47,6 +56,8 @@ export class ActivitybarPart extends Part {
private globalActionBar: ActionBar; private globalActionBar: ActionBar;
private globalActivityIdToActions: { [globalActivityId: string]: GlobalActivityAction; }; private globalActivityIdToActions: { [globalActivityId: string]: GlobalActivityAction; };
private placeholderComposites: IPlaceholderComposite[] = [];
private extensionsRegistered: boolean = false;
private compositeBar: CompositeBar; private compositeBar: CompositeBar;
private compositeActions: { [compositeId: string]: { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } }; private compositeActions: { [compositeId: string]: { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } };
...@@ -55,12 +66,15 @@ export class ActivitybarPart extends Part { ...@@ -55,12 +66,15 @@ export class ActivitybarPart extends Part {
@IViewletService private viewletService: IViewletService, @IViewletService private viewletService: IViewletService,
@IInstantiationService private instantiationService: IInstantiationService, @IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService, @IPartService private partService: IPartService,
@IThemeService themeService: IThemeService @IThemeService themeService: IThemeService,
@IStorageService private storageService: IStorageService,
@IExtensionService extensionService: IExtensionService,
) { ) {
super(id, { hasTitle: false }, themeService); super(id, { hasTitle: false }, themeService);
this.globalActivityIdToActions = Object.create(null); this.globalActivityIdToActions = Object.create(null);
this.placeholderComposites = JSON.parse(this.storageService.get(ActivitybarPart.PLACEHOLDER_VIEWLETS, StorageScope.GLOBAL, '[]'));
this.compositeActions = Object.create(null); this.compositeActions = Object.create(null);
this.compositeBar = this.instantiationService.createInstance(CompositeBar, { this.compositeBar = this.instantiationService.createInstance(CompositeBar, {
icon: true, icon: true,
...@@ -80,6 +94,15 @@ export class ActivitybarPart extends Part { ...@@ -80,6 +94,15 @@ export class ActivitybarPart extends Part {
this.registerListeners(); this.registerListeners();
this.updateCompositebar(); this.updateCompositebar();
this.updatePlaceholderComposites();
extensionService.onDidRegisterExtensions(() => this.onDidRegisterExtensions());
}
private onDidRegisterExtensions(): void {
this.extensionsRegistered = true;
this.removeNotExistingPlaceholderComposites();
this.updateCompositebar();
} }
private registerListeners(): void { private registerListeners(): void {
...@@ -181,10 +204,19 @@ export class ActivitybarPart extends Part { ...@@ -181,10 +204,19 @@ export class ActivitybarPart extends Part {
private getCompositeActions(compositeId: string): { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } { private getCompositeActions(compositeId: string): { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } {
let compositeActions = this.compositeActions[compositeId]; let compositeActions = this.compositeActions[compositeId];
if (!compositeActions) { if (!compositeActions) {
compositeActions = { const viewlet = this.viewletService.getViewlet(compositeId);
activityAction: this.instantiationService.createInstance(ViewletActivityAction, this.viewletService.getViewlet(compositeId)), if (viewlet) {
pinnedAction: new ToggleCompositePinnedAction(this.viewletService.getViewlet(compositeId), this.compositeBar) compositeActions = {
}; activityAction: this.instantiationService.createInstance(ViewletActivityAction, viewlet),
pinnedAction: new ToggleCompositePinnedAction(viewlet, this.compositeBar)
};
} else {
const placeHolderComposite = this.placeholderComposites.filter(c => c.id === compositeId)[0];
compositeActions = {
activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, placeHolderComposite.iconUrl),
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, placeHolderComposite.iconUrl, this.compositeBar)
};
}
this.compositeActions[compositeId] = compositeActions; this.compositeActions[compositeId] = compositeActions;
} }
return compositeActions; return compositeActions;
...@@ -193,9 +225,9 @@ export class ActivitybarPart extends Part { ...@@ -193,9 +225,9 @@ export class ActivitybarPart extends Part {
private updateCompositebar(): void { private updateCompositebar(): void {
const viewlets = this.viewletService.getViewlets(); const viewlets = this.viewletService.getViewlets();
for (const viewlet of viewlets) { for (const viewlet of viewlets) {
const canShow = this.canShow(viewlet); if (!this.extensionsRegistered || this.canShow(viewlet)) {
if (canShow) {
this.compositeBar.addComposite(viewlet, false); this.compositeBar.addComposite(viewlet, false);
this.enableCompositeActions(viewlet);
const activeViewlet = this.viewletService.getActiveViewlet(); const activeViewlet = this.viewletService.getActiveViewlet();
if (activeViewlet && activeViewlet.getId() === viewlet.id) { if (activeViewlet && activeViewlet.getId() === viewlet.id) {
this.compositeBar.pin(viewlet.id); this.compositeBar.pin(viewlet.id);
...@@ -207,6 +239,24 @@ export class ActivitybarPart extends Part { ...@@ -207,6 +239,24 @@ export class ActivitybarPart extends Part {
} }
} }
private updatePlaceholderComposites(): void {
const viewlets = this.viewletService.getViewlets();
for (const { id } of this.placeholderComposites) {
if (viewlets.every(viewlet => viewlet.id !== id)) {
this.compositeBar.addComposite({ id, name: id, order: void 0 }, false);
}
}
}
private removeNotExistingPlaceholderComposites(): void {
const viewlets = this.viewletService.getViewlets();
for (const { id } of this.placeholderComposites) {
if (viewlets.every(viewlet => viewlet.id !== id)) {
this.removeComposite(id);
}
}
}
private removeComposite(compositeId: string): void { private removeComposite(compositeId: string): void {
this.compositeBar.removeComposite(compositeId); this.compositeBar.removeComposite(compositeId);
const compositeActions = this.compositeActions[compositeId]; const compositeActions = this.compositeActions[compositeId];
...@@ -217,6 +267,16 @@ export class ActivitybarPart extends Part { ...@@ -217,6 +267,16 @@ export class ActivitybarPart extends Part {
} }
} }
private enableCompositeActions(viewlet: ViewletDescriptor): void {
const { activityAction, pinnedAction } = this.getCompositeActions(viewlet.id);
if (activityAction instanceof PlaceHolderViewletActivityAction) {
activityAction.enable(viewlet);
}
if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
pinnedAction.enable(viewlet);
}
}
private canShow(viewlet: ViewletDescriptor): boolean { private canShow(viewlet: ViewletDescriptor): boolean {
const viewLocation = ViewLocation.get(viewlet.id); const viewLocation = ViewLocation.get(viewlet.id);
if (viewLocation) { if (viewLocation) {
...@@ -253,6 +313,8 @@ export class ActivitybarPart extends Part { ...@@ -253,6 +313,8 @@ export class ActivitybarPart extends Part {
} }
public shutdown(): void { public shutdown(): void {
const state = this.viewletService.getViewlets().filter(viewlet => !!viewlet.iconUrl && this.canShow(viewlet)).map(viewlet => ({ id: viewlet.id, iconUrl: viewlet.iconUrl }));
this.storageService.store(ActivitybarPart.PLACEHOLDER_VIEWLETS, JSON.stringify(state), StorageScope.GLOBAL);
this.compositeBar.shutdown(); this.compositeBar.shutdown();
super.shutdown(); super.shutdown();
} }
...@@ -270,4 +332,43 @@ export class ActivitybarPart extends Part { ...@@ -270,4 +332,43 @@ export class ActivitybarPart extends Part {
super.dispose(); super.dispose();
} }
}
class PlaceHolderViewletActivityAction extends ViewletActivityAction {
constructor(
id: string, iconUrl: string,
@IViewletService viewletService: IViewletService,
@IPartService partService: IPartService,
@ITelemetryService telemetryService: ITelemetryService
) {
super({ id, name: id, cssClass: `extensionViewlet-placeholder-${id.replace(/\./g, '-')}` }, viewletService, partService, telemetryService);
// Generate Placeholder CSS to show the icon in the activity bar
const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${this.class}`;
createCSSRule(iconClass, `-webkit-mask: url('${iconUrl}') no-repeat 50% 50%`);
this.enabled = false;
}
enable(activity: IActivity): void {
this.label = activity.name;
this.class = activity.cssClass;
this.enabled = true;
}
}
class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinnedAction {
constructor(
id: string, iconUrl: string, compositeBar: ICompositeBar
) {
super({ id, name: id, cssClass: void 0 }, compositeBar);
this.enabled = false;
}
enable(activity: IActivity): void {
this.label = activity.name;
this.enabled = true;
}
} }
\ No newline at end of file
...@@ -567,11 +567,13 @@ export class CompositeActionItem extends ActivityActionItem { ...@@ -567,11 +567,13 @@ export class CompositeActionItem extends ActivityActionItem {
protected _updateClass(): void { protected _updateClass(): void {
if (this.cssClass) { if (this.cssClass) {
this.$badge.removeClass(this.cssClass); this.$label.removeClass(this.cssClass);
} }
this.cssClass = this.getAction().class; this.cssClass = this.getAction().class;
this.$badge.addClass(this.cssClass); if (this.cssClass) {
this.$label.addClass(this.cssClass);
}
} }
protected _updateChecked(): void { protected _updateChecked(): void {
......
...@@ -54,13 +54,13 @@ export class ViewletDescriptor extends CompositeDescriptor<Viewlet> { ...@@ -54,13 +54,13 @@ export class ViewletDescriptor extends CompositeDescriptor<Viewlet> {
name: string, name: string,
cssClass?: string, cssClass?: string,
order?: number, order?: number,
private _extensionId?: string private _iconUrl?: string
) { ) {
super(ctor, id, name, cssClass, order, id); super(ctor, id, name, cssClass, order, id);
} }
public get extensionId(): string { public get iconUrl(): string {
return this._extensionId; return this._iconUrl;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册