mirror of
https://github.com/zen-browser/desktop.git
synced 2025-10-15 06:16:14 +00:00
feat: Added a better custom color input, b=no-bug, c=tabs, workspaces
This commit is contained in:
@@ -116,7 +116,8 @@
|
|||||||
<vbox id="zen-theme-picker-color">
|
<vbox id="zen-theme-picker-color">
|
||||||
<label data-l10n-id="zen-panel-ui-gradient-generator-custom-color"></label>
|
<label data-l10n-id="zen-panel-ui-gradient-generator-custom-color"></label>
|
||||||
<hbox>
|
<hbox>
|
||||||
<html:input type="text" placeholder="#000000" id="PanelUI-zen-gradient-generator-custom-input" />
|
<html:input type="color" id="PanelUI-zen-gradient-generator-custom-input" />
|
||||||
|
<html:input type="number" value="1" min="0" max="1" step="0.01" id="PanelUI-zen-gradient-generator-custom-opacity" />
|
||||||
<toolbarbutton id="PanelUI-zen-gradient-generator-color-custom-add" class="subviewbutton">
|
<toolbarbutton id="PanelUI-zen-gradient-generator-color-custom-add" class="subviewbutton">
|
||||||
<image></image>
|
<image></image>
|
||||||
</toolbarbutton>
|
</toolbarbutton>
|
||||||
|
@@ -156,7 +156,7 @@
|
|||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Pinned Tabs Separator
|
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));
|
background: light-dark(rgba(1, 1, 1, 0.075), rgba(255, 255, 255, 0.1));
|
||||||
margin: 8px auto; /* Center horizontally */
|
margin: 8px auto; /* Center horizontally */
|
||||||
border: none;
|
border: none;
|
||||||
|
@@ -175,6 +175,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initCustomColorInput() {
|
||||||
|
this.customColorInput.addEventListener('change', (event) => {
|
||||||
|
// Prevent the popup from closing when the input is focused
|
||||||
|
this.openThemePicker(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
initPredefinedColors() {
|
initPredefinedColors() {
|
||||||
document
|
document
|
||||||
.getElementById('PanelUI-zen-gradient-generator-color-pages')
|
.getElementById('PanelUI-zen-gradient-generator-color-pages')
|
||||||
@@ -218,10 +225,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initCustomColorInput() {
|
|
||||||
this.customColorInput.addEventListener('keydown', this.onCustomColorKeydown.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
initColorPages() {
|
initColorPages() {
|
||||||
const leftButton = document.getElementById('PanelUI-zen-gradient-generator-color-page-left');
|
const leftButton = document.getElementById('PanelUI-zen-gradient-generator-color-page-left');
|
||||||
const rightButton = document.getElementById(
|
const rightButton = document.getElementById(
|
||||||
@@ -336,14 +339,6 @@
|
|||||||
this._onTextureMouseUp = null;
|
this._onTextureMouseUp = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCustomColorKeydown(event) {
|
|
||||||
// Check for Enter key to add custom colors
|
|
||||||
if (event.key === 'Enter') {
|
|
||||||
event.preventDefault();
|
|
||||||
this.addCustomColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initThemePicker() {
|
initThemePicker() {
|
||||||
const themePicker = this.panel.querySelector('.zen-theme-picker-gradient');
|
const themePicker = this.panel.querySelector('.zen-theme-picker-gradient');
|
||||||
this._onDotMouseMove = this.onDotMouseMove.bind(this);
|
this._onDotMouseMove = this.onDotMouseMove.bind(this);
|
||||||
@@ -558,6 +553,24 @@
|
|||||||
return;
|
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
|
// 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)) {
|
if (!color.startsWith('#') && /^[0-9A-Fa-f]{3,6}$/.test(color)) {
|
||||||
color = '#' + color;
|
color = '#' + color;
|
||||||
@@ -570,6 +583,7 @@
|
|||||||
dot.style.setProperty('--zen-theme-picker-dot-color', color);
|
dot.style.setProperty('--zen-theme-picker-dot-color', color);
|
||||||
this.panel.querySelector('#PanelUI-zen-gradient-generator-custom-list').prepend(dot);
|
this.panel.querySelector('#PanelUI-zen-gradient-generator-custom-list').prepend(dot);
|
||||||
this.customColorInput.value = '';
|
this.customColorInput.value = '';
|
||||||
|
document.getElementById('PanelUI-zen-gradient-generator-custom-opacity').value = 1;
|
||||||
await this.updateCurrentWorkspace();
|
await this.updateCurrentWorkspace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1242,93 +1256,13 @@
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
pSBC = (p, c0, c1, l) => {
|
/**
|
||||||
let r,
|
* Get the primary color from a list of colors.
|
||||||
g,
|
* @returns {string} The primary color in hex format.
|
||||||
b,
|
*/
|
||||||
P,
|
getAccentColorForUI(accentColor) {
|
||||||
f,
|
return `rgb(${accentColor[0]}, ${accentColor[1]}, ${accentColor[2]})`;
|
||||||
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)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
getMostDominantColor(allColors) {
|
getMostDominantColor(allColors) {
|
||||||
const color = this.getPrimaryColor(allColors);
|
const color = this.getPrimaryColor(allColors);
|
||||||
@@ -1400,7 +1334,7 @@
|
|||||||
let dominantColor = this.getMostDominantColor(workspaceTheme.gradientColors);
|
let dominantColor = this.getMostDominantColor(workspaceTheme.gradientColors);
|
||||||
const isDefaultTheme = !dominantColor;
|
const isDefaultTheme = !dominantColor;
|
||||||
if (isDefaultTheme) {
|
if (isDefaultTheme) {
|
||||||
dominantColor = this.hexToRgb(this.getNativeAccentColor());
|
dominantColor = this.getNativeAccentColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
const opacitySlider = browser.document.getElementById(
|
const opacitySlider = browser.document.getElementById(
|
||||||
@@ -1509,13 +1443,8 @@
|
|||||||
);
|
);
|
||||||
const isDarkModeWindow = browser.gZenThemePicker.isDarkMode;
|
const isDarkModeWindow = browser.gZenThemePicker.isDarkMode;
|
||||||
if (dominantColor) {
|
if (dominantColor) {
|
||||||
browser.document.documentElement.style.setProperty(
|
const primaryColor = this.getAccentColorForUI(dominantColor);
|
||||||
'--zen-primary-color',
|
browser.document.documentElement.style.setProperty('--zen-primary-color', primaryColor);
|
||||||
this.pSBC(
|
|
||||||
isDarkModeWindow ? 0.2 : -0.5,
|
|
||||||
`rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
browser.gZenThemePicker.isLegacyVersion = this.isLegacyVersion;
|
browser.gZenThemePicker.isLegacyVersion = this.isLegacyVersion;
|
||||||
let isDarkMode = isDarkModeWindow;
|
let isDarkMode = isDarkModeWindow;
|
||||||
const isUsingCustomColors = workspaceTheme.gradientColors.some((color) => color.isCustom);
|
const isUsingCustomColors = workspaceTheme.gradientColors.some((color) => color.isCustom);
|
||||||
@@ -1557,7 +1486,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
getNativeAccentColor() {
|
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() {
|
resetCustomColorList() {
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
</vbox>
|
</vbox>
|
||||||
<arrowscrollbox orient="vertical" class="workspace-arrowscrollbox">
|
<arrowscrollbox orient="vertical" class="workspace-arrowscrollbox">
|
||||||
<vbox class="zen-workspace-tabs-section zen-workspace-pinned-tabs-section">
|
<vbox class="zen-workspace-tabs-section zen-workspace-pinned-tabs-section">
|
||||||
<html:div class="vertical-pinned-tabs-container-separator"></html:div>
|
<html:div class="pinned-tabs-container-separator"></html:div>
|
||||||
</vbox>
|
</vbox>
|
||||||
<vbox class="zen-workspace-tabs-section zen-workspace-normal-tabs-section">
|
<vbox class="zen-workspace-tabs-section zen-workspace-normal-tabs-section">
|
||||||
<!-- Let it me as an ID to mantain compatibility with firefox's tabbrowser -->
|
<!-- Let it me as an ID to mantain compatibility with firefox's tabbrowser -->
|
||||||
|
Reference in New Issue
Block a user