mirror of
https://github.com/Boof2015/prism.git
synced 2026-08-17 19:24:03 +02:00
theme improvement
This commit is contained in:
@@ -75,6 +75,7 @@ export function scopeSettingsToOptions(
|
|||||||
secondaryLineColor: t.sideLine,
|
secondaryLineColor: t.sideLine,
|
||||||
gradientColors: t.fillGradient,
|
gradientColors: t.fillGradient,
|
||||||
heatColors: t.heatColors,
|
heatColors: t.heatColors,
|
||||||
|
heatBaseColor: t.heatBase,
|
||||||
backgroundColor: t.background,
|
backgroundColor: t.background,
|
||||||
gridColor: t.guides,
|
gridColor: t.guides,
|
||||||
labelColor: t.labels,
|
labelColor: t.labels,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
--glass-bg: rgba(255, 255, 255, 0.03);
|
--glass-bg: rgba(255, 255, 255, 0.03);
|
||||||
--glass-border: rgba(255, 255, 255, 0.08);
|
--glass-border: rgba(255, 255, 255, 0.08);
|
||||||
--glass-highlight: rgba(255, 255, 255, 0.045);
|
--glass-highlight: rgba(255, 255, 255, 0.045);
|
||||||
|
--glass-highlight-strong: rgba(255, 255, 255, 0.14);
|
||||||
|
|
||||||
--text-primary: rgba(255, 255, 255, 0.95);
|
--text-primary: rgba(255, 255, 255, 0.95);
|
||||||
--text-secondary: rgba(255, 255, 255, 0.62);
|
--text-secondary: rgba(255, 255, 255, 0.62);
|
||||||
@@ -377,7 +378,7 @@ select {
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--control-border);
|
border: 1px solid var(--control-border);
|
||||||
background: var(--control-bg);
|
background: var(--control-bg);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: inset 0 1px 0 var(--glass-highlight);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
@@ -461,7 +462,7 @@ select {
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--control-border);
|
border: 1px solid var(--control-border);
|
||||||
background: var(--control-bg);
|
background: var(--control-bg);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: inset 0 1px 0 var(--glass-highlight);
|
||||||
color: var(--text-tertiary);
|
color: var(--text-tertiary);
|
||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -497,7 +498,7 @@ select {
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--control-border);
|
border: 1px solid var(--control-border);
|
||||||
background: var(--control-bg);
|
background: var(--control-bg);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: inset 0 1px 0 var(--glass-highlight);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1067,7 +1068,7 @@ select {
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid var(--control-border);
|
border: 1px solid var(--control-border);
|
||||||
background: var(--control-bg);
|
background: var(--control-bg);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: inset 0 1px 0 var(--glass-highlight);
|
||||||
color: var(--control-text);
|
color: var(--control-text);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
transition: border-color 140ms ease, background-color 140ms ease, box-shadow 140ms ease, color 140ms ease;
|
transition: border-color 140ms ease, background-color 140ms ease, box-shadow 140ms ease, color 140ms ease;
|
||||||
@@ -1152,9 +1153,9 @@ select {
|
|||||||
border: 1px solid var(--control-border);
|
border: 1px solid var(--control-border);
|
||||||
background:
|
background:
|
||||||
linear-gradient(90deg, var(--slider-fill), var(--slider-fill)) 0 / var(--range-percent) 100% no-repeat,
|
linear-gradient(90deg, var(--slider-fill), var(--slider-fill)) 0 / var(--range-percent) 100% no-repeat,
|
||||||
linear-gradient(180deg, var(--slider-track), rgba(255, 255, 255, 0.04));
|
linear-gradient(180deg, var(--slider-track), var(--glass-highlight));
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.05),
|
inset 0 1px 0 var(--glass-highlight),
|
||||||
0 0 0 1px rgba(0, 0, 0, 0.22);
|
0 0 0 1px rgba(0, 0, 0, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,7 +1168,7 @@ select {
|
|||||||
border: 1px solid var(--control-border-active);
|
border: 1px solid var(--control-border-active);
|
||||||
background: var(--slider-thumb);
|
background: var(--slider-thumb);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.12),
|
inset 0 1px 0 var(--glass-highlight-strong),
|
||||||
0 0 0 2px rgba(var(--accent-rgb), 0.14),
|
0 0 0 2px rgba(var(--accent-rgb), 0.14),
|
||||||
0 3px 8px rgba(0, 0, 0, 0.35);
|
0 3px 8px rgba(0, 0, 0, 0.35);
|
||||||
}
|
}
|
||||||
@@ -1176,9 +1177,9 @@ select {
|
|||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--control-border);
|
border: 1px solid var(--control-border);
|
||||||
background: linear-gradient(180deg, var(--slider-track), rgba(255, 255, 255, 0.04));
|
background: linear-gradient(180deg, var(--slider-track), var(--glass-highlight));
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.05),
|
inset 0 1px 0 var(--glass-highlight),
|
||||||
0 0 0 1px rgba(0, 0, 0, 0.22);
|
0 0 0 1px rgba(0, 0, 0, 0.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1189,7 +1190,7 @@ select {
|
|||||||
border: 1px solid var(--control-border-active);
|
border: 1px solid var(--control-border-active);
|
||||||
background: var(--slider-thumb);
|
background: var(--slider-thumb);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.12),
|
inset 0 1px 0 var(--glass-highlight-strong),
|
||||||
0 0 0 2px rgba(var(--accent-rgb), 0.14),
|
0 0 0 2px rgba(var(--accent-rgb), 0.14),
|
||||||
0 3px 8px rgba(0, 0, 0, 0.35);
|
0 3px 8px rgba(0, 0, 0, 0.35);
|
||||||
}
|
}
|
||||||
@@ -1197,7 +1198,7 @@ select {
|
|||||||
.settings-control__range::-moz-range-progress {
|
.settings-control__range::-moz-range-progress {
|
||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.02);
|
border: 1px solid var(--glass-highlight);
|
||||||
background: linear-gradient(90deg, var(--slider-fill), var(--slider-fill));
|
background: linear-gradient(90deg, var(--slider-fill), var(--slider-fill));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1217,7 +1218,7 @@ select {
|
|||||||
.settings-control__range:focus-visible::-webkit-slider-thumb {
|
.settings-control__range:focus-visible::-webkit-slider-thumb {
|
||||||
border-color: rgba(var(--accent-rgb), 0.96);
|
border-color: rgba(var(--accent-rgb), 0.96);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.16),
|
inset 0 1px 0 var(--glass-highlight-strong),
|
||||||
0 0 0 3px rgba(var(--accent-rgb), 0.18),
|
0 0 0 3px rgba(var(--accent-rgb), 0.18),
|
||||||
0 3px 10px rgba(0, 0, 0, 0.4);
|
0 3px 10px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
@@ -1226,7 +1227,7 @@ select {
|
|||||||
.settings-control__range:focus-visible::-moz-range-thumb {
|
.settings-control__range:focus-visible::-moz-range-thumb {
|
||||||
border-color: rgba(var(--accent-rgb), 0.96);
|
border-color: rgba(var(--accent-rgb), 0.96);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.16),
|
inset 0 1px 0 var(--glass-highlight-strong),
|
||||||
0 0 0 3px rgba(var(--accent-rgb), 0.18),
|
0 0 0 3px rgba(var(--accent-rgb), 0.18),
|
||||||
0 3px 10px rgba(0, 0, 0, 0.4);
|
0 3px 10px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
@@ -1392,7 +1393,7 @@ select {
|
|||||||
background: linear-gradient(180deg, var(--input-bg), var(--settings-bg-bottom));
|
background: linear-gradient(180deg, var(--input-bg), var(--settings-bg-bottom));
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 3px 4px;
|
padding: 3px 4px;
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: inset 0 1px 0 var(--glass-highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-panel__close {
|
.settings-panel__close {
|
||||||
@@ -1739,7 +1740,7 @@ select {
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
background: var(--control-bg);
|
background: var(--control-bg);
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: inset 0 1px 0 var(--glass-highlight);
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease, transform 120ms ease;
|
transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease, transform 120ms ease;
|
||||||
@@ -1770,7 +1771,7 @@ select {
|
|||||||
.settings-control__select:focus-within {
|
.settings-control__select:focus-within {
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.06),
|
inset 0 1px 0 var(--glass-highlight),
|
||||||
0 0 0 1px rgba(var(--accent-rgb), 0.32),
|
0 0 0 1px rgba(var(--accent-rgb), 0.32),
|
||||||
0 0 0 4px rgba(var(--accent-rgb), 0.12);
|
0 0 0 4px rgba(var(--accent-rgb), 0.12);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export interface SpectrumAnalyzerOptions {
|
|||||||
heatmapFill?: boolean
|
heatmapFill?: boolean
|
||||||
gradientColors?: string[]
|
gradientColors?: string[]
|
||||||
heatColors?: [string, string, string]
|
heatColors?: [string, string, string]
|
||||||
|
heatBaseColor?: string
|
||||||
backgroundColor?: string
|
backgroundColor?: string
|
||||||
showGrid?: boolean
|
showGrid?: boolean
|
||||||
gridColor?: string
|
gridColor?: string
|
||||||
@@ -198,6 +199,7 @@ const defaultOptions: ResolvedSpectrumAnalyzerOptions = {
|
|||||||
heatmapFill: false,
|
heatmapFill: false,
|
||||||
gradientColors: ['rgba(0, 255, 255, 0)', 'rgba(0, 255, 255, 0.3)', 'rgba(138, 43, 226, 0.5)'],
|
gradientColors: ['rgba(0, 255, 255, 0)', 'rgba(0, 255, 255, 0.3)', 'rgba(138, 43, 226, 0.5)'],
|
||||||
heatColors: [...LEGACY_DEFAULT_HEAT_COLORS],
|
heatColors: [...LEGACY_DEFAULT_HEAT_COLORS],
|
||||||
|
heatBaseColor: 'transparent',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
showGrid: true,
|
showGrid: true,
|
||||||
gridColor: 'rgba(255, 255, 255, 0.1)',
|
gridColor: 'rgba(255, 255, 255, 0.1)',
|
||||||
@@ -636,6 +638,12 @@ export class SpectrumAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderHeatmap(xPoints: Float32Array, yPoints: Float32Array, heatmapIntensity: Float32Array, pointCount: number, width: number, height: number): void {
|
private renderHeatmap(xPoints: Float32Array, yPoints: Float32Array, heatmapIntensity: Float32Array, pointCount: number, width: number, height: number): void {
|
||||||
|
const baseColor = this.options.heatBaseColor
|
||||||
|
if (baseColor && baseColor !== 'transparent') {
|
||||||
|
this.ctx.fillStyle = baseColor
|
||||||
|
this.ctx.fillRect(0, 0, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
for (let index = 0; index < pointCount; index += 1) {
|
for (let index = 0; index < pointCount; index += 1) {
|
||||||
const x = Math.floor(xPoints[index])
|
const x = Math.floor(xPoints[index])
|
||||||
const y = yPoints[index]
|
const y = yPoints[index]
|
||||||
|
|||||||
+90
-23
@@ -63,6 +63,10 @@ const APP_SCHEMA = {
|
|||||||
border: 'border',
|
border: 'border',
|
||||||
text: 'text',
|
text: 'text',
|
||||||
text_muted: 'textMuted',
|
text_muted: 'textMuted',
|
||||||
|
toolbar_bg: 'toolbarBg',
|
||||||
|
settings_bg_top: 'settingsBgTop',
|
||||||
|
settings_bg_bottom: 'settingsBgBottom',
|
||||||
|
bottom_bar_bg: 'bottomBarBg',
|
||||||
} as const satisfies SectionSchema<ThemeAppTokens>
|
} as const satisfies SectionSchema<ThemeAppTokens>
|
||||||
|
|
||||||
const CONTROLS_SCHEMA = {
|
const CONTROLS_SCHEMA = {
|
||||||
@@ -77,6 +81,7 @@ const CONTROLS_SCHEMA = {
|
|||||||
menu_surface: 'menuSurface',
|
menu_surface: 'menuSurface',
|
||||||
menu_border: 'menuBorder',
|
menu_border: 'menuBorder',
|
||||||
slider: 'slider',
|
slider: 'slider',
|
||||||
|
flat_controls: 'flatControls',
|
||||||
} as const satisfies SectionSchema<ThemeControlsTokens>
|
} as const satisfies SectionSchema<ThemeControlsTokens>
|
||||||
|
|
||||||
const SCOPES_SCHEMA = {
|
const SCOPES_SCHEMA = {
|
||||||
@@ -95,11 +100,14 @@ const SPECTRUM_SCHEMA = {
|
|||||||
heat_low: 'heatLow',
|
heat_low: 'heatLow',
|
||||||
heat_mid: 'heatMid',
|
heat_mid: 'heatMid',
|
||||||
heat_high: 'heatHigh',
|
heat_high: 'heatHigh',
|
||||||
|
heat_base: 'heatBase',
|
||||||
|
guides: 'guides',
|
||||||
} as const satisfies SectionSchema<ThemeSpectrumTokens>
|
} as const satisfies SectionSchema<ThemeSpectrumTokens>
|
||||||
|
|
||||||
const OSCILLOSCOPE_SCHEMA = {
|
const OSCILLOSCOPE_SCHEMA = {
|
||||||
line: 'line',
|
line: 'line',
|
||||||
fill: 'fill',
|
fill: 'fill',
|
||||||
|
guides: 'guides',
|
||||||
} as const satisfies SectionSchema<ThemeOscilloscopeTokens>
|
} as const satisfies SectionSchema<ThemeOscilloscopeTokens>
|
||||||
|
|
||||||
const VECTORSCOPE_SCHEMA = {
|
const VECTORSCOPE_SCHEMA = {
|
||||||
@@ -107,6 +115,7 @@ const VECTORSCOPE_SCHEMA = {
|
|||||||
band_low: 'bandLow',
|
band_low: 'bandLow',
|
||||||
band_mid: 'bandMid',
|
band_mid: 'bandMid',
|
||||||
band_high: 'bandHigh',
|
band_high: 'bandHigh',
|
||||||
|
guides: 'guides',
|
||||||
} as const satisfies SectionSchema<ThemeVectorscopeTokens>
|
} as const satisfies SectionSchema<ThemeVectorscopeTokens>
|
||||||
|
|
||||||
const SPECTROGRAM_SCHEMA = {
|
const SPECTROGRAM_SCHEMA = {
|
||||||
@@ -121,12 +130,14 @@ const VUMETER_SCHEMA = {
|
|||||||
track: 'track',
|
track: 'track',
|
||||||
peak: 'peak',
|
peak: 'peak',
|
||||||
clip: 'clip',
|
clip: 'clip',
|
||||||
|
scale: 'scale',
|
||||||
} as const satisfies SectionSchema<ThemeVUMeterTokens>
|
} as const satisfies SectionSchema<ThemeVUMeterTokens>
|
||||||
|
|
||||||
const LUFSMETER_SCHEMA = {
|
const LUFSMETER_SCHEMA = {
|
||||||
level: 'level',
|
level: 'level',
|
||||||
track: 'track',
|
track: 'track',
|
||||||
target: 'target',
|
target: 'target',
|
||||||
|
scale: 'scale',
|
||||||
} as const satisfies SectionSchema<ThemeLUFSMeterTokens>
|
} as const satisfies SectionSchema<ThemeLUFSMeterTokens>
|
||||||
|
|
||||||
const WAVEFORM_SCHEMA = {
|
const WAVEFORM_SCHEMA = {
|
||||||
@@ -134,6 +145,7 @@ const WAVEFORM_SCHEMA = {
|
|||||||
band_low: 'bandLow',
|
band_low: 'bandLow',
|
||||||
band_mid: 'bandMid',
|
band_mid: 'bandMid',
|
||||||
band_high: 'bandHigh',
|
band_high: 'bandHigh',
|
||||||
|
guides: 'guides',
|
||||||
} as const satisfies SectionSchema<ThemeWaveformTokens>
|
} as const satisfies SectionSchema<ThemeWaveformTokens>
|
||||||
|
|
||||||
const ASTRA_SCHEMA = {
|
const ASTRA_SCHEMA = {
|
||||||
@@ -414,6 +426,8 @@ function createEmptyTheme(): PrismTheme {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PASSTHROUGH_KEYS: ReadonlySet<string> = new Set(['flatControls'])
|
||||||
|
|
||||||
function normalizeSectionTokens<T extends SectionTokenMap>(
|
function normalizeSectionTokens<T extends SectionTokenMap>(
|
||||||
raw: unknown,
|
raw: unknown,
|
||||||
schema: SectionSchema<T>,
|
schema: SectionSchema<T>,
|
||||||
@@ -433,6 +447,11 @@ function normalizeSectionTokens<T extends SectionTokenMap>(
|
|||||||
})?.[1] as keyof T | undefined
|
})?.[1] as keyof T | undefined
|
||||||
if (!key) continue
|
if (!key) continue
|
||||||
|
|
||||||
|
if (PASSTHROUGH_KEYS.has(key as string)) {
|
||||||
|
next[key] = rawValue as T[typeof key]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const parsedColor = parseCssColor(rawValue) ?? parseThemeChannelColor(rawValue)
|
const parsedColor = parseCssColor(rawValue) ?? parseThemeChannelColor(rawValue)
|
||||||
if (!parsedColor) continue
|
if (!parsedColor) continue
|
||||||
next[key] = toCssColor(quantizeThemeColor(parsedColor)) as T[typeof key]
|
next[key] = toCssColor(quantizeThemeColor(parsedColor)) as T[typeof key]
|
||||||
@@ -761,7 +780,11 @@ function serializeSection<T extends SectionTokenMap>(
|
|||||||
for (const [serializedKey, propertyKey] of Object.entries(schema)) {
|
for (const [serializedKey, propertyKey] of Object.entries(schema)) {
|
||||||
const value = tokens[propertyKey as keyof T]
|
const value = tokens[propertyKey as keyof T]
|
||||||
if (!value) continue
|
if (!value) continue
|
||||||
lines.push(`${serializedKey} = ${toThemeChannels(value)}`)
|
if (PASSTHROUGH_KEYS.has(propertyKey)) {
|
||||||
|
lines.push(`${serializedKey} = ${value}`)
|
||||||
|
} else {
|
||||||
|
lines.push(`${serializedKey} = ${toThemeChannels(value)}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
@@ -805,10 +828,29 @@ export function createTemplateThemeFile(): string {
|
|||||||
# Authoring rules:
|
# Authoring rules:
|
||||||
# - Colors use R, G, B or R, G, B, A (0-255)
|
# - Colors use R, G, B or R, G, B, A (0-255)
|
||||||
# - CSS colors like #hex, rgb(), and rgba() also work
|
# - CSS colors like #hex, rgb(), and rgba() also work
|
||||||
# - [App] controls the overall chrome and text
|
#
|
||||||
# - [Controls] covers buttons, inputs, menus, and sliders
|
# ── UI ──
|
||||||
# - [Scopes] covers the shared analyzer background and guide system
|
# [App] Overall window chrome, background, and text
|
||||||
# - Scope sections should only override visuals unique to that module
|
# toolbar_bg, settings_bg_top, settings_bg_bottom, bottom_bar_bg
|
||||||
|
# can be set to override the default derived values
|
||||||
|
# [Controls] Buttons, inputs, menus, and sliders
|
||||||
|
# Set flat_controls = true to disable glass highlights/gradients
|
||||||
|
#
|
||||||
|
# ── Scopes ──
|
||||||
|
# [Scopes] Shared background and guide color for all scopes
|
||||||
|
# background defaults to [App] background if not set
|
||||||
|
# Set it explicitly here to decouple scope bg from window bg
|
||||||
|
#
|
||||||
|
# Per-scope sections override colors unique to that module.
|
||||||
|
# Each scope can set its own guides to override the shared [Scopes] guides.
|
||||||
|
#
|
||||||
|
# [Spectrum] line, fill, heat gradient (heat_low/mid/high/base), guides
|
||||||
|
# [Oscilloscope] line, fill, guides
|
||||||
|
# [Vectorscope] trace, band_low/mid/high (RGB overlay colors), guides
|
||||||
|
# [Spectrogram] mono, heat gradient
|
||||||
|
# [VUMeter] level, track, peak, clip, scale
|
||||||
|
# [LUFSMeter] level, track, target, scale
|
||||||
|
# [Waveform] line, band_low/mid/high, guides
|
||||||
#
|
#
|
||||||
${serializeThemeFile(template)}`
|
${serializeThemeFile(template)}`
|
||||||
}
|
}
|
||||||
@@ -824,6 +866,10 @@ interface ResolvedAppTokens {
|
|||||||
border: string
|
border: string
|
||||||
text: string
|
text: string
|
||||||
textMuted: string
|
textMuted: string
|
||||||
|
toolbarBg: string | null
|
||||||
|
settingsBgTop: string | null
|
||||||
|
settingsBgBottom: string | null
|
||||||
|
bottomBarBg: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ResolvedControlsTokens {
|
interface ResolvedControlsTokens {
|
||||||
@@ -838,6 +884,7 @@ interface ResolvedControlsTokens {
|
|||||||
menuSurface: string
|
menuSurface: string
|
||||||
menuBorder: string
|
menuBorder: string
|
||||||
slider: string
|
slider: string
|
||||||
|
flatControls: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ResolvedScopesTokens {
|
interface ResolvedScopesTokens {
|
||||||
@@ -871,6 +918,10 @@ function resolveAppTokens(tokens: ThemeAppTokens): ResolvedAppTokens {
|
|||||||
border,
|
border,
|
||||||
text,
|
text,
|
||||||
textMuted,
|
textMuted,
|
||||||
|
toolbarBg: tokens.toolbarBg ?? null,
|
||||||
|
settingsBgTop: tokens.settingsBgTop ?? null,
|
||||||
|
settingsBgBottom: tokens.settingsBgBottom ?? null,
|
||||||
|
bottomBarBg: tokens.bottomBarBg ?? null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -888,6 +939,7 @@ function resolveControlsTokens(tokens: ThemeControlsTokens, app: ResolvedAppToke
|
|||||||
menuSurface: tokens.menuSurface ?? app.surface,
|
menuSurface: tokens.menuSurface ?? app.surface,
|
||||||
menuBorder: tokens.menuBorder ?? 'rgba(255, 255, 255, 0.1)',
|
menuBorder: tokens.menuBorder ?? 'rgba(255, 255, 255, 0.1)',
|
||||||
slider: tokens.slider ?? withAlpha(app.accent, 0.82),
|
slider: tokens.slider ?? withAlpha(app.accent, 0.82),
|
||||||
|
flatControls: tokens.flatControls === 'true',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,6 +962,12 @@ function resolveInterfaceTheme(
|
|||||||
controls: ResolvedControlsTokens,
|
controls: ResolvedControlsTokens,
|
||||||
scopes: ResolvedScopesTokens,
|
scopes: ResolvedScopesTokens,
|
||||||
): ResolvedInterfaceTheme {
|
): ResolvedInterfaceTheme {
|
||||||
|
const bgParsed = parseCssColor(app.background)
|
||||||
|
const colorScheme: 'light' | 'dark' = bgParsed && getPerceivedBrightness(bgParsed) >= 156 ? 'light' : 'dark'
|
||||||
|
|
||||||
|
const glassHighlight = controls.flatControls ? 'transparent' : withAlpha(app.text, 0.05)
|
||||||
|
const glassBg = controls.flatControls ? 'transparent' : withAlpha(app.surface, 0.18)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
primary: app.accent,
|
primary: app.accent,
|
||||||
secondary: app.surfaceAlt,
|
secondary: app.surfaceAlt,
|
||||||
@@ -920,6 +978,7 @@ function resolveInterfaceTheme(
|
|||||||
accentHover: lighten(app.accent, 0.2),
|
accentHover: lighten(app.accent, 0.2),
|
||||||
accentGlow: withAlpha(app.accent, 0.3),
|
accentGlow: withAlpha(app.accent, 0.3),
|
||||||
accentRgb: colorToRgbChannels(app.accent),
|
accentRgb: colorToRgbChannels(app.accent),
|
||||||
|
colorScheme,
|
||||||
bgPrimary: app.background,
|
bgPrimary: app.background,
|
||||||
bgSecondary: darken(app.background, 0.04),
|
bgSecondary: darken(app.background, 0.04),
|
||||||
bgTertiary: darken(app.background, 0.08),
|
bgTertiary: darken(app.background, 0.08),
|
||||||
@@ -927,17 +986,18 @@ function resolveInterfaceTheme(
|
|||||||
panelSurfaceSoft: app.surfaceAlt,
|
panelSurfaceSoft: app.surfaceAlt,
|
||||||
panelOutline: app.border,
|
panelOutline: app.border,
|
||||||
panelOutlineStrong: withAlpha(app.border, 0.9),
|
panelOutlineStrong: withAlpha(app.border, 0.9),
|
||||||
glassBg: withAlpha(app.surface, 0.18),
|
glassBg,
|
||||||
glassBorder: withAlpha(app.border, 0.85),
|
glassBorder: withAlpha(app.border, 0.85),
|
||||||
glassHighlight: withAlpha(app.text, 0.05),
|
glassHighlight,
|
||||||
|
glassHighlightStrong: controls.flatControls ? 'transparent' : withAlpha(app.text, 0.14),
|
||||||
textPrimary: app.text,
|
textPrimary: app.text,
|
||||||
textSecondary: blendText(app.text, app.textMuted, 0.45),
|
textSecondary: blendText(app.text, app.textMuted, 0.45),
|
||||||
textTertiary: blendText(app.text, app.textMuted, 0.7),
|
textTertiary: blendText(app.text, app.textMuted, 0.7),
|
||||||
textMuted: app.textMuted,
|
textMuted: app.textMuted,
|
||||||
toolbarBg: withAlpha(app.surfaceAlt, 0.78),
|
toolbarBg: app.toolbarBg ?? withAlpha(app.surfaceAlt, 0.78),
|
||||||
settingsBgTop: app.surface,
|
settingsBgTop: app.settingsBgTop ?? app.surface,
|
||||||
settingsBgBottom: app.surfaceAlt,
|
settingsBgBottom: app.settingsBgBottom ?? app.surfaceAlt,
|
||||||
bottomBarBg: withAlpha(app.surfaceAlt, 0.98),
|
bottomBarBg: app.bottomBarBg ?? withAlpha(app.surfaceAlt, 0.98),
|
||||||
menuBg: controls.menuSurface,
|
menuBg: controls.menuSurface,
|
||||||
menuBorder: controls.menuBorder,
|
menuBorder: controls.menuBorder,
|
||||||
controlBg: controls.surface,
|
controlBg: controls.surface,
|
||||||
@@ -977,12 +1037,13 @@ function resolveSpectrumTheme(
|
|||||||
const line = section.line ?? app.accent
|
const line = section.line ?? app.accent
|
||||||
const sideLine = section.sideLine ?? withAlpha(line, 0.5)
|
const sideLine = section.sideLine ?? withAlpha(line, 0.5)
|
||||||
const fill = section.fill ?? withAlpha(line, 0.34)
|
const fill = section.fill ?? withAlpha(line, 0.34)
|
||||||
|
const guides = section.guides ?? scopes.guides
|
||||||
return {
|
return {
|
||||||
line,
|
line,
|
||||||
sideLine,
|
sideLine,
|
||||||
guides: scopes.guides,
|
guides,
|
||||||
guidesSecondary: scopes.guidesSecondary,
|
guidesSecondary: multiplyAlpha(guides, 0.5),
|
||||||
labels: scopes.labels,
|
labels: section.guides ? guides : scopes.labels,
|
||||||
background: scopes.background,
|
background: scopes.background,
|
||||||
fill,
|
fill,
|
||||||
fillGradient: [
|
fillGradient: [
|
||||||
@@ -995,6 +1056,7 @@ function resolveSpectrumTheme(
|
|||||||
section.heatMid ?? DEFAULT_HEAT_MID,
|
section.heatMid ?? DEFAULT_HEAT_MID,
|
||||||
section.heatHigh ?? DEFAULT_HEAT_HIGH,
|
section.heatHigh ?? DEFAULT_HEAT_HIGH,
|
||||||
],
|
],
|
||||||
|
heatBase: section.heatBase ?? scopes.background,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1003,10 +1065,11 @@ function resolveOscilloscopeTheme(
|
|||||||
app: ResolvedAppTokens,
|
app: ResolvedAppTokens,
|
||||||
scopes: ResolvedScopesTokens,
|
scopes: ResolvedScopesTokens,
|
||||||
): ResolvedOscilloscopeTheme {
|
): ResolvedOscilloscopeTheme {
|
||||||
|
const guides = theme.oscilloscope.guides ?? scopes.guides
|
||||||
return {
|
return {
|
||||||
line: theme.oscilloscope.line ?? app.accent,
|
line: theme.oscilloscope.line ?? app.accent,
|
||||||
guides: scopes.guides,
|
guides,
|
||||||
guidesSecondary: scopes.guidesSecondary,
|
guidesSecondary: multiplyAlpha(guides, 0.5),
|
||||||
background: scopes.background,
|
background: scopes.background,
|
||||||
fill: theme.oscilloscope.fill ?? 'rgba(245, 248, 252, 0.18)',
|
fill: theme.oscilloscope.fill ?? 'rgba(245, 248, 252, 0.18)',
|
||||||
}
|
}
|
||||||
@@ -1017,11 +1080,12 @@ function resolveVectorscopeTheme(
|
|||||||
app: ResolvedAppTokens,
|
app: ResolvedAppTokens,
|
||||||
scopes: ResolvedScopesTokens,
|
scopes: ResolvedScopesTokens,
|
||||||
): ResolvedVectorscopeTheme {
|
): ResolvedVectorscopeTheme {
|
||||||
|
const guides = theme.vectorscope.guides ?? scopes.guides
|
||||||
return {
|
return {
|
||||||
trace: theme.vectorscope.trace ?? app.accent,
|
trace: theme.vectorscope.trace ?? app.accent,
|
||||||
guides: scopes.guides,
|
guides,
|
||||||
guidesSecondary: scopes.guidesSecondary,
|
guidesSecondary: multiplyAlpha(guides, 0.5),
|
||||||
labels: scopes.labels,
|
labels: theme.vectorscope.guides ? guides : scopes.labels,
|
||||||
background: scopes.background,
|
background: scopes.background,
|
||||||
bandLow: theme.vectorscope.bandLow ?? DEFAULT_BAND_LOW,
|
bandLow: theme.vectorscope.bandLow ?? DEFAULT_BAND_LOW,
|
||||||
bandMid: theme.vectorscope.bandMid ?? DEFAULT_BAND_MID,
|
bandMid: theme.vectorscope.bandMid ?? DEFAULT_BAND_MID,
|
||||||
@@ -1056,7 +1120,7 @@ function resolveVUMeterTheme(
|
|||||||
track: theme.vumeter.track ?? withAlpha(level, 0.08),
|
track: theme.vumeter.track ?? withAlpha(level, 0.08),
|
||||||
peak: theme.vumeter.peak ?? 'rgb(255, 127, 0)',
|
peak: theme.vumeter.peak ?? 'rgb(255, 127, 0)',
|
||||||
clip: theme.vumeter.clip ?? 'rgba(255, 120, 80, 0.9)',
|
clip: theme.vumeter.clip ?? 'rgba(255, 120, 80, 0.9)',
|
||||||
scale: scopes.guides,
|
scale: theme.vumeter.scale ?? scopes.guides,
|
||||||
labels: blendText(app.text, app.textMuted, 0.35),
|
labels: blendText(app.text, app.textMuted, 0.35),
|
||||||
background: scopes.background,
|
background: scopes.background,
|
||||||
}
|
}
|
||||||
@@ -1072,7 +1136,7 @@ function resolveLUFSMeterTheme(
|
|||||||
level,
|
level,
|
||||||
track: theme.lufsmeter.track ?? withAlpha(level, 0.08),
|
track: theme.lufsmeter.track ?? withAlpha(level, 0.08),
|
||||||
target: theme.lufsmeter.target ?? withAlpha(level, 0.25),
|
target: theme.lufsmeter.target ?? withAlpha(level, 0.25),
|
||||||
scale: scopes.guides,
|
scale: theme.lufsmeter.scale ?? scopes.guides,
|
||||||
labels: blendText(app.text, app.textMuted, 0.2),
|
labels: blendText(app.text, app.textMuted, 0.2),
|
||||||
background: scopes.background,
|
background: scopes.background,
|
||||||
}
|
}
|
||||||
@@ -1083,10 +1147,11 @@ function resolveWaveformTheme(
|
|||||||
app: ResolvedAppTokens,
|
app: ResolvedAppTokens,
|
||||||
scopes: ResolvedScopesTokens,
|
scopes: ResolvedScopesTokens,
|
||||||
): ResolvedWaveformTheme {
|
): ResolvedWaveformTheme {
|
||||||
|
const guides = theme.waveform.guides ?? scopes.guides
|
||||||
return {
|
return {
|
||||||
line: theme.waveform.line ?? app.accent,
|
line: theme.waveform.line ?? app.accent,
|
||||||
guides: scopes.guides,
|
guides,
|
||||||
guidesSecondary: scopes.guidesSecondary,
|
guidesSecondary: multiplyAlpha(guides, 0.5),
|
||||||
background: scopes.background,
|
background: scopes.background,
|
||||||
bandLow: theme.waveform.bandLow ?? DEFAULT_BAND_LOW,
|
bandLow: theme.waveform.bandLow ?? DEFAULT_BAND_LOW,
|
||||||
bandMid: theme.waveform.bandMid ?? DEFAULT_BAND_MID,
|
bandMid: theme.waveform.bandMid ?? DEFAULT_BAND_MID,
|
||||||
@@ -1216,6 +1281,7 @@ export function themeToCssVariables(theme: Pick<PrismResolvedTheme, 'interface'>
|
|||||||
'--glass-bg': ui.glassBg,
|
'--glass-bg': ui.glassBg,
|
||||||
'--glass-border': ui.glassBorder,
|
'--glass-border': ui.glassBorder,
|
||||||
'--glass-highlight': ui.glassHighlight,
|
'--glass-highlight': ui.glassHighlight,
|
||||||
|
'--glass-highlight-strong': ui.glassHighlightStrong,
|
||||||
'--text-primary': ui.textPrimary,
|
'--text-primary': ui.textPrimary,
|
||||||
'--text-secondary': ui.textSecondary,
|
'--text-secondary': ui.textSecondary,
|
||||||
'--text-tertiary': ui.textTertiary,
|
'--text-tertiary': ui.textTertiary,
|
||||||
@@ -1266,6 +1332,7 @@ export function applyResolvedThemeToDocument(
|
|||||||
for (const [name, value] of Object.entries(variables)) {
|
for (const [name, value] of Object.entries(variables)) {
|
||||||
root.setProperty(name, value)
|
root.setProperty(name, value)
|
||||||
}
|
}
|
||||||
|
root.setProperty('color-scheme', theme.interface.colorScheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDefaultThemeIdForLocalState(): string {
|
export function getDefaultThemeIdForLocalState(): string {
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export interface ThemeAppTokens {
|
|||||||
border?: string
|
border?: string
|
||||||
text?: string
|
text?: string
|
||||||
textMuted?: string
|
textMuted?: string
|
||||||
|
toolbarBg?: string
|
||||||
|
settingsBgTop?: string
|
||||||
|
settingsBgBottom?: string
|
||||||
|
bottomBarBg?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeControlsTokens {
|
export interface ThemeControlsTokens {
|
||||||
@@ -39,6 +43,7 @@ export interface ThemeControlsTokens {
|
|||||||
menuSurface?: string
|
menuSurface?: string
|
||||||
menuBorder?: string
|
menuBorder?: string
|
||||||
slider?: string
|
slider?: string
|
||||||
|
flatControls?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeScopesTokens {
|
export interface ThemeScopesTokens {
|
||||||
@@ -57,11 +62,14 @@ export interface ThemeSpectrumTokens {
|
|||||||
heatLow?: string
|
heatLow?: string
|
||||||
heatMid?: string
|
heatMid?: string
|
||||||
heatHigh?: string
|
heatHigh?: string
|
||||||
|
heatBase?: string
|
||||||
|
guides?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeOscilloscopeTokens {
|
export interface ThemeOscilloscopeTokens {
|
||||||
line?: string
|
line?: string
|
||||||
fill?: string
|
fill?: string
|
||||||
|
guides?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeVectorscopeTokens {
|
export interface ThemeVectorscopeTokens {
|
||||||
@@ -69,6 +77,7 @@ export interface ThemeVectorscopeTokens {
|
|||||||
bandLow?: string
|
bandLow?: string
|
||||||
bandMid?: string
|
bandMid?: string
|
||||||
bandHigh?: string
|
bandHigh?: string
|
||||||
|
guides?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeSpectrogramTokens {
|
export interface ThemeSpectrogramTokens {
|
||||||
@@ -83,12 +92,14 @@ export interface ThemeVUMeterTokens {
|
|||||||
track?: string
|
track?: string
|
||||||
peak?: string
|
peak?: string
|
||||||
clip?: string
|
clip?: string
|
||||||
|
scale?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeLUFSMeterTokens {
|
export interface ThemeLUFSMeterTokens {
|
||||||
level?: string
|
level?: string
|
||||||
track?: string
|
track?: string
|
||||||
target?: string
|
target?: string
|
||||||
|
scale?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeWaveformTokens {
|
export interface ThemeWaveformTokens {
|
||||||
@@ -96,6 +107,7 @@ export interface ThemeWaveformTokens {
|
|||||||
bandLow?: string
|
bandLow?: string
|
||||||
bandMid?: string
|
bandMid?: string
|
||||||
bandHigh?: string
|
bandHigh?: string
|
||||||
|
guides?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeAstraTokens {
|
export interface ThemeAstraTokens {
|
||||||
@@ -176,9 +188,11 @@ export interface ResolvedInterfaceTheme {
|
|||||||
panelSurfaceSoft: string
|
panelSurfaceSoft: string
|
||||||
panelOutline: string
|
panelOutline: string
|
||||||
panelOutlineStrong: string
|
panelOutlineStrong: string
|
||||||
|
colorScheme: 'light' | 'dark'
|
||||||
glassBg: string
|
glassBg: string
|
||||||
glassBorder: string
|
glassBorder: string
|
||||||
glassHighlight: string
|
glassHighlight: string
|
||||||
|
glassHighlightStrong: string
|
||||||
textPrimary: string
|
textPrimary: string
|
||||||
textSecondary: string
|
textSecondary: string
|
||||||
textTertiary: string
|
textTertiary: string
|
||||||
@@ -226,6 +240,7 @@ export interface ResolvedSpectrumTheme {
|
|||||||
fill: string
|
fill: string
|
||||||
fillGradient: [string, string, string]
|
fillGradient: [string, string, string]
|
||||||
heatColors: [string, string, string]
|
heatColors: [string, string, string]
|
||||||
|
heatBase: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResolvedOscilloscopeTheme {
|
export interface ResolvedOscilloscopeTheme {
|
||||||
|
|||||||
Reference in New Issue
Block a user