scrollbar: Fix scrollbar width on always show mode. (#1196)
And fixes #1192 render bug.
This commit is contained in:
parent
6569bead8b
commit
02b432ed17
5 changed files with 33 additions and 43 deletions
|
|
@ -143,13 +143,11 @@ actions!(story, [TestAction, Tab, TabPrev]);
|
|||
|
||||
pub struct AppState {
|
||||
pub invisible_panels: Entity<Vec<SharedString>>,
|
||||
pub theme_name: Option<SharedString>,
|
||||
}
|
||||
impl AppState {
|
||||
fn init(cx: &mut App) {
|
||||
let state = Self {
|
||||
invisible_panels: cx.new(|_| Vec::new()),
|
||||
theme_name: None,
|
||||
};
|
||||
cx.set_global::<AppState>(state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<ScrollbarShow>,
|
||||
}
|
||||
|
||||
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::<State>(&json) {
|
||||
if let Ok(state) = serde_json::from_str::<State>(&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::<Theme>(|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<Self>,
|
||||
) -> 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(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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::<Theme>().scrollbar_show = ScrollbarShow::Scrolling;
|
||||
Theme::global_mut(cx).scrollbar_show = if cx.should_auto_hide_scrollbars() {
|
||||
ScrollbarShow::Scrolling
|
||||
} else {
|
||||
cx.global_mut::<Theme>().scrollbar_show = ScrollbarShow::Hover;
|
||||
}
|
||||
ScrollbarShow::Hover
|
||||
};
|
||||
}
|
||||
|
||||
pub fn change(mode: impl Into<ThemeMode>, window: Option<&mut Window>, cx: &mut App) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue