提交 e0ca7167 编写于 作者: J JimiC

Add ability to reload themes without restarting the editor

上级 4fd5c099
......@@ -135,15 +135,21 @@ export class ColorThemeData implements IColorTheme {
}
public ensureLoaded(fileService: IFileService): Promise<void> {
if (!this.isLoaded) {
if (this.location) {
return _loadColorTheme(fileService, this.location, this.themeTokenColors, this.colorMap).then(_ => {
this.isLoaded = true;
this.sanitizeTokenColors();
});
}
return !this.isLoaded ? this.load(fileService) : Promise.resolve(undefined);
}
public reload(fileService: IFileService): Promise<void> {
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 {
private constructor() { }
public ensureLoaded(fileService: IFileService): Promise<string> {
if (!this.isLoaded) {
if (this.location) {
return _loadIconThemeDocument(fileService, this.location).then(iconThemeDocument => {
let 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;
});
}
return !this.isLoaded ? this.load(fileService) : Promise.resolve(this.styleSheetContent);
}
public reload(fileService: IFileService): Promise<string> {
return this.load(fileService);
}
private load(fileService: IFileService): Promise<string> {
if (!this.location) {
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 {
......
......@@ -26,7 +26,7 @@ import { FileIconThemeData } from 'vs/workbench/services/themes/electron-browser
import { IWindowService } from 'vs/platform/windows/common/windows';
import { removeClasses, addClasses } from 'vs/base/browser/dom';
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
......@@ -72,10 +72,12 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
private currentColorTheme: ColorThemeData;
private container: HTMLElement;
private readonly onColorThemeChange: Emitter<IColorTheme>;
private onColorThemeFileChangeListener: IDisposable;
private iconThemeStore: FileIconThemeStore;
private currentIconTheme: IFileIconTheme;
private readonly onFileIconThemeChange: Emitter<IFileIconTheme>;
private onIconThemeFileChangeListener: IDisposable;
private themingParticipantChangeListener: IDisposable;
private _configurationWriter: ConfigurationWriter;
......@@ -279,27 +281,54 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
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
return this.colorThemeStore.findThemeData(themeId, DEFAULT_THEME_ID).then(themeData => {
if (themeData) {
return themeData.ensureLoaded(this.fileService).then(_ => {
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.
this.currentColorTheme = themeData;
themeData.setCustomColors(this.colorCustomizations);
themeData.setCustomTokenColors(this.tokenColorCustomizations);
return Promise.resolve(themeData);
}
if (!themeData) {
return null;
}
return themeData.ensureLoaded(this.fileService).then(_ => {
onApply(themeData);
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.
this.currentColorTheme = themeData;
themeData.setCustomColors(this.colorCustomizations);
themeData.setCustomTokenColors(this.tokenColorCustomizations);
this.updateDynamicCSSRules(themeData);
return this.applyTheme(themeData, settingsTarget);
}, error => {
return Promise.reject(new Error(nls.localize('error.cannotloadtheme', "Unable to load {0}: {1}", themeData.location.toString(), error.message)));
});
}
return null;
return Promise.resolve(themeData);
}
themeData.setCustomColors(this.colorCustomizations);
themeData.setCustomTokenColors(this.tokenColorCustomizations);
this.updateDynamicCSSRules(themeData);
return this.applyTheme(themeData, settingsTarget);
}, 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 {
return this.writeFileIconConfiguration(settingsTarget);
}
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);
// remember theme data for a quick restore
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册