mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 23:44:09 +01:00
Updated API to declarative way for supplying color format.
This commit is contained in:
@@ -9,7 +9,7 @@ import { MarkedString } from 'vs/base/common/htmlContent';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { LanguageId, LanguageIdentifier, ColorMode } from 'vs/editor/common/modes';
|
||||
import { LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
@@ -62,9 +62,11 @@ export interface IModelDecorationOverviewRulerOptions {
|
||||
position: OverviewRulerLane;
|
||||
}
|
||||
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
export interface IColorInfo {
|
||||
color: Color;
|
||||
mode: ColorMode;
|
||||
format: IColorFormat;
|
||||
availableFormats: IColorFormat[];
|
||||
}
|
||||
/**
|
||||
* Options for a model decoration.
|
||||
|
||||
@@ -173,7 +173,8 @@ export interface MarkedStringHover {
|
||||
// TODO@michel documentation
|
||||
export interface ColorHover {
|
||||
color: Color;
|
||||
mode: ColorMode;
|
||||
format: IColorFormat;
|
||||
availableFormats: IColorFormat[];
|
||||
/**
|
||||
* The range to which this hover applies. When missing, the
|
||||
* editor will use the range at the current position or the
|
||||
@@ -676,16 +677,13 @@ export interface LinkProvider {
|
||||
/**
|
||||
* A color inside the editor.
|
||||
*/
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
export interface IColorInfo {
|
||||
color: Color;
|
||||
mode: ColorMode;
|
||||
format: IColorFormat;
|
||||
availableFormats: IColorFormat[];
|
||||
range: IRange;
|
||||
}
|
||||
export enum ColorMode {
|
||||
RGBA = 0,
|
||||
Hex = 1,
|
||||
HSLA = 2
|
||||
}
|
||||
/**
|
||||
* A provider of colors.
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@ import { editorWidgetBackground, editorWidgetBorder } from "vs/platform/theme/co
|
||||
import { ColorProviderRegistry, IColorInfo } from "vs/editor/common/modes";
|
||||
import { TPromise } from "vs/base/common/winjs.base";
|
||||
import { getColors } from "vs/editor/contrib/colorPicker/common/colorPicker";
|
||||
import { IRange } from "vs/editor/common/core/range";
|
||||
|
||||
@editorContribution
|
||||
export class ColorPicker implements IEditorContribution {
|
||||
@@ -83,8 +84,8 @@ export class ColorPicker implements IEditorContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
this.computePromise = getColors(this.editor.getModel()).then(colors => {
|
||||
this.updateDecorations(colors);
|
||||
this.computePromise = getColors(this.editor.getModel()).then(colorInfos => {
|
||||
this.updateDecorations(colorInfos);
|
||||
this.computePromise = null;
|
||||
});
|
||||
}
|
||||
@@ -100,24 +101,30 @@ export class ColorPicker implements IEditorContribution {
|
||||
}
|
||||
}
|
||||
|
||||
private updateDecorations(colors: IColorInfo[]): void {
|
||||
private updateDecorations(colorInfos: IColorInfo[]): void {
|
||||
this.editor.changeDecorations((changeAccessor: IModelDecorationsChangeAccessor) => {
|
||||
let newDecorations: IModelDeltaDecoration[] = [];
|
||||
for (let c of colors) {
|
||||
newDecorations.push({
|
||||
range: {
|
||||
startLineNumber: c.range.startLineNumber,
|
||||
startColumn: c.range.startColumn,
|
||||
endLineNumber: c.range.endLineNumber,
|
||||
endColumn: c.range.endColumn
|
||||
},
|
||||
|
||||
for (let c of colorInfos) {
|
||||
const range: IRange = {
|
||||
startLineNumber: c.range.startLineNumber,
|
||||
startColumn: c.range.startColumn,
|
||||
endLineNumber: c.range.endLineNumber,
|
||||
endColumn: c.range.endColumn
|
||||
};
|
||||
|
||||
const decoration = {
|
||||
range: range,
|
||||
options: {
|
||||
colorInfo: {
|
||||
color: c.color,
|
||||
mode: c.mode
|
||||
format: c.format,
|
||||
availableFormats: c.availableFormats
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
newDecorations.push(decoration);
|
||||
}
|
||||
|
||||
this.currentDecorations = changeAccessor.deltaDecorations(this.currentDecorations, newDecorations);
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
|
||||
import { ColorPickerWidget } from "vs/editor/contrib/colorPicker/browser/colorPickerWidget";
|
||||
import { Color, RGBA } from "vs/base/common/color";
|
||||
import { ColorMode } from "vs/editor/common/modes";
|
||||
import { ColorFormatter } from "vs/editor/contrib/colorPicker/common/colorFormatter";
|
||||
|
||||
export class ColorPickerModel {
|
||||
public widget: ColorPickerWidget;
|
||||
|
||||
public saturationSelection: ISaturationState;
|
||||
public originalColor: string;
|
||||
|
||||
public widget: ColorPickerWidget;
|
||||
private _color: Color;
|
||||
private _selectedColor: string;
|
||||
private _opacity: number;
|
||||
private _hue: Color;
|
||||
|
||||
private _colorModel: ColorMode;
|
||||
private _formatter: ColorFormatter;
|
||||
private _colorModelIndex: number;
|
||||
|
||||
constructor() {
|
||||
@@ -33,13 +33,7 @@ export class ColorPickerModel {
|
||||
this._hue = color;
|
||||
}
|
||||
|
||||
if (this._colorModel === ColorMode.RGBA) {
|
||||
this.selectedColorString = color.toRGBA().toString();
|
||||
} else if (this._colorModel === ColorMode.Hex) {
|
||||
this.selectedColorString = color.toRGBHex();
|
||||
} else {
|
||||
this.selectedColorString = color.toHSLA().toString();
|
||||
}
|
||||
this.selectedColorString = this._formatter.toString(this._color);
|
||||
}
|
||||
|
||||
public get color(): Color {
|
||||
@@ -74,10 +68,6 @@ export class ColorPickerModel {
|
||||
public set opacity(opacity: number) {
|
||||
this._opacity = opacity;
|
||||
|
||||
if (this._colorModel === ColorMode.Hex) {
|
||||
this.colorModel = ColorMode.RGBA;
|
||||
}
|
||||
|
||||
const rgba = this._color.toRGBA();
|
||||
this.color = Color.fromRGBA(new RGBA(rgba.r, rgba.g, rgba.b, opacity * 255));
|
||||
|
||||
@@ -90,33 +80,20 @@ export class ColorPickerModel {
|
||||
return this._opacity;
|
||||
}
|
||||
|
||||
public set colorModel(model: ColorMode) {
|
||||
this._colorModel = model;
|
||||
this._colorModelIndex = model;
|
||||
public set formatter(formatter: ColorFormatter) {
|
||||
this._formatter = formatter;
|
||||
|
||||
if (this._selectedColor) {
|
||||
this.color = this._color; // Refresh selected colour string state
|
||||
}
|
||||
}
|
||||
|
||||
public get colorModel(): ColorMode {
|
||||
return this._colorModel;
|
||||
public get formatter(): ColorFormatter {
|
||||
return this._formatter;
|
||||
}
|
||||
|
||||
public nextColorModel() { // should go to the controller perhaps
|
||||
this._colorModelIndex++;
|
||||
|
||||
if (this._colorModelIndex > 2) {
|
||||
this._colorModelIndex = 0;
|
||||
}
|
||||
|
||||
// Skip hex model if opacity is set
|
||||
if (this._colorModelIndex === ColorMode.Hex && this._opacity !== 1) {
|
||||
this.nextColorModel();
|
||||
return;
|
||||
}
|
||||
|
||||
this.colorModel = this._colorModelIndex;
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ export class ColorPickerBody extends Disposable {
|
||||
const g = c.g;
|
||||
const b = c.b;
|
||||
|
||||
this.opacityOverlay.style.background = `linear-gradient(to bottom, rgba(${r}, ${g}, ${b}, 1) 0%, rgba(${r}, ${g}, ${b}, 0.83) 17%, rgba(${r}, ${g}, ${b}, 0.67) 33%, rgba(${r}, ${g}, ${b}, 0.5) 50%, rgba(${r}, ${g}, ${b}, 0.33) 67%, rgba(${r}, ${g}, ${b}, 0.17) 83%, rgba(${r}, ${g}, ${b}, 0) 100%)`;
|
||||
this.opacityOverlay.style.background = `linear-gradient(to bottom, rgba(${r}, ${g}, ${b}, 1) 0%, rgba(${r}, ${g}, ${b}, 0) 100%)`;
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
@@ -105,7 +105,7 @@ export class ColorPickerBody extends Disposable {
|
||||
}
|
||||
const slider = element === this.hueStrip ? this.hueSlider : this.opacitySlider;
|
||||
const strip = element === this.hueStrip ? this.hueStrip : this.opacityStrip;
|
||||
const initialColorModel = this.model.colorModel;
|
||||
const initialColorModel = this.model.formatter;
|
||||
|
||||
// Update slider position if clicked on a strip itself
|
||||
if (e.target === this.hueStrip || e.target === this.opacityStrip) {
|
||||
@@ -143,8 +143,8 @@ export class ColorPickerBody extends Disposable {
|
||||
updateModel();
|
||||
|
||||
// Change back from RGBA to HEX if opacity touched
|
||||
if (this.model.colorModel !== initialColorModel && this.model.opacity === 1) {
|
||||
this.model.colorModel = initialColorModel;
|
||||
if (this.model.formatter !== initialColorModel && this.model.opacity === 1) {
|
||||
this.model.formatter = initialColorModel;
|
||||
}
|
||||
}, () => {
|
||||
strip.style.cursor = '-webkit-grab';
|
||||
|
||||
@@ -33,12 +33,12 @@ export class ColorPickerHeader extends Disposable {
|
||||
|
||||
public updatePickedColor() {
|
||||
this.pickedColorNode.textContent = this.model.selectedColorString;
|
||||
this.pickedColorNode.style.backgroundColor = this.model.selectedColorString;
|
||||
this.pickedColorNode.style.backgroundColor = this.model.color.toString();
|
||||
}
|
||||
|
||||
private drawPickedColorBox() {
|
||||
this.pickedColorNode = $('.picked-color');
|
||||
this.pickedColorNode.style.backgroundColor = this.model.selectedColorString;
|
||||
this.pickedColorNode.style.backgroundColor = this.model.color.toString();
|
||||
this.pickedColorNode.textContent = this.model.selectedColorString;
|
||||
dom.append(this.domNode, this.pickedColorNode);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Color } from "vs/base/common/color";
|
||||
|
||||
interface Node {
|
||||
(color: Color): string;
|
||||
}
|
||||
|
||||
function createLiteralNode(value: string): Node {
|
||||
return () => value;
|
||||
}
|
||||
|
||||
const RGBA_ENDRANGE = 255;
|
||||
const HSL_HUERANGE = 360;
|
||||
const HSL_ENDRANGE = 1;
|
||||
|
||||
function normalize(value: number, start?: number, end?: number, currentEndRange?: number): number {
|
||||
let val = value;
|
||||
|
||||
if (start || end) {
|
||||
// More safety checks
|
||||
// if (!start) {
|
||||
// throw new Error('Color format range defined is not correct. There is no range start.');
|
||||
// }
|
||||
// if (!end) {
|
||||
// throw new Error('Color format range defined is not correct. There is no range end.');
|
||||
// }
|
||||
if (start > end) {
|
||||
throw new Error('Color format range defined is not correct. Range start is bigger than end.');
|
||||
}
|
||||
if (start === end) {
|
||||
throw new Error('Color format range defined is not correct. Range start is the same as end.');
|
||||
}
|
||||
|
||||
const ratio = val / currentEndRange;
|
||||
val = ratio * (end - start) + start;
|
||||
}
|
||||
|
||||
return val;
|
||||
};
|
||||
|
||||
function createPropertyNode(variable: string, fractionDigits: number, type: string, min: number, max: number): Node {
|
||||
|
||||
return color => {
|
||||
let absoluteValue: number;
|
||||
|
||||
switch (variable) {
|
||||
case 'red':
|
||||
absoluteValue = normalize(color.toRGBA().r, min, max, RGBA_ENDRANGE);
|
||||
break;
|
||||
case 'blue':
|
||||
absoluteValue = normalize(color.toRGBA().g, min, max, RGBA_ENDRANGE);
|
||||
break;
|
||||
case 'green':
|
||||
absoluteValue = normalize(color.toRGBA().b, min, max, RGBA_ENDRANGE);
|
||||
break;
|
||||
case 'alpha':
|
||||
absoluteValue = normalize(color.toRGBA().a, min, max, RGBA_ENDRANGE);
|
||||
break;
|
||||
case 'hue':
|
||||
absoluteValue = normalize(color.toHSLA().h, min, max, HSL_HUERANGE);
|
||||
break;
|
||||
case 'saturation':
|
||||
absoluteValue = normalize(color.toHSLA().s, min, max, HSL_ENDRANGE);
|
||||
break;
|
||||
case 'luminosity':
|
||||
absoluteValue = normalize(color.toHSLA().l, min, max, HSL_ENDRANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (absoluteValue === undefined) {
|
||||
throw new Error(`${variable} is not supported as a color format.`);
|
||||
}
|
||||
|
||||
let value: number | string;
|
||||
if (type === 'f') {
|
||||
fractionDigits = fractionDigits ? fractionDigits : 2; // 2 is default
|
||||
value = absoluteValue.toFixed(fractionDigits);
|
||||
} else if (type === 'x' || type === 'X') {
|
||||
value = normalize(absoluteValue, min, max, RGBA_ENDRANGE).toString(16);
|
||||
|
||||
if (value.length !== 2) {
|
||||
value = '0' + value;
|
||||
}
|
||||
if (type === 'X') {
|
||||
value = value.toUpperCase();
|
||||
}
|
||||
} else { // also 'd'-case
|
||||
value = absoluteValue.toFixed(0);
|
||||
}
|
||||
|
||||
|
||||
return value.toString();
|
||||
};
|
||||
}
|
||||
|
||||
export class ColorFormatter {
|
||||
/*
|
||||
Variables
|
||||
- red
|
||||
- green
|
||||
- blue
|
||||
- hue
|
||||
- saturation
|
||||
- luminosity
|
||||
- alpha
|
||||
|
||||
Number formats
|
||||
- decimal - d
|
||||
- float - f
|
||||
- hex - x X
|
||||
|
||||
Number ranges
|
||||
- 0-1
|
||||
- 0-255
|
||||
- 0-100
|
||||
- arbitrary
|
||||
|
||||
Examples
|
||||
"{red}" - 123
|
||||
"{red:d}" - 123
|
||||
"{red:x}" - af
|
||||
"{red:X}" - AF
|
||||
"{red:d[0-255]}" - AF
|
||||
"{red:x[0-255]}" - AF
|
||||
"{red:X[0-1024]}" - FEFE
|
||||
"{red:2f}" - 123.51
|
||||
"{red:1f}" - 123.5
|
||||
"{red:2f[0-1]}" - 1.23
|
||||
|
||||
- default format: decimal
|
||||
- default range: 0-255
|
||||
*/
|
||||
|
||||
private tree: Node[] = [];
|
||||
|
||||
// Group 0: variable
|
||||
// Group 1: decimal digits
|
||||
// Group 2: floating/integer/hex
|
||||
// Group 3: range begin
|
||||
// Group 4: range end
|
||||
private static PATTERN = /{(\w+)(?::(\d*)(\w)+(?:\[(\d+)-(\d+)\])?)?}/g;
|
||||
|
||||
constructor(format: string) {
|
||||
this.parse(format);
|
||||
// this.tree.push(createLiteralNode('new Color('));
|
||||
// this.tree.push(createPropertyNode('red', 'd', 0, 255));
|
||||
// this.tree.push(createLiteralNode(')'));
|
||||
}
|
||||
|
||||
private parse(format: string): void {
|
||||
let match = ColorFormatter.PATTERN.exec(format);
|
||||
let startIndex = 0;
|
||||
|
||||
// if no match -> erroor throw new Error(`${format} is not consistent with color format syntax.`);
|
||||
while (match !== null) {
|
||||
const index = match.index;
|
||||
|
||||
if (startIndex < index) {
|
||||
this.tree.push(createLiteralNode(format.substring(startIndex, index)));
|
||||
}
|
||||
|
||||
// add more parser catches
|
||||
const variable = match[1];
|
||||
if (!variable) {
|
||||
throw new Error(`${variable} is not defined`);
|
||||
}
|
||||
const decimals = parseInt(match[2]);
|
||||
const type = match[3];
|
||||
const startRange = parseInt(match[4]);
|
||||
const endRange = parseInt(match[5]);
|
||||
|
||||
this.tree.push(createPropertyNode(variable, decimals, type, startRange, endRange));
|
||||
|
||||
startIndex = index + match[0].length;
|
||||
match = ColorFormatter.PATTERN.exec(format);
|
||||
}
|
||||
|
||||
this.tree.push(createLiteralNode(format.substring(startIndex, format.length)));
|
||||
}
|
||||
|
||||
public toString(color: Color): string {
|
||||
let colorString = [];
|
||||
this.tree.forEach(node => {
|
||||
colorString.push(node(color));
|
||||
});
|
||||
|
||||
return colorString.join('');
|
||||
}
|
||||
}
|
||||
@@ -4,28 +4,24 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TPromise } from "vs/base/common/winjs.base";
|
||||
import { ColorProviderRegistry, IColorInfo, ColorProvider } from "vs/editor/common/modes";
|
||||
import { ColorProviderRegistry, IColorInfo } from "vs/editor/common/modes";
|
||||
import { asWinJsPromise } from "vs/base/common/async";
|
||||
import { onUnexpectedExternalError } from "vs/base/common/errors";
|
||||
import { IReadOnlyModel } from "vs/editor/common/editorCommon";
|
||||
|
||||
export function getColors(model: IReadOnlyModel): TPromise<IColorInfo[]> {
|
||||
let colors: IColorInfo[] = [];
|
||||
let colorInfo: IColorInfo[] = [];
|
||||
|
||||
// ask all providers for colors in parallel
|
||||
const promises = ColorProviderRegistry.ordered(model).reverse().map(provider => {
|
||||
return asWinJsPromise(token => provider.provideColors(model, token)).then(result => {
|
||||
if (Array.isArray(result)) {
|
||||
colors = colors.concat(result);
|
||||
colorInfo = colorInfo.concat(result);
|
||||
}
|
||||
}, onUnexpectedExternalError);
|
||||
});
|
||||
|
||||
return TPromise.join(promises).then(() => {
|
||||
return colors;
|
||||
return colorInfo;
|
||||
});
|
||||
}
|
||||
|
||||
export function changeMode(provider: ColorProvider, colorInfo: IColorInfo): TPromise<string> {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDeco
|
||||
import { ColorPickerModel } from "vs/editor/contrib/colorPicker/browser/colorPickerModel";
|
||||
import { ColorPickerWidget } from "vs/editor/contrib/colorPicker/browser/colorPickerWidget";
|
||||
import { IColorInfo } from 'vs/editor/common/editorCommon';
|
||||
import { ColorFormatter } from "vs/editor/contrib/colorPicker/common/colorFormatter";
|
||||
|
||||
class ModesContentComputer implements IHoverComputer<Hover[]> {
|
||||
|
||||
@@ -98,8 +99,9 @@ class ModesContentComputer implements IHoverComputer<Hover[]> {
|
||||
if (colorInfo) {
|
||||
return {
|
||||
color: colorInfo.color,
|
||||
mode: colorInfo.mode,
|
||||
range: range
|
||||
format: colorInfo.format,
|
||||
availableFormats: colorInfo.availableFormats,
|
||||
range: range,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -294,11 +296,16 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
const widget = this._register(new ColorPickerWidget(model, this._editor));
|
||||
model.widget = widget;
|
||||
model.originalColor = msg.color.toRGBA().toString();
|
||||
model.colorModel = msg.mode;
|
||||
if (typeof msg.format !== 'string') { // TODO: take into account opaque and transparent
|
||||
msg.format = msg.format.opaque;
|
||||
}
|
||||
|
||||
model.formatter = new ColorFormatter(msg.format);
|
||||
model.color = msg.color;
|
||||
|
||||
this._colorPicker = widget;
|
||||
fragment.appendChild(widget.getDomNode());
|
||||
console.log(this._editor.getModel());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Vendored
+5
-9
@@ -265,12 +265,7 @@ declare module 'vscode' {
|
||||
static fromHex(hex: string): Color;
|
||||
}
|
||||
|
||||
export enum ColorMode {
|
||||
RGBA = 0,
|
||||
Hex = 1, // should we account for 4-byte hex?
|
||||
HSLA = 2
|
||||
}
|
||||
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
// TODO@Michel
|
||||
export class ColorInfo {
|
||||
/**
|
||||
@@ -280,14 +275,15 @@ declare module 'vscode' {
|
||||
|
||||
color: Color;
|
||||
|
||||
mode: ColorMode;
|
||||
format: IColorFormat;
|
||||
|
||||
constructor(range: Range, color: Color, mode: ColorMode);
|
||||
availableFormats: IColorFormat[];
|
||||
|
||||
constructor(range: Range, color: Color, format: IColorFormat, availableFormats: IColorFormat[]);
|
||||
}
|
||||
|
||||
export interface DocumentColorProvider {
|
||||
provideDocumentColors(document: TextDocument, token: CancellationToken): ProviderResult<ColorInfo[]>;
|
||||
provideColorFormat(colorInfo: ColorInfo): ProviderResult<string>;
|
||||
}
|
||||
|
||||
export namespace languages {
|
||||
|
||||
@@ -269,15 +269,37 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape
|
||||
// --- colors
|
||||
|
||||
$registerDocumentColorProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
const proxy = this._proxy;
|
||||
this._registrations[handle] = modes.ColorProviderRegistry.register(selector, <modes.ColorProvider>{
|
||||
provideColors: (model, token) => {
|
||||
return wireCancellationToken(token, this._proxy.$provideDocumentColors(handle, model.uri))
|
||||
provideColors: function (model, token) {
|
||||
const provider = this;
|
||||
return wireCancellationToken(token, proxy.$provideDocumentColors(handle, model.uri))
|
||||
.then((colorInfos) => {
|
||||
return colorInfos.map(c => {
|
||||
let format: modes.IColorFormat;
|
||||
if (typeof c.format === 'string') {
|
||||
format = c.format;
|
||||
} else {
|
||||
format = { opaque: c.format[0], transparent: c.format[1] };
|
||||
}
|
||||
let availableFormats: modes.IColorFormat[] = [];
|
||||
c.availableFormats.forEach(format => {
|
||||
if (typeof format === 'string') {
|
||||
availableFormats.push(format);
|
||||
} else {
|
||||
availableFormats.push({
|
||||
opaque: format[0],
|
||||
transparent: format[1]
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
color: Color.fromRGBA(new RGBA(c.color[0], c.color[1], c.color[2], c.color[3] * 255)),
|
||||
mode: c.mode,
|
||||
range: c.range
|
||||
format: format,
|
||||
availableFormats: availableFormats,
|
||||
range: c.range,
|
||||
provider: provider
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -492,7 +492,6 @@ export function createApiFactory(
|
||||
CodeLens: extHostTypes.CodeLens,
|
||||
Color: extHostTypes.Color,
|
||||
ColorInfo: extHostTypes.ColorInfo,
|
||||
ColorMode: extHostTypes.ColorMode,
|
||||
EndOfLine: extHostTypes.EndOfLine,
|
||||
CompletionItem: extHostTypes.CompletionItem,
|
||||
CompletionItemKind: extHostTypes.CompletionItemKind,
|
||||
|
||||
@@ -35,7 +35,7 @@ import { IConfigurationData } from 'vs/platform/configuration/common/configurati
|
||||
import { IPickOpenEntry, IPickOptions } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { EndOfLine, TextEditorLineNumbersStyle, ColorMode } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { EndOfLine, TextEditorLineNumbersStyle } from 'vs/workbench/api/node/extHostTypes';
|
||||
|
||||
|
||||
import { TaskSet } from 'vs/workbench/parts/tasks/common/tasks';
|
||||
@@ -453,10 +453,10 @@ export namespace ObjectIdentifier {
|
||||
export abstract class ExtHostHeapServiceShape {
|
||||
$onGarbageCollection(ids: number[]): void { throw ni(); }
|
||||
}
|
||||
|
||||
export interface IColorInfo {
|
||||
color: [number, number, number, number | undefined];
|
||||
mode: ColorMode;
|
||||
format: string | [string, string];
|
||||
availableFormats: (string | [string, string])[];
|
||||
range: IRange;
|
||||
}
|
||||
|
||||
|
||||
@@ -372,9 +372,26 @@ export namespace DocumentLink {
|
||||
|
||||
export namespace DocumentColor {
|
||||
export function from(colorInfo: vscode.ColorInfo): IColorInfo {
|
||||
let format: string | [string, string];
|
||||
if (typeof colorInfo.format === 'string') {
|
||||
format = colorInfo.format;
|
||||
} else {
|
||||
format = [colorInfo.format.opaque, colorInfo.format.transparent];
|
||||
}
|
||||
|
||||
let availableFormats: (string | [string, string])[] = [];
|
||||
colorInfo.availableFormats.forEach(format => {
|
||||
if (typeof format === 'string') {
|
||||
availableFormats.push(format);
|
||||
} else {
|
||||
availableFormats.push([format.opaque, format.transparent]);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
color: [colorInfo.color.red, colorInfo.color.green, colorInfo.color.blue, colorInfo.color.alpha],
|
||||
mode: <number>colorInfo.mode,
|
||||
format: format,
|
||||
availableFormats: availableFormats,
|
||||
range: fromRange(colorInfo.range)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1043,32 +1043,34 @@ export class Color {
|
||||
}
|
||||
}
|
||||
|
||||
export enum ColorMode {
|
||||
RGBA = 0,
|
||||
Hex = 1,
|
||||
HSLA = 2
|
||||
}
|
||||
export type IColorFormat = string | { opaque: string, transparent: string };
|
||||
|
||||
export class ColorInfo {
|
||||
range: Range;
|
||||
|
||||
color: Color;
|
||||
|
||||
mode: ColorMode;
|
||||
format: IColorFormat;
|
||||
|
||||
constructor(range: Range, color: Color, mode: ColorMode) {
|
||||
availableFormats: IColorFormat[];
|
||||
|
||||
constructor(range: Range, color: Color, format: IColorFormat, availableFormats: IColorFormat[]) {
|
||||
if (color && !(color instanceof Color)) {
|
||||
throw illegalArgument('color');
|
||||
}
|
||||
if (mode && !(mode in ColorMode)) {
|
||||
throw illegalArgument('mode');
|
||||
if (format && (typeof format !== 'string') && !format.opaque && !format.transparent && typeof format.opaque !== 'string' && typeof format.transparent !== 'string') {
|
||||
throw illegalArgument('format');
|
||||
}
|
||||
if (availableFormats && !Array.isArray(availableFormats)) {
|
||||
throw illegalArgument('availableFormats');
|
||||
}
|
||||
if (!Range.isRange(range) || range.isEmpty) {
|
||||
throw illegalArgument('range');
|
||||
}
|
||||
this.range = range;
|
||||
this.color = color;
|
||||
this.mode = mode;
|
||||
this.format = format;
|
||||
this.availableFormats = availableFormats;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user