Theme · Editing: a theme laid open, and an owner's palette per mode

settings::ThemeEditor lays a theme open: density, corners, text size,
high contrast and reduced motion, then twelve colors of the mode shown,
each a swatch that opens a picker beside its hex; each change hands the
owner a whole draft. Theme::set_palette takes an owner's palette per
mode, the colors fading to it when the mode shows; Theme::palette names
the palette the shown mode fades to; Palette::token_mut and
Syntax::token_mut reach a color by its field's name. The gallery's
theme page applies the editor to the whole gallery live, with a way
back to Ely's theme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-09-27 16:31:33 -04:00
1 parent 5f2e6a5cda
commit 3d2bc0f4d6
13 files changed
+465 -11

No files matched your search

+27
View File
@@ -12,6 +12,9 @@ mod palette;
mod project;
mod tokens;
#[cfg(all(test, feature = "test-support"))]
mod tests;
use std::time::{Duration, Instant};
use gpui::{App, Global, SharedString, WindowAppearance};
@@ -56,6 +59,7 @@ pub struct Theme {
mode: Mode,
high_contrast: bool,
transition: u64,
custom: [Option<Palette>; 2],
pub colors: Palette,
pub density: Density,
pub radius_scale: f32,
@@ -83,6 +87,7 @@ impl Theme {
mode: Mode::Light,
high_contrast: false,
transition: 0,
custom: [None, None],
colors: Palette::light(false),
density: Density::Standard,
radius_scale: 1.0,
@@ -118,6 +123,25 @@ impl Theme {
Self::fade_to_target(cx);
}
/// The owner's palette for `mode`, as an edited or imported theme gives, or none to bring Ely's back. The colors fade to it when `mode` shows. High contrast strengthens Ely's own palettes alone.
pub fn set_palette(mode: Mode, palette: Option<Palette>, cx: &mut App) {
log::info!(
"theme: {mode:?} palette -> {}",
if palette.is_some() {
"the owner's"
} else {
"Ely's"
}
);
cx.global_mut::<Theme>().custom[mode as usize] = palette;
Self::fade_to_target(cx);
}
/// The palette the shown mode fades to: the owner's, or Ely's.
pub fn palette(&self) -> Palette {
self.target()
}
/// Edits non-color tokens, then repaints.
pub fn update(cx: &mut App, edit: impl FnOnce(&mut Theme)) {
edit(cx.global_mut::<Theme>());
@@ -125,6 +149,9 @@ impl Theme {
}
fn target(&self) -> Palette {
if let Some(palette) = &self.custom[self.mode as usize] {
return palette.clone();
}
match self.mode {
Mode::Light => Palette::light(self.high_contrast),
Mode::Dark => Palette::dark(self.high_contrast),