From b7fe67fe19c5f0b8c0b65b5e7ae43153cd359381 Mon Sep 17 00:00:00 2001 From: tPenguinLTG Date: Tue, 1 Dec 2020 23:03:57 -0500 Subject: [PATCH 1/2] feat(themes): add Windows theme mapper Add a util function mapFromWindowsTheme that transforms a Windows theme into a React95 theme. --- src/common/utils/index.js | 80 ++++++++++++++++++ src/common/utils/index.spec.js | 149 ++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 1 deletion(-) diff --git a/src/common/utils/index.js b/src/common/utils/index.js index 67d33232..47a959fb 100644 --- a/src/common/utils/index.js +++ b/src/common/utils/index.js @@ -10,6 +10,86 @@ export function clamp(value, min, max) { return value; } +function linearGradient(left, right) { + return `linear-gradient(to right, ${left}, ${right})`; +} + +export function mapFromWindowsTheme(name, windowsTheme, useGradients) { + /* eslint-disable no-unused-vars */ + const { + ButtonAlternateFace, + ButtonDkShadow, + ButtonFace, + ButtonHilight, + ButtonLight, + ButtonShadow, + ButtonText, + ActiveBorder, + AppWorkspace, + Background, + InactiveBorder, + Scrollbar, + Window, + WindowFrame, + WindowText, + ActiveTitle, + GradientActiveTitle, + GradientInactiveTitle, + InactiveTitle, + InactiveTitleText, + TitleText, + Menu, + MenuBar, + MenuHilight, + MenuText, + GrayText, + Hilight, + HilightText, + HotTrackingColor, + InfoText, + InfoWindow + } = windowsTheme; + /* eslint-enable no-unused-vars */ + + return { + name, + + anchor: HotTrackingColor, + anchorVisited: HotTrackingColor, + borderDark: ButtonShadow, + borderDarkest: ButtonDkShadow, + borderLight: ButtonLight, + borderLightest: ButtonHilight, + canvas: Window, + canvasText: WindowText, + canvasTextDisabled: ButtonShadow, + canvasTextDisabledShadow: ButtonHilight, + canvasTextInvert: HilightText, + checkmark: WindowText, + checkmarkDisabled: GrayText, + flatDark: ButtonShadow, + flatLight: ButtonLight, + focusSecondary: ButtonHilight, // should be Hilight inverted + headerBackground: useGradients + ? linearGradient(ActiveTitle, GradientActiveTitle) + : ActiveTitle, + headerNotActiveBackground: useGradients + ? linearGradient(InactiveTitle, GradientInactiveTitle) + : InactiveTitle, + headerNotActiveText: InactiveTitleText, + headerText: TitleText, + hoverBackground: Hilight, + material: ButtonFace, + materialDark: InactiveTitle, + materialText: ButtonText, + materialTextDisabled: ButtonShadow, + materialTextDisabledShadow: ButtonHilight, + materialTextInvert: HilightText, + progress: Hilight, + tooltip: InfoWindow + }; +} + // helper functions below are from Material UI (https://github.com/mui-org/material-ui) export function getDecimalPrecision(num) { if (Math.abs(num) < 1) { diff --git a/src/common/utils/index.spec.js b/src/common/utils/index.spec.js index 282aa4ae..7a3cebf4 100644 --- a/src/common/utils/index.spec.js +++ b/src/common/utils/index.spec.js @@ -1,4 +1,9 @@ -import { clamp, getDecimalPrecision, roundValueToStep } from './index'; +import { + clamp, + mapFromWindowsTheme, + getDecimalPrecision, + roundValueToStep +} from './index'; describe('clamp', () => { it('should return passed value if its between min and max', () => { @@ -22,6 +27,148 @@ describe('clamp', () => { }); }); +describe('mapFromWindowsTheme', () => { + it('should map corresponding properties directly if gradients are disabled', () => { + const theme = { + ButtonAlternateFace: '#000000', + ButtonDkShadow: '#000001', + ButtonFace: '#000002', + ButtonHilight: '#000003', + ButtonLight: '#000004', + ButtonShadow: '#000005', + ButtonText: '#000006', + ActiveBorder: '#000007', + AppWorkspace: '#000008', + Background: '#000009', + InactiveBorder: '#00000a', + Scrollbar: '#00000b', + Window: '#00000c', + WindowFrame: '#00000d', + WindowText: '#00000e', + ActiveTitle: '#00000f', + GradientActiveTitle: '#000010', + GradientInactiveTitle: '#000011', + InactiveTitle: '#000012', + InactiveTitleText: '#000013', + TitleText: '#000014', + Menu: '#000015', + MenuBar: '#000016', + MenuHilight: '#000017', + MenuText: '#000018', + GrayText: '#000019', + Hilight: '#00001a', + HilightText: '#00001b', + HotTrackingColor: '#00001c', + InfoText: '#00001d', + InfoWindow: '#00001e' + }; + const expectedTheme = { + name: 'theme', + anchor: '#00001c', + anchorVisited: '#00001c', + borderDark: '#000005', + borderDarkest: '#000001', + borderLight: '#000004', + borderLightest: '#000003', + canvas: '#00000c', + canvasText: '#00000e', + canvasTextDisabled: '#000005', + canvasTextDisabledShadow: '#000003', + canvasTextInvert: '#00001b', + checkmark: '#00000e', + checkmarkDisabled: '#000019', + flatDark: '#000005', + flatLight: '#000004', + focusSecondary: '#000003', + headerBackground: '#00000f', + headerNotActiveBackground: '#000012', + headerNotActiveText: '#000013', + headerText: '#000014', + hoverBackground: '#00001a', + material: '#000002', + materialDark: '#000012', + materialText: '#000006', + materialTextDisabled: '#000005', + materialTextDisabledShadow: '#000003', + materialTextInvert: '#00001b', + progress: '#00001a', + tooltip: '#00001e' + }; + + expect(mapFromWindowsTheme('theme', theme, false)).toEqual(expectedTheme); + }); + + it('should map corresponding properties with gradients if gradients are enabled', () => { + const theme = { + ButtonAlternateFace: '#000000', + ButtonDkShadow: '#000001', + ButtonFace: '#000002', + ButtonHilight: '#000003', + ButtonLight: '#000004', + ButtonShadow: '#000005', + ButtonText: '#000006', + ActiveBorder: '#000007', + AppWorkspace: '#000008', + Background: '#000009', + InactiveBorder: '#00000a', + Scrollbar: '#00000b', + Window: '#00000c', + WindowFrame: '#00000d', + WindowText: '#00000e', + ActiveTitle: '#00000f', + GradientActiveTitle: '#000010', + GradientInactiveTitle: '#000011', + InactiveTitle: '#000012', + InactiveTitleText: '#000013', + TitleText: '#000014', + Menu: '#000015', + MenuBar: '#000016', + MenuHilight: '#000017', + MenuText: '#000018', + GrayText: '#000019', + Hilight: '#00001a', + HilightText: '#00001b', + HotTrackingColor: '#00001c', + InfoText: '#00001d', + InfoWindow: '#00001e' + }; + const expectedTheme = { + name: 'theme', + anchor: '#00001c', + anchorVisited: '#00001c', + borderDark: '#000005', + borderDarkest: '#000001', + borderLight: '#000004', + borderLightest: '#000003', + canvas: '#00000c', + canvasText: '#00000e', + canvasTextDisabled: '#000005', + canvasTextDisabledShadow: '#000003', + canvasTextInvert: '#00001b', + checkmark: '#00000e', + checkmarkDisabled: '#000019', + flatDark: '#000005', + flatLight: '#000004', + focusSecondary: '#000003', + headerBackground: 'linear-gradient(to right, #00000f, #000010)', + headerNotActiveBackground: 'linear-gradient(to right, #000012, #000011)', + headerNotActiveText: '#000013', + headerText: '#000014', + hoverBackground: '#00001a', + material: '#000002', + materialDark: '#000012', + materialText: '#000006', + materialTextDisabled: '#000005', + materialTextDisabledShadow: '#000003', + materialTextInvert: '#00001b', + progress: '#00001a', + tooltip: '#00001e' + }; + + expect(mapFromWindowsTheme('theme', theme, true)).toEqual(expectedTheme); + }); +}); + describe('getDecimalPrecision', () => { it('should return 0 when passed a round number', () => { expect(getDecimalPrecision(4)).toBe(0); From f0ed55b70278cdf881674a7915ed4a026b7e551f Mon Sep 17 00:00:00 2001 From: tPenguinLTG Date: Tue, 1 Dec 2020 23:51:44 -0500 Subject: [PATCH 2/2] feat(themes): add peggysPastels theme "Peggy's Pastels" by tPenguinLTG https://www.deviantart.com/tpenguinltg/art/Peggy-s-Pastels-505540096 --- src/common/themes/index.js | 2 ++ src/common/themes/peggysPastels.js | 45 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/common/themes/peggysPastels.js diff --git a/src/common/themes/index.js b/src/common/themes/index.js index 112a07ea..71e4c131 100644 --- a/src/common/themes/index.js +++ b/src/common/themes/index.js @@ -19,6 +19,7 @@ import ninjaTurtles from './ninjaTurtles'; import olive from './olive'; import original from './original'; import pamelaAnderson from './pamelaAnderson'; +import peggysPastels from './peggysPastels'; import plum from './plum'; import rainyDay from './rainyDay'; import rose from './rose'; @@ -55,6 +56,7 @@ export default { olive, original, pamelaAnderson, + peggysPastels, plum, rainyDay, rose, diff --git a/src/common/themes/peggysPastels.js b/src/common/themes/peggysPastels.js new file mode 100644 index 00000000..7eec6944 --- /dev/null +++ b/src/common/themes/peggysPastels.js @@ -0,0 +1,45 @@ +/* "Peggy's Pastels" by tPenguinLTG + * https://www.deviantart.com/tpenguinltg/art/Peggy-s-Pastels-505540096 + */ + +const { mapFromWindowsTheme } = require('../utils'); + +const theme = { + ActiveBorder: 'rgb(244, 193, 202)', + ActiveTitle: 'rgb(0, 191, 188)', + AppWorkspace: 'rgb(255, 184, 182)', + Background: 'rgb(162, 219, 210)', + ButtonAlternateFace: 'rgb(181, 181, 181)', + ButtonDkShadow: 'rgb(64, 64, 64)', + ButtonFace: 'rgb(244, 193, 202)', + ButtonHilight: 'rgb(250, 224, 228)', + ButtonLight: 'rgb(247, 219, 215)', + ButtonShadow: 'rgb(222, 69, 96)', + ButtonText: 'rgb(0, 0, 0)', + GradientActiveTitle: 'rgb(202, 156, 185)', + GradientInactiveTitle: 'rgb(236, 145, 162)', + GrayText: 'rgb(222, 69, 96)', + Hilight: 'rgb(162, 219, 210)', + HilightText: 'rgb(0, 0, 0)', + HotTrackingColor: 'rgb(0, 128, 128)', + InactiveBorder: 'rgb(244, 193, 202)', + InactiveTitle: 'rgb(0, 187, 169)', + InactiveTitleText: 'rgb(0, 85, 77)', + InfoText: 'rgb(0, 0, 0)', + InfoWindow: 'rgb(204, 255, 255)', + Menu: 'rgb(244, 193, 202)', + MenuHilight: 'rgb(162, 219, 210)', + MenuText: 'rgb(0, 0, 0)', + Scrollbar: 'rgb(250, 224, 228)', + TitleText: 'rgb(255, 255, 255)', + Window: 'rgb(244, 255, 255)', + WindowFrame: 'rgb(0, 0, 0)', + WindowText: 'rgb(0, 0, 0)' +}; + +export default mapFromWindowsTheme('peggysPastels', theme, false); +export const peggysPastelsG = mapFromWindowsTheme( + 'peggysPastelsG', + theme, + true +);