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:
1 parent
5f2e6a5cda
commit
3d2bc0f4d6
13 files changed
+465
-11
No files matched your search
@@ -0,0 +1,61 @@
|
||||
use ely_gpui_component::{
|
||||
buttons::{Button, ButtonVariant},
|
||||
settings::{ThemeDraft, ThemeEditor},
|
||||
theme::{ActiveTheme, Density, Mode, Theme},
|
||||
};
|
||||
use gpui::{App, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
|
||||
use crate::ui::section;
|
||||
|
||||
/// Applies a draft to the app's theme: its measures and switches, and its colors as the shown mode's own.
|
||||
fn apply(draft: &ThemeDraft, cx: &mut App) {
|
||||
let now = ThemeDraft::of(cx.theme());
|
||||
Theme::update(cx, |theme| {
|
||||
theme.density = draft.density;
|
||||
theme.radius_scale = draft.radius_scale;
|
||||
theme.font_scale = draft.font_scale;
|
||||
theme.reduced_motion = draft.reduced_motion;
|
||||
});
|
||||
if draft.high_contrast != now.high_contrast {
|
||||
Theme::set_high_contrast(draft.high_contrast, cx);
|
||||
}
|
||||
if draft.colors != now.colors {
|
||||
Theme::set_palette(cx.theme().mode(), Some(draft.colors.clone()), cx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ely's own theme again, in both modes.
|
||||
fn restore(cx: &mut App) {
|
||||
Theme::update(cx, |theme| {
|
||||
theme.density = Density::Standard;
|
||||
theme.radius_scale = 1.0;
|
||||
theme.font_scale = 1.0;
|
||||
});
|
||||
Theme::set_palette(Mode::Light, None, cx);
|
||||
Theme::set_palette(Mode::Dark, None, cx);
|
||||
Theme::set_high_contrast(false, cx);
|
||||
}
|
||||
|
||||
pub fn editor(_: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let draft = ThemeDraft::of(cx.theme());
|
||||
section(
|
||||
"ThemeEditor · DensityProvider · RadiusProvider · FontProvider · HighContrastMode · ReducedMotionProvider",
|
||||
"The theme laid open: every change here applies to the whole gallery at once, the colors as the shown mode's own. The theme switch above is settings::ThemeSelector.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(520.))
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_4()
|
||||
.child(ThemeEditor::new("theme-editor", draft).on_change(|draft, _, cx| apply(draft, cx)))
|
||||
.child(
|
||||
div().flex().child(
|
||||
Button::new("theme-restore", "Back to Ely's theme")
|
||||
.variant(ButtonVariant::Secondary)
|
||||
.on_click(|_, _, cx| restore(cx)),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -9,6 +9,8 @@ use gpui::{
|
||||
IntoElement, ParentElement, SharedString, Styled, StyledText, Window, div, px,
|
||||
};
|
||||
|
||||
mod editing;
|
||||
|
||||
use super::Page;
|
||||
use crate::ui::{section, specimen, specimens};
|
||||
|
||||
@@ -21,7 +23,7 @@ pub const PAGE: Page = Page {
|
||||
script: &[],
|
||||
};
|
||||
|
||||
fn render(_: &mut Window, cx: &mut App) -> AnyElement {
|
||||
fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
let colors = cx.theme().colors.clone();
|
||||
let surfaces = [
|
||||
("bg", colors.bg),
|
||||
@@ -144,6 +146,7 @@ fn render(_: &mut Window, cx: &mut App) -> AnyElement {
|
||||
))
|
||||
.child(track("spring", "spring · damping 0.75", motion::spring, cx)),
|
||||
)
|
||||
.child(editing::editor(window, cx))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user