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

Placeholder icons for custom viewlets

上级 88217ad4
......@@ -172,7 +172,8 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution {
id,
descriptor.title,
cssClass,
order
order,
descriptor.icon
);
viewletRegistry.registerViewlet(viewletDescriptor);
......
......@@ -10,7 +10,7 @@ import * as nls from 'vs/nls';
import { illegalArgument } from 'vs/base/common/errors';
import { $ } from 'vs/base/browser/builder';
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 { Part } from 'vs/workbench/browser/part';
import { GlobalActivityActionItem, GlobalActivityAction, ViewletActivityAction, ToggleViewletAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
......@@ -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 { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
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 { 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 {
private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets';
private static readonly PLACEHOLDER_VIEWLETS = 'workbench.activity.placeholderViewlets';
private static readonly COLORS = {
backgroundColor: ACTIVITY_BAR_FOREGROUND,
badgeBackground: ACTIVITY_BAR_BADGE_BACKGROUND,
......@@ -47,6 +56,8 @@ export class ActivitybarPart extends Part {
private globalActionBar: ActionBar;
private globalActivityIdToActions: { [globalActivityId: string]: GlobalActivityAction; };
private placeholderComposites: IPlaceholderComposite[] = [];
private extensionsRegistered: boolean = false;
private compositeBar: CompositeBar;
private compositeActions: { [compositeId: string]: { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } };
......@@ -55,12 +66,15 @@ export class ActivitybarPart extends Part {
@IViewletService private viewletService: IViewletService,
@IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService,
@IThemeService themeService: IThemeService
@IThemeService themeService: IThemeService,
@IStorageService private storageService: IStorageService,
@IExtensionService extensionService: IExtensionService,
) {
super(id, { hasTitle: false }, themeService);
this.globalActivityIdToActions = Object.create(null);
this.placeholderComposites = JSON.parse(this.storageService.get(ActivitybarPart.PLACEHOLDER_VIEWLETS, StorageScope.GLOBAL, '[]'));
this.compositeActions = Object.create(null);
this.compositeBar = this.instantiationService.createInstance(CompositeBar, {
icon: true,
......@@ -80,6 +94,15 @@ export class ActivitybarPart extends Part {
this.registerListeners();
this.updateCompositebar();
this.updatePlaceholderComposites();
extensionService.onDidRegisterExtensions(() => this.onDidRegisterExtensions());
}
private onDidRegisterExtensions(): void {
this.extensionsRegistered = true;
this.removeNotExistingPlaceholderComposites();
this.updateCompositebar();
}
private registerListeners(): void {
......@@ -181,10 +204,19 @@ export class ActivitybarPart extends Part {
private getCompositeActions(compositeId: string): { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } {
let compositeActions = this.compositeActions[compositeId];
if (!compositeActions) {
const viewlet = this.viewletService.getViewlet(compositeId);
if (viewlet) {
compositeActions = {
activityAction: this.instantiationService.createInstance(ViewletActivityAction, this.viewletService.getViewlet(compositeId)),
pinnedAction: new ToggleCompositePinnedAction(this.viewletService.getViewlet(compositeId), this.compositeBar)
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;
}
return compositeActions;
......@@ -193,9 +225,9 @@ export class ActivitybarPart extends Part {
private updateCompositebar(): void {
const viewlets = this.viewletService.getViewlets();
for (const viewlet of viewlets) {
const canShow = this.canShow(viewlet);
if (canShow) {
if (!this.extensionsRegistered || this.canShow(viewlet)) {
this.compositeBar.addComposite(viewlet, false);
this.enableCompositeActions(viewlet);
const activeViewlet = this.viewletService.getActiveViewlet();
if (activeViewlet && activeViewlet.getId() === viewlet.id) {
this.compositeBar.pin(viewlet.id);
......@@ -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 {
this.compositeBar.removeComposite(compositeId);
const compositeActions = this.compositeActions[compositeId];
......@@ -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 {
const viewLocation = ViewLocation.get(viewlet.id);
if (viewLocation) {
......@@ -253,6 +313,8 @@ export class ActivitybarPart extends Part {
}
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();
super.shutdown();
}
......@@ -271,3 +333,42 @@ export class ActivitybarPart extends Part {
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 {
protected _updateClass(): void {
if (this.cssClass) {
this.$badge.removeClass(this.cssClass);
this.$label.removeClass(this.cssClass);
}
this.cssClass = this.getAction().class;
this.$badge.addClass(this.cssClass);
if (this.cssClass) {
this.$label.addClass(this.cssClass);
}
}
protected _updateChecked(): void {
......
......@@ -54,13 +54,13 @@ export class ViewletDescriptor extends CompositeDescriptor<Viewlet> {
name: string,
cssClass?: string,
order?: number,
private _extensionId?: string
private _iconUrl?: string
) {
super(ctor, id, name, cssClass, order, id);
}
public get extensionId(): string {
return this._extensionId;
public get iconUrl(): string {
return this._iconUrl;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册