mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 02:26:04 +00:00
adopt product icon theme in extension actions & picker
This commit is contained in:
parent
1ff8393a58
commit
8d7ef6e898
|
@ -27,7 +27,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID,
|
|||
import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
|
||||
import { EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionToolTipAction, SystemDisabledWarningAction, LocalInstallAction, SyncIgnoredIconAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionToolTipAction, SystemDisabledWarningAction, LocalInstallAction, SyncIgnoredIconAction, SetProductIconThemeAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener';
|
||||
|
@ -317,8 +317,6 @@ export class ExtensionEditor extends BaseEditor {
|
|||
|
||||
private async updateTemplate(input: ExtensionsInput, template: IExtensionEditorTemplate, preserveFocus: boolean): Promise<void> {
|
||||
const runningExtensions = await this.extensionService.getExtensions();
|
||||
const colorThemes = await this.workbenchThemeService.getColorThemes();
|
||||
const fileIconThemes = await this.workbenchThemeService.getFileIconThemes();
|
||||
|
||||
this.activeElement = null;
|
||||
this.editorLoadComplete = false;
|
||||
|
@ -402,8 +400,10 @@ export class ExtensionEditor extends BaseEditor {
|
|||
this.instantiationService.createInstance(SyncIgnoredIconAction),
|
||||
this.instantiationService.createInstance(StatusLabelAction),
|
||||
this.instantiationService.createInstance(UpdateAction),
|
||||
this.instantiationService.createInstance(SetColorThemeAction, colorThemes),
|
||||
this.instantiationService.createInstance(SetFileIconThemeAction, fileIconThemes),
|
||||
this.instantiationService.createInstance(SetColorThemeAction, await this.workbenchThemeService.getColorThemes()),
|
||||
this.instantiationService.createInstance(SetFileIconThemeAction, await this.workbenchThemeService.getFileIconThemes()),
|
||||
this.instantiationService.createInstance(SetProductIconThemeAction, await this.workbenchThemeService.getProductIconThemes()),
|
||||
|
||||
this.instantiationService.createInstance(EnableDropDownAction),
|
||||
this.instantiationService.createInstance(DisableDropDownAction, runningExtensions),
|
||||
this.instantiationService.createInstance(RemoteInstallAction),
|
||||
|
|
|
@ -29,7 +29,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
|
|||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { registerThemingParticipant, IColorTheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { buttonBackground, buttonForeground, buttonHoverBackground, contrastBorder, registerColor, foreground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
|
@ -52,7 +52,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
|||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { IWorkbenchThemeService, ThemeSettings, IWorkbenchFileIconTheme, IWorkbenchColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IWorkbenchThemeService, IWorkbenchTheme, IWorkbenchColorTheme, IWorkbenchFileIconTheme, IWorkbenchProductIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { prefersExecuteOnUI, prefersExecuteOnWorkspace } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
|
@ -237,17 +237,15 @@ export class InstallAction extends ExtensionAction {
|
|||
if (extension && extension.local) {
|
||||
const runningExtension = await this.getRunningExtension(extension.local);
|
||||
if (runningExtension) {
|
||||
const colorThemes = await this.workbenchThemeService.getColorThemes();
|
||||
const fileIconThemes = await this.workbenchThemeService.getFileIconThemes();
|
||||
if (SetColorThemeAction.getColorThemes(colorThemes, this.extension).length) {
|
||||
const action = this.instantiationService.createInstance(SetColorThemeAction, colorThemes);
|
||||
action.extension = extension;
|
||||
return action.run({ showCurrentTheme: true, ignoreFocusLost: true });
|
||||
}
|
||||
if (SetFileIconThemeAction.getFileIconThemes(fileIconThemes, this.extension).length) {
|
||||
const action = this.instantiationService.createInstance(SetFileIconThemeAction, fileIconThemes);
|
||||
action.extension = extension;
|
||||
return action.run({ showCurrentTheme: true, ignoreFocusLost: true });
|
||||
let action = await SetColorThemeAction.create(this.workbenchThemeService, this.instantiationService, extension)
|
||||
|| await SetFileIconThemeAction.create(this.workbenchThemeService, this.instantiationService, extension)
|
||||
|| await SetProductIconThemeAction.create(this.workbenchThemeService, this.instantiationService, extension);
|
||||
if (action) {
|
||||
try {
|
||||
return action.run({ showCurrentTheme: true, ignoreFocusLost: true });
|
||||
} finally {
|
||||
action.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -704,19 +702,22 @@ export class ManageExtensionAction extends ExtensionDropDownAction {
|
|||
this.update();
|
||||
}
|
||||
|
||||
getActionGroups(runningExtensions: IExtensionDescription[], colorThemes: IWorkbenchColorTheme[], fileIconThemes: IWorkbenchFileIconTheme[]): IAction[][] {
|
||||
async getActionGroups(runningExtensions: IExtensionDescription[]): Promise<IAction[][]> {
|
||||
const groups: ExtensionAction[][] = [];
|
||||
if (this.extension) {
|
||||
const extensionColorThemes = SetColorThemeAction.getColorThemes(colorThemes, this.extension);
|
||||
const extensionFileIconThemes = SetFileIconThemeAction.getFileIconThemes(fileIconThemes, this.extension);
|
||||
if (extensionColorThemes.length || extensionFileIconThemes.length) {
|
||||
const themesGroup: ExtensionAction[] = [];
|
||||
if (extensionColorThemes.length) {
|
||||
themesGroup.push(this.instantiationService.createInstance(SetColorThemeAction, colorThemes));
|
||||
}
|
||||
if (extensionFileIconThemes.length) {
|
||||
themesGroup.push(this.instantiationService.createInstance(SetFileIconThemeAction, fileIconThemes));
|
||||
const actions = await Promise.all([
|
||||
SetColorThemeAction.create(this.workbenchThemeService, this.instantiationService, this.extension),
|
||||
SetFileIconThemeAction.create(this.workbenchThemeService, this.instantiationService, this.extension),
|
||||
SetProductIconThemeAction.create(this.workbenchThemeService, this.instantiationService, this.extension)
|
||||
]);
|
||||
|
||||
const themesGroup: ExtensionAction[] = [];
|
||||
for (let action of actions) {
|
||||
if (action) {
|
||||
themesGroup.push(action);
|
||||
}
|
||||
}
|
||||
if (themesGroup.length) {
|
||||
groups.push(themesGroup);
|
||||
}
|
||||
}
|
||||
|
@ -740,9 +741,7 @@ export class ManageExtensionAction extends ExtensionDropDownAction {
|
|||
|
||||
async run(): Promise<any> {
|
||||
const runtimeExtensions = await this.extensionService.getExtensions();
|
||||
const colorThemes = await this.workbenchThemeService.getColorThemes();
|
||||
const fileIconThemes = await this.workbenchThemeService.getFileIconThemes();
|
||||
return super.run({ actionGroups: this.getActionGroups(runtimeExtensions, colorThemes, fileIconThemes), disposeActionsOnHide: true });
|
||||
return super.run({ actionGroups: await this.getActionGroups(runtimeExtensions), disposeActionsOnHide: true });
|
||||
}
|
||||
|
||||
update(): void {
|
||||
|
@ -1301,21 +1300,45 @@ export class ReloadAction extends ExtensionAction {
|
|||
}
|
||||
}
|
||||
|
||||
export class SetColorThemeAction extends ExtensionAction {
|
||||
function isThemeFromExtension(theme: IWorkbenchTheme, extension: IExtension | undefined | null): boolean {
|
||||
return !!(extension && theme.extensionData && ExtensionIdentifier.equals(theme.extensionData.extensionId, extension.identifier.id));
|
||||
}
|
||||
|
||||
static getColorThemes(colorThemes: IWorkbenchColorTheme[], extension: IExtension): IWorkbenchColorTheme[] {
|
||||
return colorThemes.filter(c => c.extensionData && ExtensionIdentifier.equals(c.extensionData.extensionId, extension.identifier.id));
|
||||
function getQuickPickEntries(themes: IWorkbenchTheme[], currentTheme: IWorkbenchTheme, extension: IExtension | null | undefined, showCurrentTheme: boolean): (IQuickPickItem | IQuickPickSeparator)[] {
|
||||
const picks: (IQuickPickItem | IQuickPickSeparator)[] = [];
|
||||
for (const theme of themes) {
|
||||
if (isThemeFromExtension(theme, extension) && !(showCurrentTheme && theme === currentTheme)) {
|
||||
picks.push({ label: theme.label, id: theme.id });
|
||||
}
|
||||
}
|
||||
if (showCurrentTheme) {
|
||||
picks.push(<IQuickPickSeparator>{ type: 'separator', label: localize('current', "Current") });
|
||||
picks.push(<IQuickPickItem>{ label: currentTheme.label, id: currentTheme.id });
|
||||
}
|
||||
return picks;
|
||||
}
|
||||
|
||||
|
||||
export class SetColorThemeAction extends ExtensionAction {
|
||||
|
||||
private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`;
|
||||
private static readonly DisabledClass = `${SetColorThemeAction.EnabledClass} disabled`;
|
||||
|
||||
static async create(workbenchThemeService: IWorkbenchThemeService, instantiationService: IInstantiationService, extension: IExtension): Promise<SetColorThemeAction | undefined> {
|
||||
const themes = await workbenchThemeService.getColorThemes();
|
||||
if (themes.some(th => isThemeFromExtension(th, extension))) {
|
||||
const action = instantiationService.createInstance(SetColorThemeAction, themes);
|
||||
action.extension = extension;
|
||||
return action;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly colorThemes: IWorkbenchColorTheme[],
|
||||
private colorThemes: IWorkbenchColorTheme[],
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(`extensions.colorTheme`, localize('color theme', "Set Color Theme"), SetColorThemeAction.DisabledClass, false);
|
||||
this._register(Event.any<any>(extensionService.onDidChangeExtensions, workbenchThemeService.onDidColorThemeChange)(() => this.update(), this));
|
||||
|
@ -1323,36 +1346,21 @@ export class SetColorThemeAction extends ExtensionAction {
|
|||
}
|
||||
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
if (this.extension) {
|
||||
const isInstalled = this.extension.state === ExtensionState.Installed;
|
||||
if (isInstalled) {
|
||||
const extensionThemes = SetColorThemeAction.getColorThemes(this.colorThemes, this.extension);
|
||||
this.enabled = extensionThemes.length > 0;
|
||||
}
|
||||
}
|
||||
this.enabled = !!this.extension && (this.extension.state === ExtensionState.Installed) && this.colorThemes.some(th => isThemeFromExtension(th, this.extension));
|
||||
this.class = this.enabled ? SetColorThemeAction.EnabledClass : SetColorThemeAction.DisabledClass;
|
||||
}
|
||||
|
||||
async run({ showCurrentTheme, ignoreFocusLost }: { showCurrentTheme: boolean, ignoreFocusLost: boolean } = { showCurrentTheme: false, ignoreFocusLost: false }): Promise<any> {
|
||||
this.colorThemes = await this.workbenchThemeService.getColorThemes();
|
||||
|
||||
this.update();
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
let extensionThemes = SetColorThemeAction.getColorThemes(this.colorThemes, this.extension!);
|
||||
const currentTheme = this.colorThemes.filter(t => t.settingsId === this.configurationService.getValue(ThemeSettings.COLOR_THEME))[0] || this.workbenchThemeService.getColorTheme();
|
||||
showCurrentTheme = showCurrentTheme || extensionThemes.some(t => t.id === currentTheme.id);
|
||||
if (showCurrentTheme) {
|
||||
extensionThemes = extensionThemes.filter(t => t.id !== currentTheme.id);
|
||||
}
|
||||
const currentTheme = this.workbenchThemeService.getColorTheme();
|
||||
|
||||
const delayer = new Delayer<any>(100);
|
||||
const picks: (IQuickPickItem | IQuickPickSeparator)[] = [];
|
||||
picks.push(...extensionThemes.map(theme => (<IQuickPickItem>{ label: theme.label, id: theme.id })));
|
||||
if (showCurrentTheme) {
|
||||
picks.push(<IQuickPickSeparator>{ type: 'separator', label: localize('current', "Current") });
|
||||
picks.push(<IQuickPickItem>{ label: currentTheme.label, id: currentTheme.id });
|
||||
}
|
||||
const picks = getQuickPickEntries(this.colorThemes, currentTheme, this.extension, showCurrentTheme);
|
||||
const pickedTheme = await this.quickInputService.pick(
|
||||
picks,
|
||||
{
|
||||
|
@ -1360,9 +1368,7 @@ export class SetColorThemeAction extends ExtensionAction {
|
|||
onDidFocus: item => delayer.trigger(() => this.workbenchThemeService.setColorTheme(item.id, undefined)),
|
||||
ignoreFocusLost
|
||||
});
|
||||
let confValue = this.configurationService.inspect(ThemeSettings.COLOR_THEME);
|
||||
const target = typeof confValue.workspaceValue !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
|
||||
return this.workbenchThemeService.setColorTheme(pickedTheme ? pickedTheme.id : currentTheme.id, target);
|
||||
return this.workbenchThemeService.setColorTheme(pickedTheme ? pickedTheme.id : currentTheme.id, 'auto');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1371,16 +1377,21 @@ export class SetFileIconThemeAction extends ExtensionAction {
|
|||
private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`;
|
||||
private static readonly DisabledClass = `${SetFileIconThemeAction.EnabledClass} disabled`;
|
||||
|
||||
static getFileIconThemes(fileIconThemes: IWorkbenchFileIconTheme[], extension: IExtension): IWorkbenchFileIconTheme[] {
|
||||
return fileIconThemes.filter(c => c.extensionData && ExtensionIdentifier.equals(c.extensionData.extensionId, extension.identifier.id));
|
||||
static async create(workbenchThemeService: IWorkbenchThemeService, instantiationService: IInstantiationService, extension: IExtension): Promise<SetFileIconThemeAction | undefined> {
|
||||
const themes = await workbenchThemeService.getFileIconThemes();
|
||||
if (themes.some(th => isThemeFromExtension(th, extension))) {
|
||||
const action = instantiationService.createInstance(SetFileIconThemeAction, themes);
|
||||
action.extension = extension;
|
||||
return action;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly fileIconThemes: IWorkbenchFileIconTheme[],
|
||||
private fileIconThemes: IWorkbenchFileIconTheme[],
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService
|
||||
) {
|
||||
super(`extensions.fileIconTheme`, localize('file icon theme', "Set File Icon Theme"), SetFileIconThemeAction.DisabledClass, false);
|
||||
this._register(Event.any<any>(extensionService.onDidChangeExtensions, workbenchThemeService.onDidFileIconThemeChange)(() => this.update(), this));
|
||||
|
@ -1388,36 +1399,20 @@ export class SetFileIconThemeAction extends ExtensionAction {
|
|||
}
|
||||
|
||||
update(): void {
|
||||
this.enabled = false;
|
||||
if (this.extension) {
|
||||
const isInstalled = this.extension.state === ExtensionState.Installed;
|
||||
if (isInstalled) {
|
||||
const extensionThemes = SetFileIconThemeAction.getFileIconThemes(this.fileIconThemes, this.extension);
|
||||
this.enabled = extensionThemes.length > 0;
|
||||
}
|
||||
}
|
||||
this.enabled = !!this.extension && (this.extension.state === ExtensionState.Installed) && this.fileIconThemes.some(th => isThemeFromExtension(th, this.extension));
|
||||
this.class = this.enabled ? SetFileIconThemeAction.EnabledClass : SetFileIconThemeAction.DisabledClass;
|
||||
}
|
||||
|
||||
async run({ showCurrentTheme, ignoreFocusLost }: { showCurrentTheme: boolean, ignoreFocusLost: boolean } = { showCurrentTheme: false, ignoreFocusLost: false }): Promise<any> {
|
||||
await this.update();
|
||||
this.fileIconThemes = await this.workbenchThemeService.getFileIconThemes();
|
||||
this.update();
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
let extensionThemes = SetFileIconThemeAction.getFileIconThemes(this.fileIconThemes, this.extension!);
|
||||
const currentTheme = this.fileIconThemes.filter(t => t.settingsId === this.configurationService.getValue(ThemeSettings.ICON_THEME))[0] || this.workbenchThemeService.getFileIconTheme();
|
||||
showCurrentTheme = showCurrentTheme || extensionThemes.some(t => t.id === currentTheme.id);
|
||||
if (showCurrentTheme) {
|
||||
extensionThemes = extensionThemes.filter(t => t.id !== currentTheme.id);
|
||||
}
|
||||
const currentTheme = this.workbenchThemeService.getFileIconTheme();
|
||||
|
||||
const delayer = new Delayer<any>(100);
|
||||
const picks: (IQuickPickItem | IQuickPickSeparator)[] = [];
|
||||
picks.push(...extensionThemes.map(theme => (<IQuickPickItem>{ label: theme.label, id: theme.id })));
|
||||
if (showCurrentTheme && currentTheme.label) {
|
||||
picks.push(<IQuickPickSeparator>{ type: 'separator', label: localize('current', "Current") });
|
||||
picks.push(<IQuickPickItem>{ label: currentTheme.label, id: currentTheme.id });
|
||||
}
|
||||
const picks = getQuickPickEntries(this.fileIconThemes, currentTheme, this.extension, showCurrentTheme);
|
||||
const pickedTheme = await this.quickInputService.pick(
|
||||
picks,
|
||||
{
|
||||
|
@ -1425,9 +1420,62 @@ export class SetFileIconThemeAction extends ExtensionAction {
|
|||
onDidFocus: item => delayer.trigger(() => this.workbenchThemeService.setFileIconTheme(item.id, undefined)),
|
||||
ignoreFocusLost
|
||||
});
|
||||
let confValue = this.configurationService.inspect(ThemeSettings.ICON_THEME);
|
||||
const target = typeof confValue.workspaceValue !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
|
||||
return this.workbenchThemeService.setFileIconTheme(pickedTheme ? pickedTheme.id : currentTheme.id, target);
|
||||
return this.workbenchThemeService.setFileIconTheme(pickedTheme ? pickedTheme.id : currentTheme.id, 'auto');
|
||||
}
|
||||
}
|
||||
|
||||
export class SetProductIconThemeAction extends ExtensionAction {
|
||||
|
||||
private static readonly EnabledClass = `${ExtensionAction.LABEL_ACTION_CLASS} theme`;
|
||||
private static readonly DisabledClass = `${SetProductIconThemeAction.EnabledClass} disabled`;
|
||||
|
||||
static async create(workbenchThemeService: IWorkbenchThemeService, instantiationService: IInstantiationService, extension: IExtension): Promise<SetProductIconThemeAction | undefined> {
|
||||
const themes = await workbenchThemeService.getProductIconThemes();
|
||||
if (themes.some(th => isThemeFromExtension(th, extension))) {
|
||||
const action = instantiationService.createInstance(SetProductIconThemeAction, themes);
|
||||
action.extension = extension;
|
||||
return action;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private productIconThemes: IWorkbenchProductIconTheme[],
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService
|
||||
) {
|
||||
super(`extensions.productIconTheme`, localize('product icon theme', "Set Product Icon Theme"), SetProductIconThemeAction.DisabledClass, false);
|
||||
this._register(Event.any<any>(extensionService.onDidChangeExtensions, workbenchThemeService.onDidProductIconThemeChange)(() => this.update(), this));
|
||||
this.enabled = true; // enabled by default
|
||||
this.class = SetProductIconThemeAction.EnabledClass;
|
||||
// this.update();
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.enabled = !!this.extension && (this.extension.state === ExtensionState.Installed) && this.productIconThemes.some(th => isThemeFromExtension(th, this.extension));
|
||||
this.class = this.enabled ? SetProductIconThemeAction.EnabledClass : SetProductIconThemeAction.DisabledClass;
|
||||
}
|
||||
|
||||
async run({ showCurrentTheme, ignoreFocusLost }: { showCurrentTheme: boolean, ignoreFocusLost: boolean } = { showCurrentTheme: false, ignoreFocusLost: false }): Promise<any> {
|
||||
this.productIconThemes = await this.workbenchThemeService.getProductIconThemes();
|
||||
this.update();
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentTheme = this.workbenchThemeService.getProductIconTheme();
|
||||
|
||||
const delayer = new Delayer<any>(100);
|
||||
const picks = getQuickPickEntries(this.productIconThemes, currentTheme, this.extension, showCurrentTheme);
|
||||
const pickedTheme = await this.quickInputService.pick(
|
||||
picks,
|
||||
{
|
||||
placeHolder: localize('select product icon theme', "Select Product Icon Theme"),
|
||||
onDidFocus: item => delayer.trigger(() => this.workbenchThemeService.setProductIconTheme(item.id, undefined)),
|
||||
ignoreFocusLost
|
||||
});
|
||||
return this.workbenchThemeService.setProductIconTheme(pickedTheme ? pickedTheme.id : currentTheme.id, 'auto');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ import { createErrorWithActions } from 'vs/base/common/errorsWithActions';
|
|||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import { ExtensionType, ExtensionIdentifier, IExtensionDescription, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
|
||||
|
@ -106,7 +105,6 @@ export class ExtensionsListView extends ViewPane {
|
|||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService protected contextService: IWorkspaceContextService,
|
||||
@IExperimentService private readonly experimentService: IExperimentService,
|
||||
@IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService,
|
||||
@IExtensionManagementServerService protected readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IProductService protected readonly productService: IProductService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
|
@ -233,12 +231,10 @@ export class ExtensionsListView extends ViewPane {
|
|||
private async onContextMenu(e: IListContextMenuEvent<IExtension>): Promise<void> {
|
||||
if (e.element) {
|
||||
const runningExtensions = await this.extensionService.getExtensions();
|
||||
const colorThemes = await this.workbenchThemeService.getColorThemes();
|
||||
const fileIconThemes = await this.workbenchThemeService.getFileIconThemes();
|
||||
const manageExtensionAction = this.instantiationService.createInstance(ManageExtensionAction);
|
||||
manageExtensionAction.extension = e.element;
|
||||
if (manageExtensionAction.enabled) {
|
||||
const groups = manageExtensionAction.getActionGroups(runningExtensions, colorThemes, fileIconThemes);
|
||||
const groups = await manageExtensionAction.getActionGroups(runningExtensions);
|
||||
let actions: IAction[] = [];
|
||||
for (const menuActions of groups) {
|
||||
actions = [...actions, ...menuActions, new Separator()];
|
||||
|
@ -882,7 +878,6 @@ export class ServerExtensionsView extends ExtensionsListView {
|
|||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IExperimentService experimentService: IExperimentService,
|
||||
@IWorkbenchThemeService workbenchThemeService: IWorkbenchThemeService,
|
||||
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IProductService productService: IProductService,
|
||||
|
@ -893,7 +888,7 @@ export class ServerExtensionsView extends ExtensionsListView {
|
|||
@IPreferencesService preferencesService: IPreferencesService,
|
||||
) {
|
||||
options.server = server;
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService, viewDescriptorService, menuService, openerService, preferencesService);
|
||||
super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, extensionManagementServerService, productService, contextKeyService, viewDescriptorService, menuService, openerService, preferencesService);
|
||||
this._register(onDidChangeTitle(title => this.updateTitle(title)));
|
||||
}
|
||||
|
||||
|
|
|
@ -10,18 +10,19 @@ import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes';
|
|||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { IWorkbenchThemeService, ThemeSettings, IWorkbenchColorTheme, IWorkbenchFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IWorkbenchThemeService, IWorkbenchTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { VIEWLET_ID, IExtensionsViewPaneContainer } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IColorRegistry, Extensions as ColorRegistryExtensions } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { LIGHT, DARK, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
|
||||
import { colorThemeSchemaId } from 'vs/workbench/services/themes/common/colorThemeSchema';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { IQuickInputService, QuickPickInput } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { DEFAULT_PRODUCT_ICON_THEME_ID } from 'vs/workbench/services/themes/browser/productIconThemeData';
|
||||
|
||||
export class SelectColorThemeAction extends Action {
|
||||
|
||||
|
@ -34,8 +35,7 @@ export class SelectColorThemeAction extends Action {
|
|||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
|
||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
@IViewletService private readonly viewletService: IViewletService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
@ -60,13 +60,8 @@ export class SelectColorThemeAction extends Action {
|
|||
selectThemeTimeout = window.setTimeout(() => {
|
||||
selectThemeTimeout = undefined;
|
||||
const themeId = theme && theme.id !== undefined ? theme.id : currentTheme.id;
|
||||
let target: ConfigurationTarget | undefined = undefined;
|
||||
if (applyTheme) {
|
||||
const confValue = this.configurationService.inspect(ThemeSettings.COLOR_THEME);
|
||||
target = typeof confValue.workspaceValue !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
|
||||
}
|
||||
|
||||
this.themeService.setColorTheme(themeId, target).then(undefined,
|
||||
this.themeService.setColorTheme(themeId, applyTheme ? 'auto' : undefined).then(undefined,
|
||||
err => {
|
||||
onUnexpectedError(err);
|
||||
this.themeService.setColorTheme(currentTheme.id, undefined);
|
||||
|
@ -108,7 +103,83 @@ export class SelectColorThemeAction extends Action {
|
|||
}
|
||||
}
|
||||
|
||||
class SelectIconThemeAction extends Action {
|
||||
abstract class AbstractIconThemeAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
private readonly quickInputService: IQuickInputService,
|
||||
private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
private readonly viewletService: IViewletService
|
||||
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
protected abstract get builtInEntry(): QuickPickInput<ThemeItem>;
|
||||
protected abstract get installMessage(): string | undefined;
|
||||
protected abstract get placeholderMessage(): string;
|
||||
protected abstract get marketplaceTag(): string;
|
||||
|
||||
protected abstract setTheme(id: string, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise<any>;
|
||||
|
||||
protected pick(themes: IWorkbenchTheme[], currentTheme: IWorkbenchTheme) {
|
||||
let picks: QuickPickInput<ThemeItem>[] = [this.builtInEntry];
|
||||
picks = picks.concat(
|
||||
toEntries(themes),
|
||||
configurationEntries(this.extensionGalleryService, this.installMessage)
|
||||
);
|
||||
|
||||
let selectThemeTimeout: number | undefined;
|
||||
|
||||
const selectTheme = (theme: ThemeItem, applyTheme: boolean) => {
|
||||
if (selectThemeTimeout) {
|
||||
clearTimeout(selectThemeTimeout);
|
||||
}
|
||||
selectThemeTimeout = window.setTimeout(() => {
|
||||
selectThemeTimeout = undefined;
|
||||
const themeId = theme && theme.id !== undefined ? theme.id : currentTheme.id;
|
||||
this.setTheme(themeId, applyTheme ? 'auto' : undefined).then(undefined,
|
||||
err => {
|
||||
onUnexpectedError(err);
|
||||
this.setTheme(currentTheme.id, undefined);
|
||||
}
|
||||
);
|
||||
}, applyTheme ? 0 : 200);
|
||||
};
|
||||
|
||||
return new Promise((s, _) => {
|
||||
let isCompleted = false;
|
||||
|
||||
const autoFocusIndex = firstIndex(picks, p => isItem(p) && p.id === currentTheme.id);
|
||||
const quickpick = this.quickInputService.createQuickPick<ThemeItem>();
|
||||
quickpick.items = picks;
|
||||
quickpick.placeholder = this.placeholderMessage;
|
||||
quickpick.activeItems = [picks[autoFocusIndex] as ThemeItem];
|
||||
quickpick.canSelectMany = false;
|
||||
quickpick.onDidAccept(_ => {
|
||||
const theme = quickpick.activeItems[0];
|
||||
if (!theme || typeof theme.id === 'undefined') { // 'pick in marketplace' entry
|
||||
openExtensionViewlet(this.viewletService, `${this.marketplaceTag} ${quickpick.value}`);
|
||||
} else {
|
||||
selectTheme(theme, true);
|
||||
}
|
||||
isCompleted = true;
|
||||
quickpick.hide();
|
||||
s();
|
||||
});
|
||||
quickpick.onDidChangeActive(themes => selectTheme(themes[0], false));
|
||||
quickpick.onDidHide(() => {
|
||||
if (!isCompleted) {
|
||||
selectTheme(currentTheme, true);
|
||||
s();
|
||||
}
|
||||
});
|
||||
quickpick.show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class SelectFileIconThemeAction extends AbstractIconThemeAction {
|
||||
|
||||
static readonly ID = 'workbench.action.selectIconTheme';
|
||||
static readonly LABEL = localize('selectIconTheme.label', "File Icon Theme");
|
||||
|
@ -116,84 +187,61 @@ class SelectIconThemeAction extends Action {
|
|||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IQuickInputService quickInputService: IQuickInputService,
|
||||
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
|
||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
|
||||
@IViewletService viewletService: IViewletService
|
||||
|
||||
) {
|
||||
super(id, label);
|
||||
super(id, label, quickInputService, extensionGalleryService, viewletService);
|
||||
}
|
||||
|
||||
run(): Promise<void> {
|
||||
return this.themeService.getFileIconThemes().then(themes => {
|
||||
const currentTheme = this.themeService.getFileIconTheme();
|
||||
protected builtInEntry: QuickPickInput<ThemeItem> = { id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') };
|
||||
protected installMessage = localize('installIconThemes', "Install Additional File Icon Themes...");
|
||||
protected placeholderMessage = localize('themes.selectIconTheme', "Select File Icon Theme");
|
||||
protected marketplaceTag = 'tag:icon-theme';
|
||||
protected setTheme(id: string, settingsTarget: ConfigurationTarget | undefined | 'auto') {
|
||||
return this.themeService.setFileIconTheme(id, settingsTarget);
|
||||
}
|
||||
|
||||
let picks: QuickPickInput<ThemeItem>[] = [{ id: '', label: localize('noIconThemeLabel', 'None'), description: localize('noIconThemeDesc', 'Disable file icons') }];
|
||||
picks = picks.concat(
|
||||
toEntries(themes),
|
||||
configurationEntries(this.extensionGalleryService, localize('installIconThemes', "Install Additional File Icon Themes..."))
|
||||
);
|
||||
|
||||
let selectThemeTimeout: number | undefined;
|
||||
|
||||
const selectTheme = (theme: ThemeItem, applyTheme: boolean) => {
|
||||
if (selectThemeTimeout) {
|
||||
clearTimeout(selectThemeTimeout);
|
||||
}
|
||||
selectThemeTimeout = window.setTimeout(() => {
|
||||
selectThemeTimeout = undefined;
|
||||
const themeId = theme && theme.id !== undefined ? theme.id : currentTheme.id;
|
||||
let target: ConfigurationTarget | undefined = undefined;
|
||||
if (applyTheme) {
|
||||
const confValue = this.configurationService.inspect(ThemeSettings.ICON_THEME);
|
||||
target = typeof confValue.workspaceValue !== 'undefined' ? ConfigurationTarget.WORKSPACE : ConfigurationTarget.USER;
|
||||
}
|
||||
this.themeService.setFileIconTheme(themeId, target).then(undefined,
|
||||
err => {
|
||||
onUnexpectedError(err);
|
||||
this.themeService.setFileIconTheme(currentTheme.id, undefined);
|
||||
}
|
||||
);
|
||||
}, applyTheme ? 0 : 200);
|
||||
};
|
||||
|
||||
return new Promise((s, _) => {
|
||||
let isCompleted = false;
|
||||
|
||||
const autoFocusIndex = firstIndex(picks, p => isItem(p) && p.id === currentTheme.id);
|
||||
const quickpick = this.quickInputService.createQuickPick<ThemeItem>();
|
||||
quickpick.items = picks;
|
||||
quickpick.placeholder = localize('themes.selectIconTheme', "Select File Icon Theme");
|
||||
quickpick.activeItems = [picks[autoFocusIndex] as ThemeItem];
|
||||
quickpick.canSelectMany = false;
|
||||
quickpick.onDidAccept(_ => {
|
||||
const theme = quickpick.activeItems[0];
|
||||
if (!theme || typeof theme.id === 'undefined') { // 'pick in marketplace' entry
|
||||
openExtensionViewlet(this.viewletService, `tag:icon-theme ${quickpick.value}`);
|
||||
} else {
|
||||
selectTheme(theme, true);
|
||||
}
|
||||
isCompleted = true;
|
||||
quickpick.hide();
|
||||
s();
|
||||
});
|
||||
quickpick.onDidChangeActive(themes => selectTheme(themes[0], false));
|
||||
quickpick.onDidHide(() => {
|
||||
if (!isCompleted) {
|
||||
selectTheme(currentTheme, true);
|
||||
s();
|
||||
}
|
||||
});
|
||||
quickpick.show();
|
||||
});
|
||||
});
|
||||
async run(): Promise<void> {
|
||||
this.pick(await this.themeService.getFileIconThemes(), this.themeService.getFileIconTheme());
|
||||
}
|
||||
}
|
||||
|
||||
function configurationEntries(extensionGalleryService: IExtensionGalleryService, label: string): QuickPickInput<ThemeItem>[] {
|
||||
if (extensionGalleryService.isEnabled()) {
|
||||
|
||||
class SelectProductIconThemeAction extends AbstractIconThemeAction {
|
||||
|
||||
static readonly ID = 'workbench.action.selectProductIconTheme';
|
||||
static readonly LABEL = localize('selectProductIconTheme.label', "Product Icon Theme");
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IQuickInputService quickInputService: IQuickInputService,
|
||||
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
|
||||
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
|
||||
@IViewletService viewletService: IViewletService
|
||||
|
||||
) {
|
||||
super(id, label, quickInputService, extensionGalleryService, viewletService);
|
||||
}
|
||||
|
||||
protected builtInEntry: QuickPickInput<ThemeItem> = { id: DEFAULT_PRODUCT_ICON_THEME_ID, label: localize('defaultProductIconThemeLabel', 'Default') };
|
||||
protected installMessage = undefined; //localize('installProductIconThemes', "Install Additional Product Icon Themes...");
|
||||
protected placeholderMessage = localize('themes.selectProductIconTheme', "Select Product Icon Theme");
|
||||
protected marketplaceTag = 'tag:product-icon-theme';
|
||||
protected setTheme(id: string, settingsTarget: ConfigurationTarget | undefined | 'auto') {
|
||||
return this.themeService.setProductIconTheme(id, settingsTarget);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.pick(await this.themeService.getProductIconThemes(), this.themeService.getProductIconTheme());
|
||||
}
|
||||
}
|
||||
|
||||
function configurationEntries(extensionGalleryService: IExtensionGalleryService, label: string | undefined): QuickPickInput<ThemeItem>[] {
|
||||
if (extensionGalleryService.isEnabled() && label !== undefined) {
|
||||
return [
|
||||
{
|
||||
type: 'separator'
|
||||
|
@ -227,8 +275,8 @@ function isItem(i: QuickPickInput<ThemeItem>): i is ThemeItem {
|
|||
return (<any>i)['type'] !== 'separator';
|
||||
}
|
||||
|
||||
function toEntries(themes: Array<IWorkbenchColorTheme | IWorkbenchFileIconTheme>, label?: string): QuickPickInput<ThemeItem>[] {
|
||||
const toEntry = (theme: IWorkbenchColorTheme | IWorkbenchFileIconTheme): ThemeItem => ({ id: theme.id, label: theme.label, description: theme.description });
|
||||
function toEntries(themes: Array<IWorkbenchTheme>, label?: string): QuickPickInput<ThemeItem>[] {
|
||||
const toEntry = (theme: IWorkbenchTheme): ThemeItem => ({ id: theme.id, label: theme.label, description: theme.description });
|
||||
const sorter = (t1: ThemeItem, t2: ThemeItem) => t1.label.localeCompare(t2.label);
|
||||
let entries: QuickPickInput<ThemeItem>[] = themes.map(toEntry).sort(sorter);
|
||||
if (entries.length > 0 && label) {
|
||||
|
@ -288,8 +336,11 @@ const category = localize('preferences', "Preferences");
|
|||
const colorThemeDescriptor = SyncActionDescriptor.create(SelectColorThemeAction, SelectColorThemeAction.ID, SelectColorThemeAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_T) });
|
||||
Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions).registerWorkbenchAction(colorThemeDescriptor, 'Preferences: Color Theme', category);
|
||||
|
||||
const iconThemeDescriptor = SyncActionDescriptor.create(SelectIconThemeAction, SelectIconThemeAction.ID, SelectIconThemeAction.LABEL);
|
||||
Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions).registerWorkbenchAction(iconThemeDescriptor, 'Preferences: File Icon Theme', category);
|
||||
const fileIconThemeDescriptor = SyncActionDescriptor.create(SelectFileIconThemeAction, SelectFileIconThemeAction.ID, SelectFileIconThemeAction.LABEL);
|
||||
Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions).registerWorkbenchAction(fileIconThemeDescriptor, 'Preferences: File Icon Theme', category);
|
||||
|
||||
const productIconThemeDescriptor = SyncActionDescriptor.create(SelectProductIconThemeAction, SelectProductIconThemeAction.ID, SelectProductIconThemeAction.LABEL);
|
||||
Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions).registerWorkbenchAction(productIconThemeDescriptor, 'Preferences: Product Icon Theme', category);
|
||||
|
||||
|
||||
const developerCategory = localize('developer', "Developer");
|
||||
|
@ -309,7 +360,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
|
|||
MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
|
||||
group: '4_themes',
|
||||
command: {
|
||||
id: SelectIconThemeAction.ID,
|
||||
id: SelectFileIconThemeAction.ID,
|
||||
title: localize({ key: 'miSelectIconTheme', comment: ['&& denotes a mnemonic'] }, "File &&Icon Theme")
|
||||
},
|
||||
order: 2
|
||||
|
@ -327,7 +378,7 @@ MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
|||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||
group: '4_themes',
|
||||
command: {
|
||||
id: SelectIconThemeAction.ID,
|
||||
id: SelectFileIconThemeAction.ID,
|
||||
title: localize('themes.selectIconTheme.label', "File Icon Theme")
|
||||
},
|
||||
order: 2
|
||||
|
|
|
@ -86,7 +86,7 @@ export class ProductIconThemeData implements IWorkbenchProductIconTheme {
|
|||
static get defaultTheme(): ProductIconThemeData {
|
||||
let themeData = ProductIconThemeData._defaultProductIconTheme;
|
||||
if (!themeData) {
|
||||
themeData = ProductIconThemeData._defaultProductIconTheme = new ProductIconThemeData(DEFAULT_PRODUCT_ICON_THEME_ID, nls.localize('defaultTheme', 'Default theme'), DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE);
|
||||
themeData = ProductIconThemeData._defaultProductIconTheme = new ProductIconThemeData(DEFAULT_PRODUCT_ICON_THEME_ID, nls.localize('defaultTheme', 'Default'), DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE);
|
||||
themeData.isLoaded = true;
|
||||
themeData.extensionData = undefined;
|
||||
themeData.watch = false;
|
||||
|
|
|
@ -263,7 +263,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
|
|||
if (e.affectsConfiguration(ThemeSettings.PREFERRED_HC_THEME) && this.getPreferredColorScheme() === HIGH_CONTRAST) {
|
||||
this.applyPreferredColorTheme(HIGH_CONTRAST);
|
||||
}
|
||||
if (e.affectsConfiguration(ThemeSettings.ICON_THEME)) {
|
||||
if (e.affectsConfiguration(ThemeSettings.FILE_ICON_THEME)) {
|
||||
this.restoreFileIconTheme();
|
||||
}
|
||||
if (e.affectsConfiguration(ThemeSettings.PRODUCT_ICON_THEME)) {
|
||||
|
|
|
@ -78,11 +78,10 @@ const colorCustomizationsSchema: IConfigurationPropertySchema = {
|
|||
}
|
||||
}]
|
||||
};
|
||||
|
||||
const fileIconThemeSettingSchema: IConfigurationPropertySchema = {
|
||||
type: ['string', 'null'],
|
||||
default: DEFAULT_FILE_ICON_THEME_SETTING_VALUE,
|
||||
description: nls.localize('iconTheme', "Specifies the icon theme used in the workbench or 'null' to not show any file icons."),
|
||||
description: nls.localize('iconTheme', "Specifies the file icon theme used in the workbench or 'null' to not show any file icons."),
|
||||
enum: [null],
|
||||
enumDescriptions: [nls.localize('noIconThemeDesc', 'No file icons')],
|
||||
errorMessage: nls.localize('iconThemeError', "File icon theme is unknown or not installed.")
|
||||
|
@ -106,7 +105,7 @@ const themeSettingsConfiguration: IConfigurationNode = {
|
|||
[ThemeSettings.PREFERRED_LIGHT_THEME]: preferredLightThemeSettingSchema,
|
||||
[ThemeSettings.PREFERRED_HC_THEME]: preferredHCThemeSettingSchema,
|
||||
[ThemeSettings.DETECT_COLOR_SCHEME]: detectColorSchemeSettingSchema,
|
||||
[ThemeSettings.ICON_THEME]: fileIconThemeSettingSchema,
|
||||
[ThemeSettings.FILE_ICON_THEME]: fileIconThemeSettingSchema,
|
||||
[ThemeSettings.COLOR_CUSTOMIZATIONS]: colorCustomizationsSchema,
|
||||
[ThemeSettings.PRODUCT_ICON_THEME]: productIconThemeSettingSchema
|
||||
}
|
||||
|
@ -212,7 +211,7 @@ export class ThemeConfiguration {
|
|||
}
|
||||
|
||||
public get fileIconTheme(): string | null {
|
||||
return this.configurationService.getValue<string | null>(ThemeSettings.ICON_THEME);
|
||||
return this.configurationService.getValue<string | null>(ThemeSettings.FILE_ICON_THEME);
|
||||
}
|
||||
|
||||
public get productIconTheme(): string {
|
||||
|
@ -237,7 +236,7 @@ export class ThemeConfiguration {
|
|||
}
|
||||
|
||||
public async setFileIconTheme(theme: IWorkbenchFileIconTheme, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise<IWorkbenchFileIconTheme> {
|
||||
await this.writeConfiguration(ThemeSettings.ICON_THEME, theme.settingsId, settingsTarget);
|
||||
await this.writeConfiguration(ThemeSettings.FILE_ICON_THEME, theme.settingsId, settingsTarget);
|
||||
return theme;
|
||||
}
|
||||
|
||||
|
@ -257,6 +256,8 @@ export class ThemeConfiguration {
|
|||
settingsTarget = ConfigurationTarget.WORKSPACE_FOLDER;
|
||||
} else if (!types.isUndefined(settings.workspaceValue)) {
|
||||
settingsTarget = ConfigurationTarget.WORKSPACE;
|
||||
} else if (!types.isUndefined(settings.userRemote)) {
|
||||
settingsTarget = ConfigurationTarget.USER_REMOTE;
|
||||
} else {
|
||||
settingsTarget = ConfigurationTarget.USER;
|
||||
}
|
||||
|
@ -271,12 +272,11 @@ export class ThemeConfiguration {
|
|||
}
|
||||
value = undefined; // remove configuration from user settings
|
||||
}
|
||||
} else if (settingsTarget === ConfigurationTarget.WORKSPACE || settingsTarget === ConfigurationTarget.WORKSPACE_FOLDER) {
|
||||
} else if (settingsTarget === ConfigurationTarget.WORKSPACE || settingsTarget === ConfigurationTarget.WORKSPACE_FOLDER || settingsTarget === ConfigurationTarget.USER_REMOTE) {
|
||||
if (value === settings.value) {
|
||||
return Promise.resolve(undefined); // nothing to do
|
||||
}
|
||||
}
|
||||
return this.configurationService.updateValue(key, value, settingsTarget);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ export const HC_THEME_ID = 'Default High Contrast';
|
|||
|
||||
export enum ThemeSettings {
|
||||
COLOR_THEME = 'workbench.colorTheme',
|
||||
ICON_THEME = 'workbench.iconTheme',
|
||||
FILE_ICON_THEME = 'workbench.iconTheme',
|
||||
PRODUCT_ICON_THEME = 'workbench.productIconTheme',
|
||||
COLOR_CUSTOMIZATIONS = 'workbench.colorCustomizations',
|
||||
TOKEN_COLOR_CUSTOMIZATIONS = 'editor.tokenColorCustomizations',
|
||||
TOKEN_COLOR_CUSTOMIZATIONS_EXPERIMENTAL = 'editor.tokenColorCustomizationsExperimental',
|
||||
|
@ -29,18 +30,19 @@ export enum ThemeSettings {
|
|||
PREFERRED_LIGHT_THEME = 'workbench.preferredLightColorTheme',
|
||||
PREFERRED_HC_THEME = 'workbench.preferredHighContrastColorTheme',
|
||||
DETECT_COLOR_SCHEME = 'window.autoDetectColorScheme',
|
||||
DETECT_HC = 'window.autoDetectHighContrast',
|
||||
|
||||
PRODUCT_ICON_THEME = 'workbench.productIconTheme'
|
||||
DETECT_HC = 'window.autoDetectHighContrast'
|
||||
}
|
||||
|
||||
export interface IWorkbenchColorTheme extends IColorTheme {
|
||||
export interface IWorkbenchTheme {
|
||||
readonly id: string;
|
||||
readonly label: string;
|
||||
readonly settingsId: string;
|
||||
readonly extensionData?: ExtensionData;
|
||||
readonly description?: string;
|
||||
readonly isLoaded: boolean;
|
||||
readonly settingsId: string | null;
|
||||
}
|
||||
|
||||
export interface IWorkbenchColorTheme extends IWorkbenchTheme, IColorTheme {
|
||||
readonly settingsId: string;
|
||||
readonly tokenColors: ITextMateThemingRule[];
|
||||
}
|
||||
|
||||
|
@ -48,44 +50,28 @@ export interface IColorMap {
|
|||
[id: string]: Color;
|
||||
}
|
||||
|
||||
export interface IWorkbenchFileIconTheme extends IFileIconTheme {
|
||||
readonly id: string;
|
||||
readonly label: string;
|
||||
readonly settingsId: string | null;
|
||||
readonly description?: string;
|
||||
readonly extensionData?: ExtensionData;
|
||||
|
||||
readonly isLoaded: boolean;
|
||||
readonly hasFileIcons: boolean;
|
||||
readonly hasFolderIcons: boolean;
|
||||
readonly hidesExplorerArrows: boolean;
|
||||
export interface IWorkbenchFileIconTheme extends IWorkbenchTheme, IFileIconTheme {
|
||||
}
|
||||
|
||||
export interface IWorkbenchProductIconTheme {
|
||||
readonly id: string;
|
||||
readonly label: string;
|
||||
export interface IWorkbenchProductIconTheme extends IWorkbenchTheme {
|
||||
readonly settingsId: string;
|
||||
readonly description?: string;
|
||||
readonly extensionData?: ExtensionData;
|
||||
|
||||
readonly isLoaded: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface IWorkbenchThemeService extends IThemeService {
|
||||
_serviceBrand: undefined;
|
||||
setColorTheme(themeId: string | undefined, settingsTarget: ConfigurationTarget | undefined): Promise<IWorkbenchColorTheme | null>;
|
||||
setColorTheme(themeId: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise<IWorkbenchColorTheme | null>;
|
||||
getColorTheme(): IWorkbenchColorTheme;
|
||||
getColorThemes(): Promise<IWorkbenchColorTheme[]>;
|
||||
onDidColorThemeChange: Event<IWorkbenchColorTheme>;
|
||||
restoreColorTheme(): void;
|
||||
|
||||
setFileIconTheme(iconThemeId: string | undefined, settingsTarget: ConfigurationTarget | undefined): Promise<IWorkbenchFileIconTheme>;
|
||||
setFileIconTheme(iconThemeId: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise<IWorkbenchFileIconTheme>;
|
||||
getFileIconTheme(): IWorkbenchFileIconTheme;
|
||||
getFileIconThemes(): Promise<IWorkbenchFileIconTheme[]>;
|
||||
onDidFileIconThemeChange: Event<IWorkbenchFileIconTheme>;
|
||||
|
||||
setProductIconTheme(iconThemeId: string | undefined, settingsTarget: ConfigurationTarget | undefined): Promise<IWorkbenchProductIconTheme>;
|
||||
setProductIconTheme(iconThemeId: string | undefined, settingsTarget: ConfigurationTarget | undefined | 'auto'): Promise<IWorkbenchProductIconTheme>;
|
||||
getProductIconTheme(): IWorkbenchProductIconTheme;
|
||||
getProductIconThemes(): Promise<IWorkbenchProductIconTheme[]>;
|
||||
onDidProductIconThemeChange: Event<IWorkbenchProductIconTheme>;
|
||||
|
|
Loading…
Reference in a new issue