提交 86cd46a4 编写于 作者: J Johannes Rieken

deco - allow to derive new decoration from existing decoration, add IDecorationData#source

上级 f9d60296
...@@ -265,7 +265,7 @@ export class Resource implements SourceControlResourceState { ...@@ -265,7 +265,7 @@ export class Resource implements SourceControlResourceState {
const abbreviation = this.letter; const abbreviation = this.letter;
const color = this.color; const color = this.color;
const priority = this.priority; const priority = this.priority;
return { bubble: true, title, abbreviation, color, priority }; return { bubble: true, source: 'git.resource', title, abbreviation, color, priority };
} }
constructor( constructor(
......
...@@ -178,6 +178,7 @@ declare module 'vscode' { ...@@ -178,6 +178,7 @@ declare module 'vscode' {
bubble?: boolean; bubble?: boolean;
abbreviation?: string; abbreviation?: string;
color?: ThemeColor; color?: ThemeColor;
source?: string;
} }
export interface DecorationProvider { export interface DecorationProvider {
......
...@@ -29,23 +29,24 @@ export class MainThreadDecorations implements MainThreadDecorationsShape { ...@@ -29,23 +29,24 @@ export class MainThreadDecorations implements MainThreadDecorationsShape {
this._provider.clear(); this._provider.clear();
} }
$registerDecorationProvider(handle: number): void { $registerDecorationProvider(handle: number, label: string): void {
let emitter = new Emitter<URI[]>(); let emitter = new Emitter<URI[]>();
let registration = this._decorationsService.registerDecorationsProvider({ let registration = this._decorationsService.registerDecorationsProvider({
label: 'extension-provider', label,
onDidChange: emitter.event, onDidChange: emitter.event,
provideDecorations: (uri) => { provideDecorations: (uri) => {
return this._proxy.$providerDecorations(handle, uri).then(data => { return this._proxy.$providerDecorations(handle, uri).then(data => {
if (!data) { if (!data) {
return undefined; return undefined;
} }
const [weight, bubble, title, letter, themeColor] = data; const [weight, bubble, title, letter, themeColor, source] = data;
return { return {
weight: weight || 0, weight: weight || 0,
bubble: bubble || false, bubble: bubble || false,
color: themeColor && themeColor.id,
title, title,
letter, letter,
color: themeColor && themeColor.id source,
}; };
}); });
} }
......
...@@ -378,8 +378,8 @@ export function createApiFactory( ...@@ -378,8 +378,8 @@ export function createApiFactory(
sampleFunction: proposedApiFunction(extension, () => { sampleFunction: proposedApiFunction(extension, () => {
return extHostMessageService.showMessage(extension, Severity.Info, 'Hello Proposed Api!', {}, []); return extHostMessageService.showMessage(extension, Severity.Info, 'Hello Proposed Api!', {}, []);
}), }),
registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => { registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider, source) => {
return extHostDecorations.registerDecorationProvider(provider, extension.id); return extHostDecorations.registerDecorationProvider(provider, source);
}) })
}; };
......
...@@ -625,7 +625,7 @@ export interface ExtHostDebugServiceShape { ...@@ -625,7 +625,7 @@ export interface ExtHostDebugServiceShape {
} }
export type DecorationData = [number, boolean, string, string, ThemeColor]; export type DecorationData = [number, boolean, string, string, ThemeColor, string];
export interface ExtHostDecorationsShape { export interface ExtHostDecorationsShape {
$providerDecorations(handle: number, uri: URI): TPromise<DecorationData>; $providerDecorations(handle: number, uri: URI): TPromise<DecorationData>;
......
...@@ -41,7 +41,7 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { ...@@ -41,7 +41,7 @@ export class ExtHostDecorations implements ExtHostDecorationsShape {
$providerDecorations(handle: number, uri: URI): TPromise<DecorationData> { $providerDecorations(handle: number, uri: URI): TPromise<DecorationData> {
const provider = this._provider.get(handle); const provider = this._provider.get(handle);
return asWinJsPromise(token => provider.provideDecoration(uri, token)).then(data => { return asWinJsPromise(token => provider.provideDecoration(uri, token)).then(data => {
return data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color]; return data && <DecorationData>[data.priority, data.bubble, data.title, data.abbreviation, data.color, data.source];
}); });
} }
} }
...@@ -18,14 +18,15 @@ export interface IDecorationData { ...@@ -18,14 +18,15 @@ export interface IDecorationData {
readonly letter?: string; readonly letter?: string;
readonly title?: string; readonly title?: string;
readonly bubble?: boolean; readonly bubble?: boolean;
readonly source?: string;
} }
export interface IDecoration { export interface IDecoration {
readonly _decoBrand: undefined; readonly title: string;
readonly weight?: number; readonly labelClassName: string;
readonly title?: string; readonly badgeClassName: string;
readonly labelClassName?: string; readonly data: IDecorationData[];
readonly badgeClassName?: string; update(replace: { source?: string, data?: IDecorationData }): IDecoration;
} }
export interface IDecorationsProvider { export interface IDecorationsProvider {
......
...@@ -75,33 +75,6 @@ class DecorationRule { ...@@ -75,33 +75,6 @@ class DecorationRule {
} }
} }
class ResourceDecoration implements IDecoration {
static from(data: IDecorationData | IDecorationData[]): ResourceDecoration {
let result = new ResourceDecoration(data);
if (Array.isArray(data)) {
result.weight = data[0].weight;
result.title = data.map(d => d.title).join(', ');
} else {
result.weight = data.weight;
result.title = data.title;
}
return result;
}
_decoBrand: undefined;
_data: IDecorationData | IDecorationData[];
weight?: number;
title?: string;
labelClassName?: string;
badgeClassName?: string;
private constructor(data: IDecorationData | IDecorationData[]) {
this._data = data;
}
}
class DecorationStyles { class DecorationStyles {
private readonly _disposables: IDisposable[]; private readonly _disposables: IDisposable[];
...@@ -121,10 +94,13 @@ class DecorationStyles { ...@@ -121,10 +94,13 @@ class DecorationStyles {
this._styleElement.parentElement.removeChild(this._styleElement); this._styleElement.parentElement.removeChild(this._styleElement);
} }
asDecoration(data: IDecorationData | IDecorationData[]): ResourceDecoration { asDecoration(data: IDecorationData[], onlyChildren: boolean): IDecoration {
// sort by weight
data.sort((a, b) => b.weight - a.weight);
let key = DecorationRule.keyOf(data); let key = DecorationRule.keyOf(data);
let rule = this._decorationRules.get(key); let rule = this._decorationRules.get(key);
let result = ResourceDecoration.from(data);
if (!rule) { if (!rule) {
// new css rule // new css rule
...@@ -133,9 +109,35 @@ class DecorationStyles { ...@@ -133,9 +109,35 @@ class DecorationStyles {
rule.appendCSSRules(this._styleElement, this._themeService.getTheme()); rule.appendCSSRules(this._styleElement, this._themeService.getTheme());
} }
result.labelClassName = rule.labelClassName; return {
result.badgeClassName = rule.badgeClassName; data,
return result; labelClassName: rule.labelClassName,
badgeClassName: !onlyChildren ? rule.badgeClassName : '',
title: !onlyChildren ? data.filter(d => Boolean(d.title)).map(d => d.title).join(', ') : '',
update: replace => {
let newData = data.slice();
if (!replace.source) {
// add -> just append
newData.push(replace.data);
} else {
// remove/replace -> require a walk
for (let i = 0; i < newData.length; i++) {
if (newData[i].source === replace.source) {
if (!replace.data) {
// remove
newData.splice(i, 1);
i--;
} else {
// replace
newData[i] = replace.data;
}
}
}
}
return this.asDecoration(newData, onlyChildren);
}
};
} }
private _onThemeChange(): void { private _onThemeChange(): void {
...@@ -373,15 +375,8 @@ export class FileDecorationsService implements IDecorationsService { ...@@ -373,15 +375,8 @@ export class FileDecorationsService implements IDecorationsService {
if (data.length === 0) { if (data.length === 0) {
return undefined; return undefined;
} else if (onlyChildren) {
let result = this._decorationStyles.asDecoration(data.sort((a, b) => b.weight - a.weight)[0]);
result.badgeClassName = '';
result.title = '';
return result;
} else if (data.length === 1) {
return this._decorationStyles.asDecoration(data[0]);
} else {
return this._decorationStyles.asDecoration(data.sort((a, b) => b.weight - a.weight));
} }
return this._decorationStyles.asDecoration(data, onlyChildren);
} }
} }
...@@ -120,7 +120,6 @@ suite('DecorationsService', function () { ...@@ -120,7 +120,6 @@ suite('DecorationsService', function () {
let deco = service.getDecoration(childUri, false); let deco = service.getDecoration(childUri, false);
assert.equal(deco.title, '.txt'); assert.equal(deco.title, '.txt');
assert.equal(deco.weight, 17);
deco = service.getDecoration(childUri.with({ path: 'some/path/' }), true); deco = service.getDecoration(childUri.with({ path: 'some/path/' }), true);
assert.equal(deco, undefined); assert.equal(deco, undefined);
...@@ -139,10 +138,8 @@ suite('DecorationsService', function () { ...@@ -139,10 +138,8 @@ suite('DecorationsService', function () {
deco = service.getDecoration(childUri, false); deco = service.getDecoration(childUri, false);
assert.equal(deco.title, '.txt.bubble'); assert.equal(deco.title, '.txt.bubble');
assert.equal(deco.weight, 71);
deco = service.getDecoration(childUri.with({ path: 'some/path/' }), true); deco = service.getDecoration(childUri.with({ path: 'some/path/' }), true);
assert.equal(deco.title, ''); assert.equal(deco.title, '');
assert.equal(deco.weight, 71);
}); });
}); });
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册