diff --git a/src/color.ts b/src/color.ts index 298ba03..ceb3b52 100644 --- a/src/color.ts +++ b/src/color.ts @@ -1,5 +1,21 @@ import { IColorSet, IBaseColorSet } from './interfaces'; +function getRgb(color: string): [number, number, number] { + return [ + parseInt(color.substr(1, 2), 16), + parseInt(color.substr(3, 2), 16), + parseInt(color.substr(5, 2), 16) + ] +} + +function toCssString(rgb: [number, number, number]): string { + let result = '#'; + result += (rgb[0] < 10 ? '0' : '') + rgb[0]; + result += (rgb[1] < 10 ? '0' : '') + rgb[1]; + result += (rgb[2] < 10 ? '0' : '') + rgb[2]; + return result; +} + export function lighten(color: string, amount: number): string { const MAX = 255; let r = parseInt(color.substr(1, 2), 16); @@ -8,19 +24,7 @@ export function lighten(color: string, amount: number): string { r = Math.min(Math.floor(r + (r * amount)), MAX); g = Math.min(Math.floor(g + (g * amount)), MAX); b = Math.min(Math.floor(b + (b * amount)), MAX); - let rs = r.toString(16); - if (rs.length === 1) { - rs = '0' + rs; - } - let gs = g.toString(16); - if (gs.length === 1) { - gs = '0' + gs; - } - let bs = b.toString(16); - if (bs.length === 1) { - bs = '0' + bs; - } - return `#${rs}${gs}${bs}`; + return toCssString([r, g, b]); } export function darken(color: string, amount: number): string { @@ -38,6 +42,12 @@ export function addAlpha(color: string, alpha: number): string { return color + alphaHex; } +export function contast(color: string): string { + const rgb = getRgb(color); + const luminance = rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114; + return luminance > 192 ? '#000000' : '#ffffff'; +} + export function generateFallbackColorSet(s: IBaseColorSet, type: 'light' | 'dark'): IColorSet { return { type, diff --git a/src/vscodeThemeGenerator.ts b/src/vscodeThemeGenerator.ts index ecbc540..2f7d96a 100644 --- a/src/vscodeThemeGenerator.ts +++ b/src/vscodeThemeGenerator.ts @@ -1,5 +1,5 @@ import { IColorSet, IThemeGenerator, IBaseColorSet } from './interfaces'; -import { darken, lighten, generateFallbackColorSet, addAlpha } from './color'; +import { darken, lighten, generateFallbackColorSet, addAlpha, contast as contrast } from './color'; import { tokenRules, globalRules, IVscodeJsonThemeSetting } from './rules'; export interface IVscodeJsonTheme { @@ -106,10 +106,12 @@ export class VscodeThemeGenerator implements IThemeGenerator { // list.activeSelectionBackground: List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not. theme.colors['list.activeSelectionBackground'] = addAlpha(colorSet.base.color1, 0.5); // list.activeSelectionForeground: List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not. + theme.colors['list.activeSelectionForeground'] = contrast(addAlpha(colorSet.base.color1, 0.5)); // list.dropBackground: List/Tree drag and drop background when moving items around using the mouse. theme.colors['list.dropBackground'] = addAlpha(colorSet.base.color1, 0.5); // list.focusBackground: List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not. theme.colors['list.focusBackground'] = addAlpha(colorSet.base.color1, 0.5); + theme.colors['list.focusForeground'] = contrast(addAlpha(colorSet.base.color1, 0.5)); // list.highlightForeground: List/Tree foreground color of the match highlights when searching inside the list/tree. // list.hoverBackground: List/Tree background when hovering over items using the mouse. theme.colors['list.hoverBackground'] = addAlpha('#FFFFFF', 0.1); @@ -125,6 +127,11 @@ export class VscodeThemeGenerator implements IThemeGenerator { // activityBarBadge.background: Activity notification badge background color. The activity bar is showing on the far left or right and allows to switch between views of the side bar. theme.colors['activityBarBadge.background'] = colorSet.base.color1; // activityBarBadge.foreground: Activity notification badge foreground color. The activity bar is showing on the far left or right and allows to switch between views of the side bar. + theme.colors['activityBarBadge.foreground'] = contrast(colorSet.base.color1); + + // Badge + theme.colors['badge.background'] = colorSet.base.color1; + theme.colors['badge.foreground'] = contrast('#e0ed36'); // Side Bar // sideBar.background: Side bar background color. The side bar is the container for views like explorer and search. @@ -255,6 +262,7 @@ export class VscodeThemeGenerator implements IThemeGenerator { theme.colors['statusBar.background'] = background1; // statusBar.debuggingBackground: Status bar background color when a program is being debugged. The status bar is shown in the bottom of the window theme.colors['statusBar.debuggingBackground'] = colorSet.base.color1; + theme.colors['statusBar.debuggingForeground'] = contrast(colorSet.base.color1); // statusBar.foreground: Status bar foreground color. The status bar is shown in the bottom of the window. // statusBar.noFolderBackground: Status bar background color when no folder is opened. The status bar is shown in the bottom of the window. theme.colors['statusBar.noFolderBackground'] = background1; // Don't make distinction between folder/no folder