diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 0f068fec7de..73a1e08d61d 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -128,7 +128,7 @@ export abstract class HeaderView extends View { private headerForeground: Color; private headerBackground: Color; - private headerHighContrastBorder; + private headerHighContrastBorder: Color; constructor(opts: IHeaderViewOptions) { super(opts); diff --git a/src/vs/base/common/color.ts b/src/vs/base/common/color.ts index 4916d8ecba6..9b93e0653ed 100644 --- a/src/vs/base/common/color.ts +++ b/src/vs/base/common/color.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { CharCode } from 'vs/base/common/charCode'; +import { memoize } from 'vs/base/common/decorators'; export class RGBA { _rgbaBrand: void; @@ -50,14 +51,6 @@ export class RGBA { } return c | 0; } - - public toString(): string { - if (this.a === 255) { - return `rgb(${this.r}, ${this.g}, ${this.b})`; - } - - return `rgba(${this.r}, ${this.g}, ${this.b}, ${(this.a / 255).toFixed(2)})`; - } } /** @@ -109,17 +102,6 @@ export class HSLA { } return n; } - - public toString() { - const s = (this.s * 100).toFixed(2); - const l = (this.l * 100).toFixed(2); - - if (this.a === 1) { - return `hsl(${this.h}, ${s}%, ${l}%)`; - } - - return `hsla(${this.h}, ${s}%, ${l}%, ${this.a.toFixed(2)})`; - } } /** @@ -293,6 +275,11 @@ function _hue2rgb(p: number, q: number, t: number) { return p; } +function _toTwoDigitHex(n: number): string { + const r = n.toString(16); + return r.length !== 2 ? '0' + r : r; +} + export class Color { public static fromRGBA(rgba: RGBA): Color { @@ -357,17 +344,17 @@ export class Color { return Color.fromRGBA(new RGBA(red, green, blue, opacity)); } - private readonly rgba: RGBA; + readonly rgba: RGBA; + + @memoize + get hsla(): HSLA { return rgba2hsla(this.rgba); } private constructor(arg: RGBA) { this.rgba = arg; } public equals(other: Color): boolean { - if (!other) { - return false; - } - return RGBA.equals(this.rgba, other.rgba); + return !!other && RGBA.equals(this.rgba, other.rgba); } /** @@ -465,14 +452,12 @@ export class Color { } public lighten(factor: number): Color { - const hsl = this.toHSLA(); - const result = new HSLA(hsl.h, hsl.s, hsl.l + hsl.l * factor, hsl.a); + const result = new HSLA(this.hsla.h, this.hsla.s, this.hsla.l + this.hsla.l * factor, this.hsla.a); return new Color(hsla2rgba(result)); } public darken(factor: number): Color { - const hsl = this.toHSLA(); - const result = new HSLA(hsl.h, hsl.s, hsl.l - hsl.l * factor, hsl.a); + const result = new HSLA(this.hsla.h, this.hsla.s, this.hsla.l - this.hsla.l * factor, this.hsla.a); return new Color(hsla2rgba(result)); } @@ -496,67 +481,27 @@ export class Color { } public blend(c: Color): Color { - const color = c.toRGBA(); + const rgba = c.rgba; // Convert to 0..1 opacity const thisA = this.rgba.a / 255; - const colorA = color.a / 255; + const colorA = rgba.a / 255; let a = thisA + colorA * (1 - thisA); if (a < 1.0e-6) { return Color.transparent; } - const r = this.rgba.r * thisA / a + color.r * colorA * (1 - thisA) / a; - const g = this.rgba.g * thisA / a + color.g * colorA * (1 - thisA) / a; - const b = this.rgba.b * thisA / a + color.b * colorA * (1 - thisA) / a; + const r = this.rgba.r * thisA / a + rgba.r * colorA * (1 - thisA) / a; + const g = this.rgba.g * thisA / a + rgba.g * colorA * (1 - thisA) / a; + const b = this.rgba.b * thisA / a + rgba.b * colorA * (1 - thisA) / a; a *= 255; return new Color(new RGBA(r, g, b, a)); } - public toString(): string { - const rgba = this.rgba; - if (rgba.a === 255) { - return this.toRGBHex(); - } - return `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${+(rgba.a / 255).toFixed(2)})`; - } - - /** - * Prins the color as #RRGGBB - */ - public toRGBHex(): string { - const rgba = this.rgba; - return `#${Color._toTwoDigitHex(rgba.r)}${Color._toTwoDigitHex(rgba.g)}${Color._toTwoDigitHex(rgba.b)}`; - } - - /** - * Prins the color as #RRGGBBAA - * If 'compact' is set, colors without transparancy will be printed as #RRGGBB - */ - public toRGBAHex(compact = false): string { - const rgba = this.rgba; - if (compact && rgba.a === 0xFF) { - return this.toRGBHex(); - } - return `#${Color._toTwoDigitHex(rgba.r)}${Color._toTwoDigitHex(rgba.g)}${Color._toTwoDigitHex(rgba.b)}${Color._toTwoDigitHex(rgba.a)}`; - } - - private static _toTwoDigitHex(n: number): string { - let r = n.toString(16); - if (r.length !== 2) { - return '0' + r; - } - return r; - } - - public toHSLA(): HSLA { - return rgba2hsla(this.rgba); - } - - public toRGBA(): RGBA { - return this.rgba; + toString(): string { + return Color.Format.CSS.format(this); } public static getLighterColor(of: Color, relative: Color, factor?: number): Color { @@ -590,3 +535,68 @@ export class Color { public static readonly lightgrey = new Color(new RGBA(211, 211, 211, 255)); public static readonly transparent = new Color(new RGBA(0, 0, 0, 0)); } + +export namespace Color { + export namespace Format { + export namespace CSS { + + export function asRGB(color: Color): string { + if (color.rgba.a === 255) { + return `rgb(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b})`; + } + + return Color.Format.CSS.asRGBA(color); + } + + export function asRGBA(color: Color): string { + return `rgba(${color.rgba.r}, ${color.rgba.g}, ${color.rgba.b}, ${+(color.rgba.a / 255).toFixed(2)})`; + } + + export function asHSL(color: Color): string { + if (color.hsla.a === 1) { + return `hsl(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%)`; + } + + return Color.Format.CSS.asHSLA(color); + } + + export function asHSLA(color: Color): string { + return `hsla(${color.hsla.h}, ${(color.hsla.s * 100).toFixed(2)}%, ${(color.hsla.l * 100).toFixed(2)}%, ${color.hsla.a.toFixed(2)})`; + } + + /** + * Formats the color as #RRGGBB + */ + export function asHex(color: Color): string { + return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}`; + } + + /** + * Formats the color as #RRGGBBAA + * If 'compact' is set, colors without transparancy will be printed as #RRGGBB + */ + export function asHexA(color: Color, compact = false): string { + if (compact && color.rgba.a === 0xFF) { + return Color.Format.CSS.asHex(color); + } + + return `#${_toTwoDigitHex(color.rgba.r)}${_toTwoDigitHex(color.rgba.g)}${_toTwoDigitHex(color.rgba.b)}${_toTwoDigitHex(color.rgba.a)}`; + } + + /** + * The default format will use HEX if opaque and RGBA otherwise. + */ + export function format(color: Color): string | null { + if (!color) { + return null; + } + + if (color.rgba.a === 255) { + return Color.Format.CSS.asHex(color); + } + + return Color.Format.CSS.asRGBA(color); + } + } + } +} \ No newline at end of file diff --git a/src/vs/base/test/common/color.test.ts b/src/vs/base/test/common/color.test.ts index 8ea10841b30..6ec3a5f6de1 100644 --- a/src/vs/base/test/common/color.test.ts +++ b/src/vs/base/test/common/color.test.ts @@ -11,75 +11,75 @@ import { Color, RGBA, HSLA, isValidHexColor } from 'vs/base/common/color'; suite('Color', () => { test('rgba2hsla', function () { - assert.deepEqual(new HSLA(0, 0, 0, 1), Color.fromRGBA(new RGBA(0, 0, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(0, 0, 1, 1), Color.fromRGBA(new RGBA(255, 255, 255, 255)).toHSLA()); + assert.deepEqual(new HSLA(0, 0, 0, 1), Color.fromRGBA(new RGBA(0, 0, 0, 255)).hsla); + assert.deepEqual(new HSLA(0, 0, 1, 1), Color.fromRGBA(new RGBA(255, 255, 255, 255)).hsla); - assert.deepEqual(new HSLA(0, 1, 0.5, 1), Color.fromRGBA(new RGBA(255, 0, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(120, 1, 0.5, 1), Color.fromRGBA(new RGBA(0, 255, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(240, 1, 0.5, 1), Color.fromRGBA(new RGBA(0, 0, 255, 255)).toHSLA()); + assert.deepEqual(new HSLA(0, 1, 0.5, 1), Color.fromRGBA(new RGBA(255, 0, 0, 255)).hsla); + assert.deepEqual(new HSLA(120, 1, 0.5, 1), Color.fromRGBA(new RGBA(0, 255, 0, 255)).hsla); + assert.deepEqual(new HSLA(240, 1, 0.5, 1), Color.fromRGBA(new RGBA(0, 0, 255, 255)).hsla); - assert.deepEqual(new HSLA(60, 1, 0.5, 1), Color.fromRGBA(new RGBA(255, 255, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(180, 1, 0.5, 1), Color.fromRGBA(new RGBA(0, 255, 255, 255)).toHSLA()); - assert.deepEqual(new HSLA(300, 1, 0.5, 1), Color.fromRGBA(new RGBA(255, 0, 255, 255)).toHSLA()); + assert.deepEqual(new HSLA(60, 1, 0.5, 1), Color.fromRGBA(new RGBA(255, 255, 0, 255)).hsla); + assert.deepEqual(new HSLA(180, 1, 0.5, 1), Color.fromRGBA(new RGBA(0, 255, 255, 255)).hsla); + assert.deepEqual(new HSLA(300, 1, 0.5, 1), Color.fromRGBA(new RGBA(255, 0, 255, 255)).hsla); - assert.deepEqual(new HSLA(0, 0, 0.753, 1), Color.fromRGBA(new RGBA(192, 192, 192, 255)).toHSLA()); + assert.deepEqual(new HSLA(0, 0, 0.753, 1), Color.fromRGBA(new RGBA(192, 192, 192, 255)).hsla); - assert.deepEqual(new HSLA(0, 0, 0.502, 1), Color.fromRGBA(new RGBA(128, 128, 128, 255)).toHSLA()); - assert.deepEqual(new HSLA(0, 1, 0.251, 1), Color.fromRGBA(new RGBA(128, 0, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(60, 1, 0.251, 1), Color.fromRGBA(new RGBA(128, 128, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(120, 1, 0.251, 1), Color.fromRGBA(new RGBA(0, 128, 0, 255)).toHSLA()); - assert.deepEqual(new HSLA(300, 1, 0.251, 1), Color.fromRGBA(new RGBA(128, 0, 128, 255)).toHSLA()); - assert.deepEqual(new HSLA(180, 1, 0.251, 1), Color.fromRGBA(new RGBA(0, 128, 128, 255)).toHSLA()); - assert.deepEqual(new HSLA(240, 1, 0.251, 1), Color.fromRGBA(new RGBA(0, 0, 128, 255)).toHSLA()); + assert.deepEqual(new HSLA(0, 0, 0.502, 1), Color.fromRGBA(new RGBA(128, 128, 128, 255)).hsla); + assert.deepEqual(new HSLA(0, 1, 0.251, 1), Color.fromRGBA(new RGBA(128, 0, 0, 255)).hsla); + assert.deepEqual(new HSLA(60, 1, 0.251, 1), Color.fromRGBA(new RGBA(128, 128, 0, 255)).hsla); + assert.deepEqual(new HSLA(120, 1, 0.251, 1), Color.fromRGBA(new RGBA(0, 128, 0, 255)).hsla); + assert.deepEqual(new HSLA(300, 1, 0.251, 1), Color.fromRGBA(new RGBA(128, 0, 128, 255)).hsla); + assert.deepEqual(new HSLA(180, 1, 0.251, 1), Color.fromRGBA(new RGBA(0, 128, 128, 255)).hsla); + assert.deepEqual(new HSLA(240, 1, 0.251, 1), Color.fromRGBA(new RGBA(0, 0, 128, 255)).hsla); }); test('hsla2rgba', function () { - assert.deepEqual(new RGBA(0, 0, 0, 255), Color.fromHSLA(new HSLA(0, 0, 0, 1)).toRGBA()); - assert.deepEqual(new RGBA(255, 255, 255, 255), Color.fromHSLA(new HSLA(0, 0, 1, 1)).toRGBA()); + assert.deepEqual(new RGBA(0, 0, 0, 255), Color.fromHSLA(new HSLA(0, 0, 0, 1)).rgba); + assert.deepEqual(new RGBA(255, 255, 255, 255), Color.fromHSLA(new HSLA(0, 0, 1, 1)).rgba); - assert.deepEqual(new RGBA(255, 0, 0, 255), Color.fromHSLA(new HSLA(0, 1, 0.5, 1)).toRGBA()); - assert.deepEqual(new RGBA(0, 255, 0, 255), Color.fromHSLA(new HSLA(120, 1, 0.5, 1)).toRGBA()); - assert.deepEqual(new RGBA(0, 0, 255, 255), Color.fromHSLA(new HSLA(240, 1, 0.5, 1)).toRGBA()); + assert.deepEqual(new RGBA(255, 0, 0, 255), Color.fromHSLA(new HSLA(0, 1, 0.5, 1)).rgba); + assert.deepEqual(new RGBA(0, 255, 0, 255), Color.fromHSLA(new HSLA(120, 1, 0.5, 1)).rgba); + assert.deepEqual(new RGBA(0, 0, 255, 255), Color.fromHSLA(new HSLA(240, 1, 0.5, 1)).rgba); - assert.deepEqual(new RGBA(255, 255, 0, 255), Color.fromHSLA(new HSLA(60, 1, 0.5, 1)).toRGBA()); - assert.deepEqual(new RGBA(0, 255, 255, 255), Color.fromHSLA(new HSLA(180, 1, 0.5, 1)).toRGBA()); - assert.deepEqual(new RGBA(255, 0, 255, 255), Color.fromHSLA(new HSLA(300, 1, 0.5, 1)).toRGBA()); + assert.deepEqual(new RGBA(255, 255, 0, 255), Color.fromHSLA(new HSLA(60, 1, 0.5, 1)).rgba); + assert.deepEqual(new RGBA(0, 255, 255, 255), Color.fromHSLA(new HSLA(180, 1, 0.5, 1)).rgba); + assert.deepEqual(new RGBA(255, 0, 255, 255), Color.fromHSLA(new HSLA(300, 1, 0.5, 1)).rgba); - assert.deepEqual(new RGBA(192, 192, 192, 255), Color.fromHSLA(new HSLA(0, 0, 0.753, 1)).toRGBA()); + assert.deepEqual(new RGBA(192, 192, 192, 255), Color.fromHSLA(new HSLA(0, 0, 0.753, 1)).rgba); - assert.deepEqual(new RGBA(128, 128, 128, 255), Color.fromHSLA(new HSLA(0, 0, 0.502, 1)).toRGBA()); - assert.deepEqual(new RGBA(128, 0, 0, 255), Color.fromHSLA(new HSLA(0, 1, 0.251, 1)).toRGBA()); - assert.deepEqual(new RGBA(128, 128, 0, 255), Color.fromHSLA(new HSLA(60, 1, 0.251, 1)).toRGBA()); - assert.deepEqual(new RGBA(0, 128, 0, 255), Color.fromHSLA(new HSLA(120, 1, 0.251, 1)).toRGBA()); - assert.deepEqual(new RGBA(128, 0, 128, 255), Color.fromHSLA(new HSLA(300, 1, 0.251, 1)).toRGBA()); - assert.deepEqual(new RGBA(0, 128, 128, 255), Color.fromHSLA(new HSLA(180, 1, 0.251, 1)).toRGBA()); - assert.deepEqual(new RGBA(0, 0, 128, 255), Color.fromHSLA(new HSLA(240, 1, 0.251, 1)).toRGBA()); + assert.deepEqual(new RGBA(128, 128, 128, 255), Color.fromHSLA(new HSLA(0, 0, 0.502, 1)).rgba); + assert.deepEqual(new RGBA(128, 0, 0, 255), Color.fromHSLA(new HSLA(0, 1, 0.251, 1)).rgba); + assert.deepEqual(new RGBA(128, 128, 0, 255), Color.fromHSLA(new HSLA(60, 1, 0.251, 1)).rgba); + assert.deepEqual(new RGBA(0, 128, 0, 255), Color.fromHSLA(new HSLA(120, 1, 0.251, 1)).rgba); + assert.deepEqual(new RGBA(128, 0, 128, 255), Color.fromHSLA(new HSLA(300, 1, 0.251, 1)).rgba); + assert.deepEqual(new RGBA(0, 128, 128, 255), Color.fromHSLA(new HSLA(180, 1, 0.251, 1)).rgba); + assert.deepEqual(new RGBA(0, 0, 128, 255), Color.fromHSLA(new HSLA(240, 1, 0.251, 1)).rgba); }); test('hex2rgba', function () { - assert.deepEqual(new RGBA(0, 0, 0, 255), Color.fromHex('#000000').toRGBA()); - assert.deepEqual(new RGBA(255, 255, 255, 255), Color.fromHex('#FFFFFF').toRGBA()); + assert.deepEqual(new RGBA(0, 0, 0, 255), Color.fromHex('#000000').rgba); + assert.deepEqual(new RGBA(255, 255, 255, 255), Color.fromHex('#FFFFFF').rgba); - assert.deepEqual(new RGBA(255, 0, 0, 255), Color.fromHex('#FF0000').toRGBA()); - assert.deepEqual(new RGBA(0, 255, 0, 255), Color.fromHex('#00FF00').toRGBA()); - assert.deepEqual(new RGBA(0, 0, 255, 255), Color.fromHex('#0000FF').toRGBA()); + assert.deepEqual(new RGBA(255, 0, 0, 255), Color.fromHex('#FF0000').rgba); + assert.deepEqual(new RGBA(0, 255, 0, 255), Color.fromHex('#00FF00').rgba); + assert.deepEqual(new RGBA(0, 0, 255, 255), Color.fromHex('#0000FF').rgba); - assert.deepEqual(new RGBA(255, 255, 0, 255), Color.fromHex('#FFFF00').toRGBA()); - assert.deepEqual(new RGBA(0, 255, 255, 255), Color.fromHex('#00FFFF').toRGBA()); - assert.deepEqual(new RGBA(255, 0, 255, 255), Color.fromHex('#FF00FF').toRGBA()); + assert.deepEqual(new RGBA(255, 255, 0, 255), Color.fromHex('#FFFF00').rgba); + assert.deepEqual(new RGBA(0, 255, 255, 255), Color.fromHex('#00FFFF').rgba); + assert.deepEqual(new RGBA(255, 0, 255, 255), Color.fromHex('#FF00FF').rgba); - assert.deepEqual(new RGBA(192, 192, 192, 255), Color.fromHex('#C0C0C0').toRGBA()); + assert.deepEqual(new RGBA(192, 192, 192, 255), Color.fromHex('#C0C0C0').rgba); - assert.deepEqual(new RGBA(128, 128, 128, 255), Color.fromHex('#808080').toRGBA()); - assert.deepEqual(new RGBA(128, 0, 0, 255), Color.fromHex('#800000').toRGBA()); - assert.deepEqual(new RGBA(128, 128, 0, 255), Color.fromHex('#808000').toRGBA()); - assert.deepEqual(new RGBA(0, 128, 0, 255), Color.fromHex('#008000').toRGBA()); - assert.deepEqual(new RGBA(128, 0, 128, 255), Color.fromHex('#800080').toRGBA()); - assert.deepEqual(new RGBA(0, 128, 128, 255), Color.fromHex('#008080').toRGBA()); - assert.deepEqual(new RGBA(0, 0, 128, 255), Color.fromHex('#000080').toRGBA()); + assert.deepEqual(new RGBA(128, 128, 128, 255), Color.fromHex('#808080').rgba); + assert.deepEqual(new RGBA(128, 0, 0, 255), Color.fromHex('#800000').rgba); + assert.deepEqual(new RGBA(128, 128, 0, 255), Color.fromHex('#808000').rgba); + assert.deepEqual(new RGBA(0, 128, 0, 255), Color.fromHex('#008000').rgba); + assert.deepEqual(new RGBA(128, 0, 128, 255), Color.fromHex('#800080').rgba); + assert.deepEqual(new RGBA(0, 128, 128, 255), Color.fromHex('#008080').rgba); + assert.deepEqual(new RGBA(0, 0, 128, 255), Color.fromHex('#000080').rgba); function assertParseColor(input: string, expected: RGBA): void { - let actual = Color.fromHex(input).toRGBA(); + let actual = Color.fromHex(input).rgba; assert.deepEqual(actual, expected, input); } @@ -154,11 +154,11 @@ suite('Color', () => { test('getLighterColor', function () { let color1 = Color.fromHSLA(new HSLA(60, 1, 0.5, 1)), color2 = Color.fromHSLA(new HSLA(0, 0, 0.753, 1)); - assert.deepEqual(color1.toHSLA(), Color.getLighterColor(color1, color2).toHSLA()); - assert.deepEqual(new HSLA(0, 0, 0.914, 1), Color.getLighterColor(color2, color1).toHSLA()); - assert.deepEqual(new HSLA(0, 0, 0.851, 1), Color.getLighterColor(color2, color1, 0.3).toHSLA()); - assert.deepEqual(new HSLA(0, 0, 0.98, 1), Color.getLighterColor(color2, color1, 0.7).toHSLA()); - assert.deepEqual(new HSLA(0, 0, 1, 1), Color.getLighterColor(color2, color1, 1).toHSLA()); + assert.deepEqual(color1.hsla, Color.getLighterColor(color1, color2).hsla); + assert.deepEqual(new HSLA(0, 0, 0.914, 1), Color.getLighterColor(color2, color1).hsla); + assert.deepEqual(new HSLA(0, 0, 0.851, 1), Color.getLighterColor(color2, color1, 0.3).hsla); + assert.deepEqual(new HSLA(0, 0, 0.98, 1), Color.getLighterColor(color2, color1, 0.7).hsla); + assert.deepEqual(new HSLA(0, 0, 1, 1), Color.getLighterColor(color2, color1, 1).hsla); }); @@ -172,14 +172,14 @@ suite('Color', () => { test('getDarkerColor', function () { let color1 = Color.fromHSLA(new HSLA(60, 1, 0.5, 1)), color2 = Color.fromHSLA(new HSLA(0, 0, 0.753, 1)); - assert.deepEqual(color2.toHSLA(), Color.getDarkerColor(color2, color1).toHSLA()); - assert.deepEqual(new HSLA(60, 1, 0.392, 1), Color.getDarkerColor(color1, color2).toHSLA()); - assert.deepEqual(new HSLA(60, 1, 0.435, 1), Color.getDarkerColor(color1, color2, 0.3).toHSLA()); - assert.deepEqual(new HSLA(60, 1, 0.349, 1), Color.getDarkerColor(color1, color2, 0.7).toHSLA()); - assert.deepEqual(new HSLA(60, 1, 0.284, 1), Color.getDarkerColor(color1, color2, 1).toHSLA()); + assert.deepEqual(color2.hsla, Color.getDarkerColor(color2, color1).hsla); + assert.deepEqual(new HSLA(60, 1, 0.392, 1), Color.getDarkerColor(color1, color2).hsla); + assert.deepEqual(new HSLA(60, 1, 0.435, 1), Color.getDarkerColor(color1, color2, 0.3).hsla); + assert.deepEqual(new HSLA(60, 1, 0.349, 1), Color.getDarkerColor(color1, color2, 0.7).hsla); + assert.deepEqual(new HSLA(60, 1, 0.284, 1), Color.getDarkerColor(color1, color2, 1).hsla); // Abyss theme - assert.deepEqual(new HSLA(355, 0.874, 0.157, 1), Color.getDarkerColor(Color.fromHex('#770811'), Color.fromHex('#000c18'), 0.4).toHSLA()); + assert.deepEqual(new HSLA(355, 0.874, 0.157, 1), Color.getDarkerColor(Color.fromHex('#770811'), Color.fromHex('#000c18'), 0.4).hsla); }); test('luminosity', function () { diff --git a/src/vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl.ts b/src/vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl.ts index 2e6a03a39d8..1ef6e492e32 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/overviewRulerImpl.ts @@ -159,7 +159,7 @@ export class OverviewRulerImpl { if (this._background === null) { ctx.clearRect(0, 0, width, height); } else { - ctx.fillStyle = this._background.toRGBHex(); + ctx.fillStyle = Color.Format.CSS.asHex(this._background); ctx.fillRect(0, 0, width, height); } diff --git a/src/vs/editor/common/modes/supports/tokenization.ts b/src/vs/editor/common/modes/supports/tokenization.ts index 55851cc295f..53953fbc57c 100644 --- a/src/vs/editor/common/modes/supports/tokenization.ts +++ b/src/vs/editor/common/modes/supports/tokenization.ts @@ -395,7 +395,7 @@ export function generateTokensCSSForColorMap(colorMap: Color[]): string { let rules: string[] = []; for (let i = 1, len = colorMap.length; i < len; i++) { let color = colorMap[i]; - rules[i] = `.mtk${i} { color: ${color.toString()}; }`; + rules[i] = `.mtk${i} { color: ${color}; }`; } rules.push('.mtki { font-style: italic; }'); rules.push('.mtkb { font-weight: bold; }'); diff --git a/src/vs/editor/common/view/minimapCharRenderer.ts b/src/vs/editor/common/view/minimapCharRenderer.ts index cdf67f31294..ae9a4cb9e69 100644 --- a/src/vs/editor/common/view/minimapCharRenderer.ts +++ b/src/vs/editor/common/view/minimapCharRenderer.ts @@ -41,7 +41,7 @@ export class MinimapTokensColorTracker { } this._colors = [null]; for (let colorId = 1; colorId < colorMap.length; colorId++) { - this._colors[colorId] = colorMap[colorId].toRGBA(); + this._colors[colorId] = colorMap[colorId].rgba; } let backgroundLuminosity = colorMap[ColorId.DefaultBackground].getLuminosity(); this._backgroundIsLight = (backgroundLuminosity >= 0.5); diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 3fae750679f..ff0905c3454 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -20,6 +20,7 @@ import * as textModelEvents from 'vs/editor/common/model/textModelEvents'; import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; import { CharacterHardWrappingLineMapperFactory } from 'vs/editor/common/viewModel/characterHardWrappingLineMapper'; import { ViewLayout } from 'vs/editor/common/viewLayout/viewLayout'; +import { Color } from 'vs/base/common/color'; const USE_IDENTITY_LINES_COLLECTION = true; @@ -533,7 +534,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel let colorMap = TokenizationRegistry.getColorMap(); let result: string[] = [null]; for (let i = 1, len = colorMap.length; i < len; i++) { - result[i] = colorMap[i].toRGBHex(); + result[i] = Color.Format.CSS.asHex(colorMap[i]); } return result; } diff --git a/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts b/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts index 32a82445b04..7062fa65086 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorPickerModel.ts @@ -59,7 +59,7 @@ export class ColorPickerModel { public set color(color: Color) { this._color = color; - const alpha = color.toRGBA().a; + const alpha = color.rgba.a; if (!this._opacity) { this._opacity = alpha / 255; } @@ -118,7 +118,7 @@ export class ColorPickerModel { public set opacity(opacity: number) { this._opacity = opacity; - const rgba = this._color.toRGBA(); + const rgba = this._color.rgba; this.color = Color.fromRGBA(new RGBA(rgba.r, rgba.g, rgba.b, opacity * 255)); if (this.widget.header) { diff --git a/src/vs/editor/contrib/colorPicker/browser/elements/colorPickerBody.ts b/src/vs/editor/contrib/colorPicker/browser/elements/colorPickerBody.ts index 757691a1a98..a971449108e 100644 --- a/src/vs/editor/contrib/colorPicker/browser/elements/colorPickerBody.ts +++ b/src/vs/editor/contrib/colorPicker/browser/elements/colorPickerBody.ts @@ -41,11 +41,7 @@ export class ColorPickerBody extends Disposable { } public fillOpacityOverlay(color: Color): void { - const c = color.toRGBA(); - const r = c.r; - const g = c.g; - const b = c.b; - + const { r, g, b } = color.rgba; this.opacityOverlay.style.background = `linear-gradient(to bottom, rgba(${r}, ${g}, ${b}, 1) 0%, rgba(${r}, ${g}, ${b}, 0) 100%)`; } @@ -72,8 +68,8 @@ export class ColorPickerBody extends Disposable { } const updateModel = (x: number, y: number) => { - const saturationRGBA = this.saturationBox.extractColor(x, y).toRGBA(); - this.widget.model.color = Color.fromRGBA(new RGBA(saturationRGBA.r, saturationRGBA.g, saturationRGBA.b, this.widget.model.opacity * 255)); // TODO@Michel store opacity in [0-255] instead + const { r, g, b } = this.saturationBox.extractColor(x, y).rgba; + this.widget.model.color = Color.fromRGBA(new RGBA(r, g, b, this.widget.model.opacity * 255)); // TODO@Michel store opacity in [0-255] instead this.saturationBox.focusSaturationSelection({ x: x, y: y }); }; @@ -235,7 +231,7 @@ export class SaturationBox { } public fillSaturationBox(): void { - this.saturationCtx.fillStyle = this.calculateHueColor(this.model.hue).toString(); + this.saturationCtx.fillStyle = Color.Format.CSS.format(this.calculateHueColor(this.model.hue)); this.saturationCtx.fill(); this.saturationCtx.fillStyle = this.whiteGradient; this.saturationCtx.fill(); diff --git a/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts b/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts index e1b3643ad8d..e4a3cc7f32d 100644 --- a/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts +++ b/src/vs/editor/contrib/colorPicker/common/colorFormatter.ts @@ -49,25 +49,25 @@ function createPropertyNode(variable: string, fractionDigits: number, type: stri switch (variable) { case 'red': - absoluteValue = normalize(color.toRGBA().r, min, max, RGBA_ENDRANGE); + absoluteValue = normalize(color.rgba.r, min, max, RGBA_ENDRANGE); break; case 'green': - absoluteValue = normalize(color.toRGBA().g, min, max, RGBA_ENDRANGE); + absoluteValue = normalize(color.rgba.g, min, max, RGBA_ENDRANGE); break; case 'blue': - absoluteValue = normalize(color.toRGBA().b, min, max, RGBA_ENDRANGE); + absoluteValue = normalize(color.rgba.b, min, max, RGBA_ENDRANGE); break; case 'alpha': - absoluteValue = normalize(color.toRGBA().a, min, max, RGBA_ENDRANGE); + absoluteValue = normalize(color.rgba.a, min, max, RGBA_ENDRANGE); break; case 'hue': - absoluteValue = normalize(color.toHSLA().h, min, max, HSL_HUERANGE); + absoluteValue = normalize(color.hsla.h, min, max, HSL_HUERANGE); break; case 'saturation': - absoluteValue = normalize(color.toHSLA().s, min, max, HSL_ENDRANGE); + absoluteValue = normalize(color.hsla.s, min, max, HSL_ENDRANGE); break; case 'luminosity': - absoluteValue = normalize(color.toHSLA().l, min, max, HSL_ENDRANGE); + absoluteValue = normalize(color.hsla.l, min, max, HSL_ENDRANGE); break; } diff --git a/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts b/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts index 8964611f587..256baedf60d 100644 --- a/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts +++ b/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts @@ -240,8 +240,8 @@ class InspectTokensWidget extends Disposable implements IContentWidget { result += `language${escape(metadata.languageIdentifier.language)}`; result += `token type${this._tokenTypeToString(metadata.tokenType)}`; result += `font style${this._fontStyleToString(metadata.fontStyle)}`; - result += `foreground${metadata.foreground.toRGBHex()}`; - result += `background${metadata.background.toRGBHex()}`; + result += `foreground${Color.Format.CSS.asHex(metadata.foreground)}`; + result += `background${Color.Format.CSS.asHex(metadata.background)}`; result += ``; result += `
`; diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index 6a20707ba5a..44cf9e5ce3f 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -1031,12 +1031,12 @@ export class Color { if (!alpha) { alpha = 1; } - const color = CommonColor.fromHSLA(new HSLA(hue, saturation, luminosity, alpha)).toRGBA(); + const color = CommonColor.fromHSLA(new HSLA(hue, saturation, luminosity, alpha)).rgba; return new Color(color.r, color.g, color.b, color.a / 255); } static fromHex(hex: string): Color { - const color = CommonColor.fromHex(hex).toRGBA(); + const color = CommonColor.fromHex(hex).rgba; return new Color(color.r, color.g, color.b, color.a / 255); } } diff --git a/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts b/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts index 0518392efba..ea452891453 100644 --- a/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts +++ b/src/vs/workbench/parts/codeEditor/electron-browser/textMate/inspectTMScopes.ts @@ -270,8 +270,8 @@ class InspectTMScopesWidget extends Disposable implements IContentWidget { result += `language${escape(metadata.languageIdentifier.language)}`; result += `token type${this._tokenTypeToString(metadata.tokenType)}`; result += `font style${this._fontStyleToString(metadata.fontStyle)}`; - result += `foreground${metadata.foreground.toRGBAHex()}`; - result += `background${metadata.background.toRGBAHex()}`; + result += `foreground${Color.Format.CSS.asHexA(metadata.foreground)}`; + result += `background${Color.Format.CSS.asHexA(metadata.background)}`; result += ``; let theme = this._themeService.getColorTheme(); diff --git a/src/vs/workbench/parts/terminal/test/electron-browser/terminalColorRegistry.test.ts b/src/vs/workbench/parts/terminal/test/electron-browser/terminalColorRegistry.test.ts index cc2b29482c7..b6cb4216fb2 100644 --- a/src/vs/workbench/parts/terminal/test/electron-browser/terminalColorRegistry.test.ts +++ b/src/vs/workbench/parts/terminal/test/electron-browser/terminalColorRegistry.test.ts @@ -10,6 +10,7 @@ import { Extensions as ThemeingExtensions, IColorRegistry } from 'vs/platform/th import { Registry } from 'vs/platform/registry/common/platform'; import { ansiColorIdentifiers, registerColors } from 'vs/workbench/parts/terminal/electron-browser/terminalColorRegistry'; import { ITheme, ThemeType } from 'vs/platform/theme/common/themeService'; +import { Color } from 'vs/base/common/color'; registerColors(); @@ -29,7 +30,7 @@ suite('Workbench - TerminalColorRegistry', () => { test('hc colors', function () { let theme = getMockTheme('hc'); - let colors = ansiColorIdentifiers.map(colorId => theme.getColor(colorId).toRGBAHex(true)); + let colors = ansiColorIdentifiers.map(colorId => Color.Format.CSS.asHexA(theme.getColor(colorId), true)); assert.deepEqual(colors, [ '#000000', @@ -54,7 +55,7 @@ suite('Workbench - TerminalColorRegistry', () => { test('light colors', function () { let theme = getMockTheme('light'); - let colors = ansiColorIdentifiers.map(colorId => theme.getColor(colorId).toRGBAHex(true)); + let colors = ansiColorIdentifiers.map(colorId => Color.Format.CSS.asHexA(theme.getColor(colorId), true)); assert.deepEqual(colors, [ '#000000', @@ -79,7 +80,7 @@ suite('Workbench - TerminalColorRegistry', () => { test('dark colors', function () { let theme = getMockTheme('dark'); - let colors = ansiColorIdentifiers.map(colorId => theme.getColor(colorId).toRGBAHex(true)); + let colors = ansiColorIdentifiers.map(colorId => Color.Format.CSS.asHexA(theme.getColor(colorId), true)); assert.deepEqual(colors, [ '#000000', diff --git a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts index d2525d73ec1..f4247cabd73 100644 --- a/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts +++ b/src/vs/workbench/parts/themes/electron-browser/themes.contribution.ts @@ -24,6 +24,7 @@ import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/ import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IColorRegistry, Extensions as ColorRegistryExtensions } from 'vs/platform/theme/common/colorRegistry'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { Color } from 'vs/base/common/color'; export class SelectColorThemeAction extends Action { @@ -189,7 +190,7 @@ class GenerateColorThemeAction extends Action { colorRegistry.getColors().map(c => { let color = theme.getColor(c.id, false); if (color) { - resultingColors[c.id] = color.toRGBAHex(true); + resultingColors[c.id] = Color.Format.CSS.asHexA(color, true); } }); let contents = JSON.stringify({ diff --git a/src/vs/workbench/parts/themes/test/electron-browser/themes.test.contribution.ts b/src/vs/workbench/parts/themes/test/electron-browser/themes.test.contribution.ts index dd158a71fd2..af7598c9ce6 100644 --- a/src/vs/workbench/parts/themes/test/electron-browser/themes.test.contribution.ts +++ b/src/vs/workbench/parts/themes/test/electron-browser/themes.test.contribution.ts @@ -58,7 +58,7 @@ class ThemeDocument { } private _generateExplanation(selector: string, color: Color): string { - return `${selector}: ${color.toRGBAHex(true).toUpperCase()}`; + return `${selector}: ${Color.Format.CSS.asHexA(color, true).toUpperCase()}`; } public explainTokenColor(scopes: string, color: Color): string { @@ -68,14 +68,14 @@ class ThemeDocument { let expected = Color.fromHex(this._defaultColor); // No matching rule if (!color.equals(expected)) { - throw new Error(`[${this._theme.label}]: Unexpected color ${color.toRGBAHex()} for ${scopes}. Expected default ${expected.toRGBAHex()}`); + throw new Error(`[${this._theme.label}]: Unexpected color ${Color.Format.CSS.asHexA(color)} for ${scopes}. Expected default ${Color.Format.CSS.asHexA(expected)}`); } return this._generateExplanation('default', color); } let expected = Color.fromHex(matchingRule.settings.foreground); if (!color.equals(expected)) { - throw new Error(`[${this._theme.label}]: Unexpected color ${color.toRGBAHex()} for ${scopes}. Expected ${expected.toRGBAHex()} coming in from ${matchingRule.rawSelector}`); + throw new Error(`[${this._theme.label}]: Unexpected color ${Color.Format.CSS.asHexA(color)} for ${scopes}. Expected ${Color.Format.CSS.asHexA(expected)} coming in from ${matchingRule.rawSelector}`); } return this._generateExplanation(matchingRule.rawSelector, color); } diff --git a/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts b/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts index 1ae79efeab1..5b3313bf86b 100644 --- a/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts +++ b/src/vs/workbench/services/themes/electron-browser/colorThemeData.ts @@ -140,7 +140,7 @@ export class ColorThemeData implements IColorTheme { } let content = { name: this.label, colors: {}, tokenColors: this.tokenColors }; for (let key in this.colorMap) { - content.colors[key] = this.colorMap[key].toRGBAHex(true); + content.colors[key] = Color.Format.CSS.asHexA(this.colorMap[key], true); } return JSON.stringify(content, null, '\t'); } @@ -148,7 +148,7 @@ export class ColorThemeData implements IColorTheme { toStorageData() { let colorMapData = {}; for (let key in this.colorMap) { - colorMapData[key] = this.colorMap[key].toRGBAHex(true); + colorMapData[key] = Color.Format.CSS.asHexA(this.colorMap[key], true); } // no need to persist custom colors, they will be taken from the settings return JSON.stringify({ @@ -322,8 +322,8 @@ function _sanitizeTokenColors(theme: ColorThemeData) { function updateDefaultRuleSettings(defaultRule: ITokenColorizationRule, theme: ColorThemeData): ITokenColorizationRule { let foreground = theme.getColor(editorForeground) || theme.getDefault(editorForeground); let background = theme.getColor(editorBackground) || theme.getDefault(editorBackground); - defaultRule.settings.foreground = foreground.toRGBAHex(); - defaultRule.settings.background = background.toRGBAHex(); + defaultRule.settings.foreground = Color.Format.CSS.asHexA(foreground); + defaultRule.settings.background = Color.Format.CSS.asHexA(background); return defaultRule; } diff --git a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts index a9f1772cb4b..183a5474ae5 100644 --- a/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts +++ b/src/vs/workbench/services/themes/electron-browser/workbenchThemeService.ts @@ -29,6 +29,7 @@ import Severity from 'vs/base/common/severity'; import { ColorThemeData, fromStorageData, fromExtensionTheme, createUnloadedTheme } from './colorThemeData'; import { ITheme, Extensions as ThemingExtensions, IThemingRegistry } from 'vs/platform/theme/common/themeService'; import { editorBackground } from 'vs/platform/theme/common/colorRegistry'; +import { Color } from 'vs/base/common/color'; import { $ } from 'vs/base/browser/builder'; import Event, { Emitter } from 'vs/base/common/event'; @@ -453,7 +454,7 @@ export class WorkbenchThemeService implements IWorkbenchThemeService { this.onColorThemeChange.fire(this.currentColorTheme); if (settingsTarget !== ConfigurationTarget.WORKSPACE) { - let background = newTheme.getColor(editorBackground).toRGBHex(); // only take RGB, its what is used in the initial CSS + let background = Color.Format.CSS.asHex(newTheme.getColor(editorBackground)); // only take RGB, its what is used in the initial CSS let data = { id: newTheme.id, background: background }; this.broadcastService.broadcast({ channel: 'vscode:changeColorTheme', payload: JSON.stringify(data) }); }