add accent color and surface preferences to settings
This commit is contained in:
@@ -318,6 +318,34 @@ impl AppSettings {
|
|||||||
self.apply_theme(Some(window), cx);
|
self.apply_theme(Some(window), cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the accent color override and re-resolve the theme
|
||||||
|
pub fn apply_accent(
|
||||||
|
&mut self,
|
||||||
|
selection: AccentSelection,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.inner.update(cx, |this, cx| {
|
||||||
|
this.accent_selection = selection;
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
self.apply_theme(Some(window), cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the surface treatment preference
|
||||||
|
pub fn apply_surface(
|
||||||
|
&mut self,
|
||||||
|
preference: SurfacePreference,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
self.inner.update(cx, |this, cx| {
|
||||||
|
this.surface_preference = preference;
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
self.apply_theme(Some(window), cx);
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply theme
|
/// Apply theme
|
||||||
pub fn apply_theme(&mut self, window: Option<&mut Window>, cx: &mut Context<Self>) {
|
pub fn apply_theme(&mut self, window: Option<&mut Window>, cx: &mut Context<Self>) {
|
||||||
let (selection, accent, surface, appearance) = {
|
let (selection, accent, surface, appearance) = {
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ pub const TABBAR_HEIGHT: Pixels = px(36.0);
|
|||||||
pub const SIDEBAR_WIDTH: Pixels = px(240.);
|
pub const SIDEBAR_WIDTH: Pixels = px(240.);
|
||||||
|
|
||||||
pub fn init(cx: &mut App) {
|
pub fn init(cx: &mut App) {
|
||||||
|
for issue in ThemeRegistry::active().validate() {
|
||||||
|
log::warn!("theme {}: {}", issue.variant_id, issue.message);
|
||||||
|
}
|
||||||
|
|
||||||
Theme::sync_system_appearance(None, cx);
|
Theme::sync_system_appearance(None, cx);
|
||||||
Theme::sync_scrollbar_appearance(cx);
|
Theme::sync_scrollbar_appearance(cx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use gpui::{
|
|||||||
Window, div, px,
|
Window, div, px,
|
||||||
};
|
};
|
||||||
use settings::AppSettings;
|
use settings::AppSettings;
|
||||||
use theme::{ActiveTheme, Appearance, Theme};
|
use theme::{AccentPreset, AccentSelection, ActiveTheme, Appearance, SurfacePreference, Theme};
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
use ui::group_box::{GroupBox, GroupBoxVariants};
|
use ui::group_box::{GroupBox, GroupBoxVariants};
|
||||||
use ui::input::{Input, InputState};
|
use ui::input::{Input, InputState};
|
||||||
@@ -59,6 +59,8 @@ impl Render for Preferences {
|
|||||||
const SCREENING: &str = "Show an screening dialog to verify the unknown sender.";
|
const SCREENING: &str = "Show an screening dialog to verify the unknown sender.";
|
||||||
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
|
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
|
||||||
const MODE: &str = "Use the selected light or dark theme, or to follow the OS.";
|
const MODE: &str = "Use the selected light or dark theme, or to follow the OS.";
|
||||||
|
const ACCENT: &str = "Override the accent color of the selected theme.";
|
||||||
|
const SURFACE: &str = "Preferred surface treatment. Frosted rendering is not applied yet.";
|
||||||
const NIP4E: &str = "Use a dedicated key to encrypt and decrypt messages.";
|
const NIP4E: &str = "Use a dedicated key to encrypt and decrypt messages.";
|
||||||
const RESET: &str = "Reset the theme to the default one.";
|
const RESET: &str = "Reset the theme to the default one.";
|
||||||
|
|
||||||
@@ -66,6 +68,8 @@ impl Render for Preferences {
|
|||||||
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
||||||
let nip4e = AppSettings::get_nip4e(cx);
|
let nip4e = AppSettings::get_nip4e(cx);
|
||||||
let appearance = AppSettings::get_appearance(cx);
|
let appearance = AppSettings::get_appearance(cx);
|
||||||
|
let accent_selection = AppSettings::get_accent_selection(cx);
|
||||||
|
let surface_preference = AppSettings::get_surface_preference(cx);
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_4()
|
.gap_4()
|
||||||
@@ -135,6 +139,127 @@ impl Render for Preferences {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_3()
|
||||||
|
.justify_between()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.child(div().text_sm().child(SharedString::from("Accent")))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(SharedString::from(ACCENT)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("accent")
|
||||||
|
.label(accent_selection.label())
|
||||||
|
.ghost_alt()
|
||||||
|
.small()
|
||||||
|
.dropdown_menu(|menu, _window, _cx| {
|
||||||
|
let menu =
|
||||||
|
menu.item(
|
||||||
|
PopupMenuItem::new(
|
||||||
|
AccentSelection::ThemeDefault.label(),
|
||||||
|
)
|
||||||
|
.on_click(|_, window, cx| {
|
||||||
|
AppSettings::global(cx).update(cx, |s, cx| {
|
||||||
|
s.apply_accent(
|
||||||
|
AccentSelection::ThemeDefault,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut menu = menu;
|
||||||
|
for preset in AccentPreset::ALL {
|
||||||
|
menu = menu.item(
|
||||||
|
PopupMenuItem::new(preset.label()).on_click({
|
||||||
|
move |_, window, cx| {
|
||||||
|
AppSettings::global(cx).update(
|
||||||
|
cx,
|
||||||
|
|s, cx| {
|
||||||
|
s.apply_accent(
|
||||||
|
AccentSelection::Preset(preset),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
menu
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_3()
|
||||||
|
.justify_between()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.child(div().text_sm().child(SharedString::from("Surface")))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(SharedString::from(SURFACE)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("surface")
|
||||||
|
.label(match surface_preference {
|
||||||
|
SurfacePreference::ThemeDefault => "Theme default",
|
||||||
|
SurfacePreference::Frosted => "Frosted",
|
||||||
|
SurfacePreference::Opaque => "Opaque",
|
||||||
|
})
|
||||||
|
.ghost_alt()
|
||||||
|
.small()
|
||||||
|
.dropdown_menu(|menu, _window, _cx| {
|
||||||
|
menu.item(PopupMenuItem::new("Theme default").on_click(
|
||||||
|
|_, window, cx| {
|
||||||
|
AppSettings::global(cx).update(cx, |s, cx| {
|
||||||
|
s.apply_surface(
|
||||||
|
SurfacePreference::ThemeDefault,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.item(PopupMenuItem::new("Frosted").on_click(
|
||||||
|
|_, window, cx| {
|
||||||
|
AppSettings::global(cx).update(cx, |s, cx| {
|
||||||
|
s.apply_surface(
|
||||||
|
SurfacePreference::Frosted,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.item(
|
||||||
|
PopupMenuItem::new("Opaque").on_click(
|
||||||
|
|_, window, cx| {
|
||||||
|
AppSettings::global(cx).update(cx, |s, cx| {
|
||||||
|
s.apply_surface(
|
||||||
|
SurfacePreference::Opaque,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_3()
|
.gap_3()
|
||||||
|
|||||||
@@ -465,17 +465,42 @@ impl Workspace {
|
|||||||
|
|
||||||
fn theme_selector(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
fn theme_selector(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
let appearance = cx.theme().appearance;
|
let appearance = cx.theme().appearance;
|
||||||
let variants: Vec<ThemeVariant> = ThemeRegistry::active()
|
let registry = ThemeRegistry::active();
|
||||||
.variants_for(appearance)
|
let groups: Vec<(String, Vec<ThemeVariant>)> = registry
|
||||||
|
.families
|
||||||
|
.iter()
|
||||||
|
.filter_map(|family| {
|
||||||
|
let variants: Vec<ThemeVariant> = family
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.filter(|variant| variant.appearance == appearance)
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
if variants.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((family.name.clone(), variants))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
window.open_dialog(cx, move |this, _window, cx| {
|
window.open_dialog(cx, move |this, _window, cx| {
|
||||||
this.width(px(520.))
|
this.width(px(520.))
|
||||||
.show_close(true)
|
.show_close(true)
|
||||||
.title("Select theme")
|
.title("Select theme")
|
||||||
.child(v_flex().gap_2().w_full().children({
|
.child(v_flex().gap_2().w_full().children({
|
||||||
let mut items = vec![];
|
let mut items: Vec<gpui::AnyElement> = vec![];
|
||||||
|
|
||||||
|
for (family_name, variants) in groups.iter() {
|
||||||
|
items.push(
|
||||||
|
div()
|
||||||
|
.pt_2()
|
||||||
|
.text_xs()
|
||||||
|
.italic()
|
||||||
|
.text_color(cx.theme().text_faint)
|
||||||
|
.child(SharedString::from(family_name.clone()))
|
||||||
|
.into_any_element(),
|
||||||
|
);
|
||||||
|
|
||||||
for (ix, variant) in variants.iter().enumerate() {
|
for (ix, variant) in variants.iter().enumerate() {
|
||||||
items.push(
|
items.push(
|
||||||
@@ -499,9 +524,9 @@ impl Workspace {
|
|||||||
div()
|
div()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.italic()
|
.italic()
|
||||||
.text_color(cx.theme().text_muted)
|
.text_color(cx.theme().text_faint)
|
||||||
.child(SharedString::from(
|
.child(SharedString::from(
|
||||||
variant.family_id.clone(),
|
variant.source.license.clone(),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -542,9 +567,11 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
|
.into_any_element(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
items
|
items
|
||||||
}))
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user