diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 061381129610c03d7aeea32a7218d33303ffc6cc..691cd72513606c221392e60fa137ef52b4a9fa18 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -37,7 +37,6 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { createCSSRule, asCSSUrl } from 'vs/base/browser/dom'; export interface IUserFriendlyViewsContainerDescriptor { id: string; @@ -254,10 +253,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution { private registerTestViewContainer(): void { const title = localize('test', "Test"); - const cssClass = `extensionViewlet-test`; const icon = URI.parse(require.toUrl('./media/test.svg')); - this.registerCustomViewContainer(TEST_VIEW_CONTAINER_ID, title, icon, TEST_VIEW_CONTAINER_ORDER, cssClass, undefined); + this.registerCustomViewContainer(TEST_VIEW_CONTAINER_ID, title, icon, TEST_VIEW_CONTAINER_ORDER, undefined); } private isValidViewsContainer(viewsContainersDescriptors: IUserFriendlyViewsContainerDescriptor[], collector: ExtensionMessageCollector): boolean { @@ -290,10 +288,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution { private registerCustomViewContainers(containers: IUserFriendlyViewsContainerDescriptor[], extension: IExtensionDescription, order: number, existingViewContainers: ViewContainer[]): number { containers.forEach(descriptor => { - const cssClass = `extensionViewlet-${descriptor.id}`; const icon = resources.joinPath(extension.extensionLocation, descriptor.icon); const id = `workbench.view.extension.${descriptor.id}`; - const viewContainer = this.registerCustomViewContainer(id, descriptor.title, icon, order++, cssClass, extension.identifier); + const viewContainer = this.registerCustomViewContainer(id, descriptor.title, icon, order++, extension.identifier); // Move those views that belongs to this container if (existingViewContainers.length) { @@ -311,7 +308,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { return order; } - private registerCustomViewContainer(id: string, title: string, icon: URI, order: number, cssClass: string, extensionId: ExtensionIdentifier | undefined): ViewContainer { + private registerCustomViewContainer(id: string, title: string, icon: URI, order: number, extensionId: ExtensionIdentifier | undefined): ViewContainer { let viewContainer = this.viewContainersRegistry.get(id); if (!viewContainer) { @@ -339,7 +336,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { CustomViewlet, id, title, - cssClass, + undefined, order, icon ); @@ -363,15 +360,6 @@ class ViewsExtensionHandler implements IWorkbenchContribution { `View: Show ${title}`, localize('view', "View") ); - - // Generate CSS to show the icon in the activity bar - const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`; - createCSSRule(iconClass, ` - mask: ${asCSSUrl(icon)} no-repeat 50% 50%; - mask-size: 24px; - -webkit-mask: ${asCSSUrl(icon)} no-repeat 50% 50%; - -webkit-mask-size: 24px;` - ); } return viewContainer; diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index fdcf9b346d10491bd7783f14ca82e73dbd77d284..45da3780a68a5c9c221f65c2bccde627fd6c3f9e 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -33,15 +33,45 @@ export class ViewletActivityAction extends ActivityAction { private static readonly preventDoubleClickDelay = 300; - private lastRun: number = 0; + private readonly viewletService: IViewletService; + private readonly layoutService: IWorkbenchLayoutService; + private readonly telemetryService: ITelemetryService; + + private lastRun: number; constructor( activity: IActivity, - @IViewletService private readonly viewletService: IViewletService, - @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, - @ITelemetryService private readonly telemetryService: ITelemetryService + @IViewletService viewletService: IViewletService, + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @ITelemetryService telemetryService: ITelemetryService ) { + ViewletActivityAction.generateIconCSS(activity); super(activity); + + this.lastRun = 0; + this.viewletService = viewletService; + this.layoutService = layoutService; + this.telemetryService = telemetryService; + } + + private static generateIconCSS(activity: IActivity): void { + if (activity.iconUrl) { + activity.cssClass = activity.cssClass || `activity-${activity.id.replace(/\./g, '-')}`; + const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${activity.cssClass}`; + DOM.createCSSRule(iconClass, ` + mask: ${DOM.asCSSUrl(activity.iconUrl)} no-repeat 50% 50%; + mask-size: 24px; + -webkit-mask: ${DOM.asCSSUrl(activity.iconUrl)} no-repeat 50% 50%; + -webkit-mask-size: 24px; + `); + } + } + + setActivity(activity: IActivity): void { + if (activity.iconUrl && this.activity.cssClass !== activity.cssClass) { + ViewletActivityAction.generateIconCSS(activity); + } + this.activity = activity; } async run(event: any): Promise { @@ -170,21 +200,7 @@ export class PlaceHolderViewletActivityAction extends ViewletActivityAction { @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ITelemetryService telemetryService: ITelemetryService ) { - super({ id, name: id, cssClass: `extensionViewlet-placeholder-${id.replace(/\./g, '-')}` }, viewletService, layoutService, telemetryService); - - if (iconUrl) { - const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar - DOM.createCSSRule(iconClass, ` - mask: ${DOM.asCSSUrl(iconUrl)} no-repeat 50% 50%; - mask-size: 24px; - -webkit-mask: ${DOM.asCSSUrl(iconUrl)} no-repeat 50% 50%; - -webkit-mask-size: 24px; - `); - } - } - - setActivity(activity: IActivity): void { - this.activity = activity; + super({ id, name: id, iconUrl }, viewletService, layoutService, telemetryService); } } diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index cfcbbf171b1e1e63e4ebf246b0e960e8e6c93779..0f86e922cc39f7d55c63da4dd07873733af0b8d5 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -158,15 +158,12 @@ export class ActivityActionViewItem extends BaseActionViewItem { if (this.label) { if (this.options.icon) { const foreground = this._action.checked ? colors.activeBackgroundColor || colors.activeForegroundColor : colors.inactiveBackgroundColor || colors.inactiveForegroundColor; - // TODO @misolori find a cleaner way to do this - const isExtension = this.activity.cssClass?.indexOf('extensionViewlet') === 0; - if (!isExtension) { - // Apply foreground color to activity bar items (codicons) - this.label.style.color = foreground ? foreground.toString() : ''; - } else { - // Apply background color to extensions + remote explorer (svgs) - + if (this.activity.iconUrl) { + // Apply background color to activity bar item provided with iconUrls this.label.style.backgroundColor = foreground ? foreground.toString() : ''; + } else { + // Apply foreground color to activity bar items provided with codicons + this.label.style.color = foreground ? foreground.toString() : ''; } } else { const foreground = this._action.checked ? colors.activeForegroundColor : colors.inactiveForegroundColor; @@ -242,6 +239,7 @@ export class ActivityActionViewItem extends BaseActionViewItem { this.updateLabel(); this.updateTitle(this.activity.name); this.updateBadge(); + this.updateStyles(); } protected updateBadge(): void { @@ -319,15 +317,14 @@ export class ActivityActionViewItem extends BaseActionViewItem { this.label.className = 'action-label'; if (this.activity.cssClass) { - // TODO @misolori find a cleaner way to do this - const isExtension = this.activity.cssClass?.indexOf('extensionViewlet') === 0; - if (this.options.icon && !isExtension) { - // Only apply icon class to activity bar items (exclude extensions + remote explorer) - dom.addClass(this.label, 'codicon'); - } dom.addClass(this.label, this.activity.cssClass); } + if (this.options.icon && !this.activity.iconUrl) { + // Only apply codicon class to activity bar icon items without iconUrl + dom.addClass(this.label, 'codicon'); + } + if (!this.options.icon) { this.label.textContent = this.getAction().label; } @@ -496,11 +493,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem { activityName = this.compositeActivityAction.activity.name; } - this.compositeActivity = { - id: this.compositeActivityAction.activity.id, - cssClass: this.compositeActivityAction.activity.cssClass, - name: activityName - }; + this.compositeActivity = { ...this.compositeActivityAction.activity, ... { name: activityName } }; } return this.compositeActivity; diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index 5591737dd017f3cb9d0a024f4a7a12c2376c4098..2e4c2f168e18ecf0321df1118cc2d516d555a28a 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -73,14 +73,10 @@ export class ViewletDescriptor extends CompositeDescriptor { name: string, cssClass?: string, order?: number, - private _iconUrl?: URI + readonly iconUrl?: URI ) { super(ctor, id, name, cssClass, order, id); } - - get iconUrl(): URI | undefined { - return this._iconUrl; - } } export const Extensions = { diff --git a/src/vs/workbench/common/activity.ts b/src/vs/workbench/common/activity.ts index 513894f2cea56eadc6ee18119f4c0f9f1a8e7077..79a7c6586a0bb5a594dbcdbf711d02435d6a7db9 100644 --- a/src/vs/workbench/common/activity.ts +++ b/src/vs/workbench/common/activity.ts @@ -3,11 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { URI } from 'vs/base/common/uri'; + export interface IActivity { id: string; name: string; keybindingId?: string; cssClass?: string; + iconUrl?: URI; } -export const GLOBAL_ACTIVITY_ID = 'workbench.action.globalActivity'; \ No newline at end of file +export const GLOBAL_ACTIVITY_ID = 'workbench.action.globalActivity';