From 9e9d4f294ab63510f4d6faa48a8d9599f2cb6f6f Mon Sep 17 00:00:00 2001 From: "Mr. M" Date: Wed, 16 Jul 2025 23:27:40 +0200 Subject: [PATCH] feat: Added a better custom color input, b=no-bug, c=tabs, workspaces --- .../content/zen-panels/gradient-generator.inc | 3 +- src/zen/tabs/zen-tabs/vertical-tabs.css | 2 +- src/zen/workspaces/ZenGradientGenerator.mjs | 151 +++++------------- src/zen/workspaces/ZenWorkspace.mjs | 2 +- 4 files changed, 47 insertions(+), 111 deletions(-) diff --git a/src/browser/base/content/zen-panels/gradient-generator.inc b/src/browser/base/content/zen-panels/gradient-generator.inc index fa2c495da..b5f87468b 100644 --- a/src/browser/base/content/zen-panels/gradient-generator.inc +++ b/src/browser/base/content/zen-panels/gradient-generator.inc @@ -116,7 +116,8 @@ - + + diff --git a/src/zen/tabs/zen-tabs/vertical-tabs.css b/src/zen/tabs/zen-tabs/vertical-tabs.css index 316ad7fa0..5507f2b84 100644 --- a/src/zen/tabs/zen-tabs/vertical-tabs.css +++ b/src/zen/tabs/zen-tabs/vertical-tabs.css @@ -156,7 +156,7 @@ /* ========================================================================== Pinned Tabs Separator ========================================================================== */ -.vertical-pinned-tabs-container-separator { +.pinned-tabs-container-separator { background: light-dark(rgba(1, 1, 1, 0.075), rgba(255, 255, 255, 0.1)); margin: 8px auto; /* Center horizontally */ border: none; diff --git a/src/zen/workspaces/ZenGradientGenerator.mjs b/src/zen/workspaces/ZenGradientGenerator.mjs index d9996d6e9..5935b5b3f 100644 --- a/src/zen/workspaces/ZenGradientGenerator.mjs +++ b/src/zen/workspaces/ZenGradientGenerator.mjs @@ -175,6 +175,13 @@ }); } + initCustomColorInput() { + this.customColorInput.addEventListener('change', (event) => { + // Prevent the popup from closing when the input is focused + this.openThemePicker(event); + }); + } + initPredefinedColors() { document .getElementById('PanelUI-zen-gradient-generator-color-pages') @@ -218,10 +225,6 @@ }); } - initCustomColorInput() { - this.customColorInput.addEventListener('keydown', this.onCustomColorKeydown.bind(this)); - } - initColorPages() { const leftButton = document.getElementById('PanelUI-zen-gradient-generator-color-page-left'); const rightButton = document.getElementById( @@ -336,14 +339,6 @@ this._onTextureMouseUp = null; } - onCustomColorKeydown(event) { - // Check for Enter key to add custom colors - if (event.key === 'Enter') { - event.preventDefault(); - this.addCustomColor(); - } - } - initThemePicker() { const themePicker = this.panel.querySelector('.zen-theme-picker-gradient'); this._onDotMouseMove = this.onDotMouseMove.bind(this); @@ -558,6 +553,24 @@ return; } + let colorOpacity = + document.getElementById('PanelUI-zen-gradient-generator-custom-opacity')?.value ?? 1; + // Convert the opacity into a hex value if it's not already + if (colorOpacity < 1) { + // e.g. if opacity is 1, we add to the color FF, if it's 0.5 we add 80, etc. + const hexOpacity = Math.round(colorOpacity * 255) + .toString(16) + .padStart(2, '0') + .toUpperCase(); + // If the color is in hex format + if (color.startsWith('#')) { + // If the color is already in hex format, we just append the opacity + if (color.length === 7) { + color += hexOpacity; + } + } + } + // Add '#' prefix if it's missing and the input appears to be a hex color if (!color.startsWith('#') && /^[0-9A-Fa-f]{3,6}$/.test(color)) { color = '#' + color; @@ -570,6 +583,7 @@ dot.style.setProperty('--zen-theme-picker-dot-color', color); this.panel.querySelector('#PanelUI-zen-gradient-generator-custom-list').prepend(dot); this.customColorInput.value = ''; + document.getElementById('PanelUI-zen-gradient-generator-custom-opacity').value = 1; await this.updateCurrentWorkspace(); } @@ -1242,93 +1256,13 @@ ]; } - pSBC = (p, c0, c1, l) => { - let r, - g, - b, - P, - f, - t, - h, - i = parseInt, - m = Math.round, - a = typeof c1 == 'string'; - if ( - typeof p != 'number' || - p < -1 || - p > 1 || - typeof c0 != 'string' || - (c0[0] != 'r' && c0[0] != '#') || - (c1 && !a) - ) - return null; - if (!this.pSBCr) - this.pSBCr = (d) => { - let n = d.length, - x = {}; - if (n > 9) { - ([r, g, b, a] = d = d.split(',')), (n = d.length); - if (n < 3 || n > 4) return null; - (x.r = i(r[3] == 'a' ? r.slice(5) : r.slice(4))), - (x.g = i(g)), - (x.b = i(b)), - (x.a = a ? parseFloat(a) : -1); - } else { - if (n == 8 || n == 6 || n < 4) return null; - if (n < 6) - d = '#' + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (n > 4 ? d[4] + d[4] : ''); - d = i(d.slice(1), 16); - if (n == 9 || n == 5) - (x.r = (d >> 24) & 255), - (x.g = (d >> 16) & 255), - (x.b = (d >> 8) & 255), - (x.a = m((d & 255) / 0.255) / 1000); - else (x.r = d >> 16), (x.g = (d >> 8) & 255), (x.b = d & 255), (x.a = -1); - } - return x; - }; - (h = c0.length > 9), - (h = a ? (c1.length > 9 ? true : c1 == 'c' ? !h : false) : h), - (f = this.pSBCr(c0)), - (P = p < 0), - (t = - c1 && c1 != 'c' - ? this.pSBCr(c1) - : P - ? { r: 0, g: 0, b: 0, a: -1 } - : { r: 255, g: 255, b: 255, a: -1 }), - (p = P ? p * -1 : p), - (P = 1 - p); - if (!f || !t) return null; - if (l) (r = m(P * f.r + p * t.r)), (g = m(P * f.g + p * t.g)), (b = m(P * f.b + p * t.b)); - else - (r = m((P * f.r ** 2 + p * t.r ** 2) ** 0.5)), - (g = m((P * f.g ** 2 + p * t.g ** 2) ** 0.5)), - (b = m((P * f.b ** 2 + p * t.b ** 2) ** 0.5)); - (a = f.a), - (t = t.a), - (f = a >= 0 || t >= 0), - (a = f ? (a < 0 ? t : t < 0 ? a : a * P + t * p) : 0); - if (h) - return ( - 'rgb' + - (f ? 'a(' : '(') + - r + - ',' + - g + - ',' + - b + - (f ? ',' + m(a * 1000) / 1000 : '') + - ')' - ); - else - return ( - '#' + - (4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0)) - .toString(16) - .slice(1, f ? undefined : -2) - ); - }; + /** + * Get the primary color from a list of colors. + * @returns {string} The primary color in hex format. + */ + getAccentColorForUI(accentColor) { + return `rgb(${accentColor[0]}, ${accentColor[1]}, ${accentColor[2]})`; + } getMostDominantColor(allColors) { const color = this.getPrimaryColor(allColors); @@ -1400,7 +1334,7 @@ let dominantColor = this.getMostDominantColor(workspaceTheme.gradientColors); const isDefaultTheme = !dominantColor; if (isDefaultTheme) { - dominantColor = this.hexToRgb(this.getNativeAccentColor()); + dominantColor = this.getNativeAccentColor(); } const opacitySlider = browser.document.getElementById( @@ -1509,13 +1443,8 @@ ); const isDarkModeWindow = browser.gZenThemePicker.isDarkMode; if (dominantColor) { - browser.document.documentElement.style.setProperty( - '--zen-primary-color', - this.pSBC( - isDarkModeWindow ? 0.2 : -0.5, - `rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})` - ) - ); + const primaryColor = this.getAccentColorForUI(dominantColor); + browser.document.documentElement.style.setProperty('--zen-primary-color', primaryColor); browser.gZenThemePicker.isLegacyVersion = this.isLegacyVersion; let isDarkMode = isDarkModeWindow; const isUsingCustomColors = workspaceTheme.gradientColors.some((color) => color.isCustom); @@ -1557,7 +1486,13 @@ } getNativeAccentColor() { - return Services.prefs.getStringPref('zen.theme.accent-color'); + const accentColor = Services.prefs.getStringPref('zen.theme.accent-color'); + const rgb = this.hexToRgb(accentColor); + if (this.isDarkMode) { + // If the theme is dark, we want to use a lighter color + return this.blendColors(rgb, [0, 0, 0], 30); + } + return rgb; } resetCustomColorList() { diff --git a/src/zen/workspaces/ZenWorkspace.mjs b/src/zen/workspaces/ZenWorkspace.mjs index 4795fed0b..139f05cb6 100644 --- a/src/zen/workspaces/ZenWorkspace.mjs +++ b/src/zen/workspaces/ZenWorkspace.mjs @@ -12,7 +12,7 @@ - +