Add translucency setting + apply to runtime panel alpha
Domain: - AppearanceSettings gains translucency_pct (u8, 0..=100, default 40) with a clamping setter and serde round-trip coverage. - DEFAULT_TRANSLUCENCY_PCT and MAX_TRANSLUCENCY_PCT exported for the shell. Core: - BrowserCore::set_translucency_pct delegates to the appearance struct; the existing reset_appearance covers the reset path. - Integration test covers persistence into snapshot.appearance. Render: - chrome::sidebar::panel_bg(snapshot) replaces the static PANEL_BG constant, mapping the user's translucency_pct linearly into the alpha byte 0xff..0xb3. Sidebar (expanded + compact) and main pane consume the helper so changing the setting at runtime updates every glass surface in lock-step. Form: - Translucency row in chrome::appearance_form mirrors the design's static track + thumb visual driven by the persisted percentage, plus three preset chips (Solid 0 / Default 40 / Glassy 75) that mutate the setting through shell.set_translucency_pct. Strict UX rule preserved: alpha never drops below 0xb3 so panels stay readable without backdrop blur (which GPUI 0.2.2 doesn't expose).
This commit is contained in:
@@ -19,11 +19,26 @@ pub enum ThemeMode {
|
||||
Dark,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub const DEFAULT_TRANSLUCENCY_PCT: u8 = 40;
|
||||
pub const MAX_TRANSLUCENCY_PCT: u8 = 100;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct AppearanceSettings {
|
||||
wallpaper: WallpaperTheme,
|
||||
theme_mode: ThemeMode,
|
||||
reduce_motion: bool,
|
||||
translucency_pct: u8,
|
||||
}
|
||||
|
||||
impl Default for AppearanceSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
wallpaper: WallpaperTheme::default(),
|
||||
theme_mode: ThemeMode::default(),
|
||||
reduce_motion: false,
|
||||
translucency_pct: DEFAULT_TRANSLUCENCY_PCT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppearanceSettings {
|
||||
@@ -39,6 +54,10 @@ impl AppearanceSettings {
|
||||
self.reduce_motion
|
||||
}
|
||||
|
||||
pub fn translucency_pct(&self) -> u8 {
|
||||
self.translucency_pct
|
||||
}
|
||||
|
||||
pub fn set_wallpaper(&mut self, wallpaper: WallpaperTheme) {
|
||||
self.wallpaper = wallpaper;
|
||||
}
|
||||
@@ -50,6 +69,10 @@ impl AppearanceSettings {
|
||||
pub fn set_reduce_motion(&mut self, reduce_motion: bool) {
|
||||
self.reduce_motion = reduce_motion;
|
||||
}
|
||||
|
||||
pub fn set_translucency_pct(&mut self, value: u8) {
|
||||
self.translucency_pct = value.min(MAX_TRANSLUCENCY_PCT);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -62,6 +85,7 @@ mod tests {
|
||||
assert_eq!(settings.wallpaper(), WallpaperTheme::Dawn);
|
||||
assert_eq!(settings.theme_mode(), ThemeMode::System);
|
||||
assert!(!settings.reduce_motion());
|
||||
assert_eq!(settings.translucency_pct(), super::DEFAULT_TRANSLUCENCY_PCT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -71,23 +95,33 @@ mod tests {
|
||||
settings.set_wallpaper(WallpaperTheme::Violet);
|
||||
settings.set_theme_mode(ThemeMode::Dark);
|
||||
settings.set_reduce_motion(true);
|
||||
settings.set_translucency_pct(75);
|
||||
|
||||
assert_eq!(settings.wallpaper(), WallpaperTheme::Violet);
|
||||
assert_eq!(settings.theme_mode(), ThemeMode::Dark);
|
||||
assert!(settings.reduce_motion());
|
||||
assert_eq!(settings.translucency_pct(), 75);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn translucency_setter_clamps_above_max() {
|
||||
let mut settings = AppearanceSettings::default();
|
||||
settings.set_translucency_pct(200);
|
||||
assert_eq!(settings.translucency_pct(), super::MAX_TRANSLUCENCY_PCT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_round_trip_preserves_kebab_case_variants() {
|
||||
let settings = AppearanceSettings {
|
||||
wallpaper: WallpaperTheme::Mint,
|
||||
theme_mode: ThemeMode::Light,
|
||||
reduce_motion: true,
|
||||
};
|
||||
let mut settings = AppearanceSettings::default();
|
||||
settings.set_wallpaper(WallpaperTheme::Mint);
|
||||
settings.set_theme_mode(ThemeMode::Light);
|
||||
settings.set_reduce_motion(true);
|
||||
settings.set_translucency_pct(60);
|
||||
|
||||
let json = serde_json::to_string(&settings).unwrap();
|
||||
assert!(json.contains("\"wallpaper\":\"mint\""));
|
||||
assert!(json.contains("\"theme_mode\":\"light\""));
|
||||
assert!(json.contains("\"translucency_pct\":60"));
|
||||
|
||||
let restored: AppearanceSettings = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(restored, settings);
|
||||
|
||||
@@ -24,7 +24,9 @@ mod tab_group;
|
||||
mod update;
|
||||
mod url_text;
|
||||
|
||||
pub use appearance::{AppearanceSettings, ThemeMode, WallpaperTheme};
|
||||
pub use appearance::{
|
||||
AppearanceSettings, DEFAULT_TRANSLUCENCY_PCT, MAX_TRANSLUCENCY_PCT, ThemeMode, WallpaperTheme,
|
||||
};
|
||||
pub use archive::{ArchiveSource, ArchivedTab};
|
||||
pub use bookmark::BookmarkEntry;
|
||||
pub use command::{CommandIntent, CommandScope};
|
||||
|
||||
Reference in New Issue
Block a user