提交 e0ca7167 编写于 作者: J JimiC

Add ability to reload themes without restarting the editor

上级 4fd5c099
...@@ -135,15 +135,21 @@ export class ColorThemeData implements IColorTheme { ...@@ -135,15 +135,21 @@ export class ColorThemeData implements IColorTheme {
} }
public ensureLoaded(fileService: IFileService): Promise<void> { public ensureLoaded(fileService: IFileService): Promise<void> {
if (!this.isLoaded) { return !this.isLoaded ? this.load(fileService) : Promise.resolve(undefined);
if (this.location) { }
return _loadColorTheme(fileService, this.location, this.themeTokenColors, this.colorMap).then(_ => {
this.isLoaded = true; public reload(fileService: IFileService): Promise<void> {
this.sanitizeTokenColors(); return this.load(fileService);
}); }
}
private load(fileService: IFileService): Promise<void> {
if (!this.location) {
return Promise.resolve(undefined);
} }
return Promise.resolve(undefined); return _loadColorTheme(fileService, this.location, this.themeTokenColors, this.colorMap).then(_ => {
this.isLoaded = true;
this.sanitizeTokenColors();
});
} }
/** /**
......
...@@ -29,20 +29,26 @@ export class FileIconThemeData implements IFileIconTheme { ...@@ -29,20 +29,26 @@ export class FileIconThemeData implements IFileIconTheme {
private constructor() { } private constructor() { }
public ensureLoaded(fileService: IFileService): Promise<string> { public ensureLoaded(fileService: IFileService): Promise<string> {
if (!this.isLoaded) { return !this.isLoaded ? this.load(fileService) : Promise.resolve(this.styleSheetContent);
if (this.location) { }
return _loadIconThemeDocument(fileService, this.location).then(iconThemeDocument => {
let result = _processIconThemeDocument(this.id, this.location!, iconThemeDocument); public reload(fileService: IFileService): Promise<string> {
this.styleSheetContent = result.content; return this.load(fileService);
this.hasFileIcons = result.hasFileIcons; }
this.hasFolderIcons = result.hasFolderIcons;
this.hidesExplorerArrows = result.hidesExplorerArrows; private load(fileService: IFileService): Promise<string> {
this.isLoaded = true; if (!this.location) {
return this.styleSheetContent; return Promise.resolve(this.styleSheetContent);
});
}
} }
return Promise.resolve(this.styleSheetContent); return _loadIconThemeDocument(fileService, this.location).then(iconThemeDocument => {
const result = _processIconThemeDocument(this.id, this.location!, iconThemeDocument);
this.styleSheetContent = result.content;
this.hasFileIcons = result.hasFileIcons;
this.hasFolderIcons = result.hasFolderIcons;
this.hidesExplorerArrows = result.hidesExplorerArrows;
this.isLoaded = true;
return this.styleSheetContent;
});
} }
static fromExtensionTheme(iconTheme: IThemeExtensionPoint, iconThemeLocation: URI, extensionData: ExtensionData): FileIconThemeData { static fromExtensionTheme(iconTheme: IThemeExtensionPoint, iconThemeLocation: URI, extensionData: ExtensionData): FileIconThemeData {
......
...@@ -26,7 +26,7 @@ import { FileIconThemeData } from 'vs/workbench/services/themes/electron-browser ...@@ -26,7 +26,7 @@ import { FileIconThemeData } from 'vs/workbench/services/themes/electron-browser
import { IWindowService } from 'vs/platform/windows/common/windows'; import { IWindowService } from 'vs/platform/windows/common/windows';
import { removeClasses, addClasses } from 'vs/base/browser/dom'; import { removeClasses, addClasses } from 'vs/base/browser/dom';
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files'; import { IFileService, FileChangeType } from 'vs/platform/files/common/files';
// implementation // implementation
...@@ -72,10 +72,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { ...@@ -72,10 +72,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
private currentColorTheme: ColorThemeData; private currentColorTheme: ColorThemeData;
private container: HTMLElement; private container: HTMLElement;
private readonly onColorThemeChange: Emitter<IColorTheme>; private readonly onColorThemeChange: Emitter<IColorTheme>;
private onColorThemeFileChangeListener: IDisposable;
private iconThemeStore: FileIconThemeStore; private iconThemeStore: FileIconThemeStore;
private currentIconTheme: IFileIconTheme; private currentIconTheme: IFileIconTheme;
private readonly onFileIconThemeChange: Emitter<IFileIconTheme>; private readonly onFileIconThemeChange: Emitter<IFileIconTheme>;
private onIconThemeFileChangeListener: IDisposable;
private themingParticipantChangeListener: IDisposable; private themingParticipantChangeListener: IDisposable;
private _configurationWriter: ConfigurationWriter; private _configurationWriter: ConfigurationWriter;
...@@ -279,27 +281,54 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { ...@@ -279,27 +281,54 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return this.writeColorThemeConfiguration(settingsTarget); return this.writeColorThemeConfiguration(settingsTarget);
} }
const onApply = (themeData: ColorThemeData) => {
// determine which color theme file to monitor for changes
if (this.fileService) {
const _currentColorThemeData = this.currentColorTheme as ColorThemeData;
if (!this.onColorThemeFileChangeListener) {
this.onColorThemeFileChangeListener = this.fileService.onFileChanges(e => {
return e.contains(themeData.location, FileChangeType.UPDATED)
&& themeData.reload(this.fileService)
.then(_ => {
themeData.setCustomColors(this.colorCustomizations);
themeData.setCustomTokenColors(this.tokenColorCustomizations);
this.updateDynamicCSSRules(themeData);
});
});
}
// stop monitoring previous color theme file for changes
if (_currentColorThemeData.location) {
this.fileService.unwatchFileChanges(_currentColorThemeData.location);
}
// start monitoring new color theme file for changes
if (themeData.location) {
this.fileService.watchFileChanges(themeData.location);
}
}
};
themeId = validateThemeId(themeId); // migrate theme ids themeId = validateThemeId(themeId); // migrate theme ids
return this.colorThemeStore.findThemeData(themeId, DEFAULT_THEME_ID).then(themeData => { return this.colorThemeStore.findThemeData(themeId, DEFAULT_THEME_ID).then(themeData => {
if (themeData) { if (!themeData) {
return themeData.ensureLoaded(this.fileService).then(_ => { return null;
if (themeId === this.currentColorTheme.id && !this.currentColorTheme.isLoaded && this.currentColorTheme.hasEqualData(themeData)) { }
// the loaded theme is identical to the perisisted theme. Don't need to send an event. return themeData.ensureLoaded(this.fileService).then(_ => {
this.currentColorTheme = themeData; onApply(themeData);
themeData.setCustomColors(this.colorCustomizations); if (themeId === this.currentColorTheme.id && !this.currentColorTheme.isLoaded && this.currentColorTheme.hasEqualData(themeData)) {
themeData.setCustomTokenColors(this.tokenColorCustomizations); // the loaded theme is identical to the perisisted theme. Don't need to send an event.
return Promise.resolve(themeData); this.currentColorTheme = themeData;
}
themeData.setCustomColors(this.colorCustomizations); themeData.setCustomColors(this.colorCustomizations);
themeData.setCustomTokenColors(this.tokenColorCustomizations); themeData.setCustomTokenColors(this.tokenColorCustomizations);
this.updateDynamicCSSRules(themeData); return Promise.resolve(themeData);
return this.applyTheme(themeData, settingsTarget); }
}, error => { themeData.setCustomColors(this.colorCustomizations);
return Promise.reject(new Error(nls.localize('error.cannotloadtheme', "Unable to load {0}: {1}", themeData.location.toString(), error.message))); themeData.setCustomTokenColors(this.tokenColorCustomizations);
}); this.updateDynamicCSSRules(themeData);
} return this.applyTheme(themeData, settingsTarget);
return null; }, error => {
return Promise.reject(new Error(nls.localize('error.cannotloadtheme', "Unable to load {0}: {1}", themeData.location.toString(), error.message)));
});
}); });
} }
...@@ -408,6 +437,28 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { ...@@ -408,6 +437,28 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return this.writeFileIconConfiguration(settingsTarget); return this.writeFileIconConfiguration(settingsTarget);
} }
let onApply = (newIconTheme: FileIconThemeData) => { let onApply = (newIconTheme: FileIconThemeData) => {
// determine which icon theme file to monitor for changes
if (this.currentIconTheme.id !== newIconTheme.id || !this.currentIconTheme.isLoaded) {
if (this.fileService) {
if (!this.onIconThemeFileChangeListener) {
this.onIconThemeFileChangeListener = this.fileService.onFileChanges(e => {
return e.contains(newIconTheme.location, FileChangeType.UPDATED)
&& newIconTheme.reload(this.fileService)
.then(_ => _applyIconTheme(newIconTheme, () => Promise.resolve(this.currentIconTheme)));
});
}
const _currentIconThemeData = this.currentIconTheme as FileIconThemeData;
// stop monitoring previous icon theme file for changes
if (_currentIconThemeData.location) {
this.fileService.unwatchFileChanges(_currentIconThemeData.location);
}
// start monitoring new icon theme file for changes
if (newIconTheme.location) {
this.fileService.watchFileChanges(newIconTheme.location);
}
}
}
this.doSetFileIconTheme(newIconTheme); this.doSetFileIconTheme(newIconTheme);
// remember theme data for a quick restore // remember theme data for a quick restore
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册