提交 f4123caa 编写于 作者: M Martin Aeschlimann

[theming] Support late themingRegistrations, css participation only through themingRegistry

上级 684d0ad5
......@@ -9,6 +9,7 @@ import { Color } from 'vs/base/common/color';
import { IDisposable } from 'vs/base/common/lifecycle';
import platform = require('vs/platform/platform');
import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
import Event, { Emitter } from 'vs/base/common/event';
export let IThemeService = createDecorator<IThemeService>('themeService');
......@@ -49,9 +50,9 @@ export interface IThemeService {
getTheme(): ITheme;
/**
* Register a theming participant that is invoked on every theme change.
* Register a theming participant that is invoked after every theme change.
*/
onThemeChange(participant: IThemingParticipant): IDisposable;
onThemeChange: Event<ITheme>;
}
......@@ -68,18 +69,22 @@ export interface IThemingRegistry {
onThemeChange(participant: IThemingParticipant): IDisposable;
getThemingParticipants(): IThemingParticipant[];
readonly onThemingParticipantAdded: Event<IThemingParticipant>;
}
class ThemingRegistry implements IThemingRegistry {
private themingParticipants: IThemingParticipant[] = [];
private onThemingParticipantAddedEmitter: Emitter<IThemingParticipant>;
constructor() {
this.themingParticipants = [];
this.onThemingParticipantAddedEmitter = new Emitter<IThemingParticipant>();
}
public onThemeChange(participant: IThemingParticipant): IDisposable {
this.themingParticipants.push(participant);
this.onThemingParticipantAddedEmitter.fire(participant);
return {
dispose: () => {
const idx = this.themingParticipants.indexOf(participant);
......@@ -88,6 +93,10 @@ class ThemingRegistry implements IThemingRegistry {
};
}
public get onThemingParticipantAdded(): Event<IThemingParticipant> {
return this.onThemingParticipantAddedEmitter.event;
}
public getThemingParticipants(): IThemingParticipant[] {
return this.themingParticipants;
}
......
......@@ -8,7 +8,7 @@
import 'vs/css!./media/part';
import { Dimension, Builder } from 'vs/base/browser/builder';
import { Component } from 'vs/workbench/common/component';
import { IThemeService, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
export interface IPartOptions {
hasTitle?: boolean;
......@@ -32,11 +32,11 @@ export abstract class Part extends Component {
super(id, themeService);
}
protected onThemeChange(theme: ITheme, collector: ICssStyleCollector): void {
protected onThemeChange(theme: ITheme): void {
// only call if our create() method has been called
if (this.parent) {
super.onThemeChange(theme, collector);
super.onThemeChange(theme);
}
}
......
......@@ -6,7 +6,7 @@
import nls = require('vs/nls');
import { registerColor, editorBackground } from 'vs/platform/theme/common/colorRegistry';
import { IDisposable, Disposable, dispose } from 'vs/base/common/lifecycle';
import { IThemeService, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
import { Color, RGBA } from 'vs/base/common/color';
// < --- Tabs --- >
......@@ -75,20 +75,20 @@ export class Themable extends Disposable {
this.theme = themeService.getTheme();
// Hook up to theme changes
this._toUnbind.push(this.themeService.onThemeChange((theme, collector) => this.onThemeChange(theme, collector)));
this._toUnbind.push(this.themeService.onThemeChange(theme => this.onThemeChange(theme)));
}
protected get toUnbind() {
return this._toUnbind;
}
protected onThemeChange(theme: ITheme, collector: ICssStyleCollector): void {
protected onThemeChange(theme: ITheme): void {
this.theme = theme;
this.updateStyles(theme, collector);
this.updateStyles(theme);
}
protected updateStyles(theme: ITheme, collector: ICssStyleCollector): void {
protected updateStyles(theme: ITheme): void {
// Subclasses to override
}
......
......@@ -58,7 +58,7 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
import * as Constants from 'vs/workbench/parts/search/common/constants';
import { IListService } from 'vs/platform/list/browser/listService';
import { IThemeService, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { IThemeService, ITheme, ICssStyleCollector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { editorFindMatchHighlight } from 'vs/platform/theme/common/colorRegistry';
export class SearchViewlet extends Viewlet {
......@@ -142,14 +142,6 @@ export class SearchViewlet extends Viewlet {
this.updateGlobalPatternExclusions(configuration);
}
protected updateStyles(theme: ITheme, collector: ICssStyleCollector) {
let matchHighlightColor = theme.getColor(editorFindMatchHighlight);
if (matchHighlightColor) {
collector.addRule(`.search-viewlet .findInFileMatch { background-color: ${matchHighlightColor}; }`);
collector.addRule(`.search-viewlet .highlight { background-color: ${matchHighlightColor}; }`);
}
}
public create(parent: Builder): TPromise<void> {
super.create(parent);
......@@ -1372,4 +1364,12 @@ export class SearchViewlet extends Viewlet {
super.dispose();
}
}
\ No newline at end of file
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
let matchHighlightColor = theme.getColor(editorFindMatchHighlight);
if (matchHighlightColor) {
collector.addRule(`.search-viewlet .findInFileMatch { background-color: ${matchHighlightColor}; }`);
collector.addRule(`.search-viewlet .highlight { background-color: ${matchHighlightColor}; }`);
}
});
\ No newline at end of file
......@@ -27,7 +27,7 @@ import { IMessageService } from 'vs/platform/message/common/message';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import Severity from 'vs/base/common/severity';
import { ColorThemeData } from './colorThemeData';
import { ITheme, IThemingParticipant, Extensions as ThemingExtensions, IThemingRegistry } from 'vs/platform/theme/common/themeService';
import { ITheme, Extensions as ThemingExtensions, IThemingRegistry } from 'vs/platform/theme/common/themeService';
import { $ } from 'vs/base/browser/builder';
import Event, { Emitter } from 'vs/base/common/event';
......@@ -186,7 +186,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
private currentIconTheme: IFileIconTheme;
private onFileIconThemeChange: Emitter<IFileIconTheme>;
private themingParticipants: IThemingParticipant[];
private themingParticipantChangeListener: IDisposable;
private _configurationWriter: ConfigurationWriter;
constructor(
......@@ -202,7 +202,6 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
this.container = container;
this.knownColorThemes = [];
this.themingParticipants = [];
// In order to avoid paint flashing for tokens, because
// themes are loaded asynchronously, we need to initialize
......@@ -277,15 +276,8 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return this.onFileIconThemeChange.event;
}
public onThemeChange(participant: IThemingParticipant): IDisposable {
this.themingParticipants.push(participant);
return {
dispose: () => {
const idx = this.themingParticipants.indexOf(participant);
this.themingParticipants.splice(idx, 1);
}
};
public get onThemeChange(): Event<ITheme> {
return this.onColorThemeChange.event;
}
private backupSettings(): TPromise<string> {
......@@ -384,6 +376,11 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
themeId = validateThemeId(themeId); // migrate theme ids
if (this.themingParticipantChangeListener) {
this.themingParticipantChangeListener.dispose();
this.themingParticipantChangeListener = null;
}
let onApply = (newTheme: ColorThemeData) => {
let newThemeId = newTheme.id;
if (this.container) {
......@@ -393,6 +390,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
$(this.container).addClass(newThemeId);
}
this.currentColorTheme = newTheme;
this.themingParticipantChangeListener = themingRegistry.onThemingParticipantAdded(p => this.updateDynamicCSSRules(this.currentColorTheme));
this.sendTelemetry(newTheme.id, newTheme.extensionData, 'color');
......@@ -408,19 +406,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
return this.findThemeData(themeId, DEFAULT_THEME_ID).then(themeData => {
if (themeData) {
return themeData.ensureLoaded().then(_ => {
let cssRules = [];
let hasRule = {};
let ruleCollector = {
addRule: (rule: string) => {
if (!hasRule[rule]) {
cssRules.push(rule);
hasRule[rule] = true;
}
}
};
this.themingParticipants.forEach(p => p(themeData, ruleCollector));
themingRegistry.getThemingParticipants().forEach(p => p(themeData, ruleCollector));
_applyRules(cssRules.join('\n'), colorThemeRulesClassName);
this.updateDynamicCSSRules(themeData);
return onApply(themeData);
}, error => {
return TPromise.wrapError(nls.localize('error.cannotloadtheme', "Unable to load {0}: {1}", themeData.path, error.message));
......@@ -430,6 +416,21 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
});
}
private updateDynamicCSSRules(themeData: ITheme) {
let cssRules = [];
let hasRule = {};
let ruleCollector = {
addRule: (rule: string) => {
if (!hasRule[rule]) {
cssRules.push(rule);
hasRule[rule] = true;
}
}
};
themingRegistry.getThemingParticipants().forEach(p => p(themeData, ruleCollector));
_applyRules(cssRules.join('\n'), colorThemeRulesClassName);
}
private writeColorThemeConfiguration(settingsTarget: ConfigurationTarget): TPromise<IFileIconTheme> {
if (!types.isUndefinedOrNull(settingsTarget)) {
return this.configurationWriter.writeConfiguration(COLOR_THEME_SETTING, this.currentColorTheme.settingsId, settingsTarget).then(_ => this.currentColorTheme);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册