diff --git a/crates/story/src/lib.rs b/crates/story/src/lib.rs index 93615113..e7e3e6a5 100644 --- a/crates/story/src/lib.rs +++ b/crates/story/src/lib.rs @@ -143,13 +143,11 @@ actions!(story, [TestAction, Tab, TabPrev]); pub struct AppState { pub invisible_panels: Entity>, - pub theme_name: Option, } impl AppState { fn init(cx: &mut App) { let state = Self { invisible_panels: cx.new(|_| Vec::new()), - theme_name: None, }; cx.set_global::(state); } diff --git a/crates/story/src/themes.rs b/crates/story/src/themes.rs index e6a91fda..611352f2 100644 --- a/crates/story/src/themes.rs +++ b/crates/story/src/themes.rs @@ -6,41 +6,50 @@ use gpui::{ use gpui_component::{ button::{Button, ButtonVariants}, popup_menu::PopupMenuExt, + scroll::ScrollbarShow, ActiveTheme, IconName, Sizable, Theme, ThemeRegistry, }; use serde::{Deserialize, Serialize}; -use crate::AppState; - const STATE_FILE: &str = "target/state.json"; #[derive(Debug, Clone, Serialize, Deserialize)] struct State { theme: SharedString, + scrollbar_show: Option, } pub fn init(cx: &mut App) { // Load last theme state let json = std::fs::read_to_string(STATE_FILE).unwrap_or(String::default()); tracing::info!("Load themes..."); - if let Err(err) = ThemeRegistry::watch_dir(PathBuf::from("./themes"), cx, move |cx| { - if let Ok(state) = serde_json::from_str::(&json) { + if let Ok(state) = serde_json::from_str::(&json) { + if let Err(err) = ThemeRegistry::watch_dir(PathBuf::from("./themes"), cx, move |cx| { if let Some(theme) = ThemeRegistry::global(cx) .themes() .get(&state.theme) .cloned() { - AppState::global_mut(cx).theme_name = Some(state.theme.clone()); Theme::global_mut(cx).apply_config(&theme); - cx.refresh_windows(); } + }) { + tracing::error!("Failed to watch themes directory: {}", err); } - }) { - tracing::error!("Failed to watch themes directory: {}", err); + + if let Some(scrollbar_show) = state.scrollbar_show { + Theme::global_mut(cx).scrollbar_show = scrollbar_show; + } + cx.refresh_windows(); } cx.observe_global::(|cx| { - AppState::global_mut(cx).theme_name = Some(cx.theme().theme_name().into()); + let state = State { + theme: cx.theme().theme_name().clone(), + scrollbar_show: Some(cx.theme().scrollbar_show), + }; + + let json = serde_json::to_string_pretty(&state).unwrap(); + std::fs::write(STATE_FILE, json).unwrap(); }) .detach(); } @@ -63,31 +72,17 @@ impl Render for ThemeSwitcher { _: &mut gpui::Window, cx: &mut gpui::Context, ) -> impl gpui::IntoElement { - let theme_name = AppState::global(cx) - .theme_name - .clone() - .unwrap_or("default-light".into()); + let theme_name = cx.theme().theme_name().clone(); div() .id("theme-switcher") .on_action(cx.listener(|_, switch: &SwitchTheme, _, cx| { let theme_name = switch.0.clone(); - // Save AppState - let mut state = State { - theme: theme_name.clone(), - }; - if let Some(theme_config) = ThemeRegistry::global(cx).themes().get(&theme_name).cloned() { Theme::global_mut(cx).apply_config(&theme_config); - state.theme = theme_config.name.clone(); - AppState::global_mut(cx).theme_name = Some(theme_name.clone()); } - - let json = serde_json::to_string_pretty(&state).unwrap(); - std::fs::write(STATE_FILE, json).unwrap(); - cx.notify(); })) .child( diff --git a/crates/story/src/title_bar.rs b/crates/story/src/title_bar.rs index cd1eaade..9d3aaf5a 100644 --- a/crates/story/src/title_bar.rs +++ b/crates/story/src/title_bar.rs @@ -34,13 +34,6 @@ impl AppTitleBar { ) -> Self { let locale_selector = cx.new(|cx| LocaleSelector::new(window, cx)); let font_size_selector = cx.new(|cx| FontSizeSelector::new(window, cx)); - - if cx.should_auto_hide_scrollbars() { - Theme::global_mut(cx).scrollbar_show = ScrollbarShow::Scrolling; - } else { - Theme::global_mut(cx).scrollbar_show = ScrollbarShow::Hover; - } - let theme_switcher = cx.new(|cx| ThemeSwitcher::new(cx)); Self { diff --git a/crates/ui/src/scroll/scrollbar.rs b/crates/ui/src/scroll/scrollbar.rs index b847d331..90fb9e16 100644 --- a/crates/ui/src/scroll/scrollbar.rs +++ b/crates/ui/src/scroll/scrollbar.rs @@ -386,13 +386,18 @@ impl Scrollbar { } fn style_for_normal(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) { + let (width, inset, radius) = match cx.theme().scrollbar_show { + ScrollbarShow::Scrolling => (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS), + _ => (THUMB_ACTIVE_WIDTH, THUMB_ACTIVE_INSET, THUMB_ACTIVE_RADIUS), + }; + ( cx.theme().scrollbar_thumb, cx.theme().scrollbar, gpui::transparent_black(), - THUMB_WIDTH, - THUMB_INSET, - THUMB_RADIUS, + width, + inset, + radius, ) } @@ -509,7 +514,7 @@ impl Element for Scrollbar { // The horizontal scrollbar is set avoid overlapping with the vertical scrollbar, if the vertical scrollbar is visible. let margin_end = if has_both && !is_vertical { - THUMB_ACTIVE_WIDTH + WIDTH } else { px(0.) }; @@ -551,7 +556,6 @@ impl Element for Scrollbar { let state = self.state.clone(); let is_always_to_show = cx.theme().scrollbar_show.is_always(); - let is_hover_to_show = cx.theme().scrollbar_show.is_hover(); let is_hovered_on_bar = state.get().hovered_axis == Some(axis); let is_hovered_on_thumb = state.get().hovered_on_thumb == Some(axis); let is_offset_changed = state.get().last_scroll_offset != self.scroll_handle.offset(); @@ -559,7 +563,7 @@ impl Element for Scrollbar { let (thumb_bg, bar_bg, bar_border, thumb_width, inset, radius) = if state.get().dragged_axis == Some(axis) { Self::style_for_active(cx) - } else if is_hover_to_show && (is_hovered_on_bar || is_hovered_on_thumb) { + } else if is_hovered_on_bar || is_hovered_on_thumb { if is_hovered_on_thumb { Self::style_for_hovered_thumb(cx) } else { diff --git a/crates/ui/src/theme/mod.rs b/crates/ui/src/theme/mod.rs index 61646c83..abbc80b8 100644 --- a/crates/ui/src/theme/mod.rs +++ b/crates/ui/src/theme/mod.rs @@ -140,11 +140,11 @@ impl Theme { /// Sync the Scrollbar showing behavior with the system pub fn sync_scrollbar_appearance(cx: &mut App) { - if cx.should_auto_hide_scrollbars() { - cx.global_mut::().scrollbar_show = ScrollbarShow::Scrolling; + Theme::global_mut(cx).scrollbar_show = if cx.should_auto_hide_scrollbars() { + ScrollbarShow::Scrolling } else { - cx.global_mut::().scrollbar_show = ScrollbarShow::Hover; - } + ScrollbarShow::Hover + }; } pub fn change(mode: impl Into, window: Option<&mut Window>, cx: &mut App) {