Update outline panel representation when a theme is changed (#19747)

Kirill Bulatov created

Release Notes:

- N/A

Change summary

crates/outline_panel/src/outline_panel.rs | 28 +++++++++++++++++-------
crates/theme/src/schema.rs                | 16 +++++++-------
crates/theme/src/settings.rs              |  4 +-
crates/theme/src/styles/accents.rs        |  2 
crates/theme/src/styles/colors.rs         |  4 +-
crates/theme/src/styles/players.rs        |  4 +-
crates/theme/src/styles/status.rs         |  2 
crates/theme/src/styles/system.rs         |  2 
crates/theme/src/theme.rs                 |  2 
9 files changed, 38 insertions(+), 26 deletions(-)

Detailed changes

crates/outline_panel/src/outline_panel.rs 🔗

@@ -41,7 +41,7 @@ use search::{BufferSearchBar, ProjectSearchView};
 use serde::{Deserialize, Serialize};
 use settings::{Settings, SettingsStore};
 use smol::channel;
-use theme::SyntaxTheme;
+use theme::{SyntaxTheme, ThemeSettings};
 use util::{debug_panic, RangeExt, ResultExt, TryFutureExt};
 use workspace::{
     dock::{DockPosition, Panel, PanelEvent},
@@ -653,13 +653,25 @@ impl OutlinePanel {
             });
 
             let mut outline_panel_settings = *OutlinePanelSettings::get_global(cx);
-            let settings_subscription = cx.observe_global::<SettingsStore>(move |_, cx| {
-                let new_settings = *OutlinePanelSettings::get_global(cx);
-                if outline_panel_settings != new_settings {
-                    outline_panel_settings = new_settings;
-                    cx.notify();
-                }
-            });
+            let mut current_theme = ThemeSettings::get_global(cx).clone();
+            let settings_subscription =
+                cx.observe_global::<SettingsStore>(move |outline_panel, cx| {
+                    let new_settings = OutlinePanelSettings::get_global(cx);
+                    let new_theme = ThemeSettings::get_global(cx);
+                    if &current_theme != new_theme {
+                        outline_panel_settings = *new_settings;
+                        current_theme = new_theme.clone();
+                        for excerpts in outline_panel.excerpts.values_mut() {
+                            for excerpt in excerpts.values_mut() {
+                                excerpt.invalidate_outlines();
+                            }
+                        }
+                        outline_panel.update_non_fs_items(cx);
+                    } else if &outline_panel_settings != new_settings {
+                        outline_panel_settings = *new_settings;
+                        cx.notify();
+                    }
+                });
 
             let mut outline_panel = Self {
                 mode: ItemsDisplayMode::Outline,

crates/theme/src/schema.rs 🔗

@@ -71,7 +71,7 @@ pub struct ThemeContent {
 }
 
 /// The content of a serialized theme.
-#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
 #[serde(default)]
 pub struct ThemeStyleContent {
     #[serde(default, rename = "background.appearance")]
@@ -133,7 +133,7 @@ impl ThemeStyleContent {
     }
 }
 
-#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
 #[serde(default)]
 pub struct ThemeColorsContent {
     /// Border color. Used for most borders, is usually a high contrast color.
@@ -952,7 +952,7 @@ impl ThemeColorsContent {
     }
 }
 
-#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
 #[serde(default)]
 pub struct StatusColorsContent {
     /// Indicates some kind of conflict, like a file changed on disk while it was open, or
@@ -1273,17 +1273,17 @@ impl StatusColorsContent {
     }
 }
 
-#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
 pub struct AccentContent(pub Option<String>);
 
-#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
 pub struct PlayerColorContent {
     pub cursor: Option<String>,
     pub background: Option<String>,
     pub selection: Option<String>,
 }
 
-#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
 #[serde(rename_all = "snake_case")]
 pub enum FontStyleContent {
     Normal,
@@ -1301,7 +1301,7 @@ impl From<FontStyleContent> for FontStyle {
     }
 }
 
-#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr)]
+#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr, PartialEq)]
 #[repr(u16)]
 pub enum FontWeightContent {
     Thin = 100,
@@ -1359,7 +1359,7 @@ impl From<FontWeightContent> for FontWeight {
     }
 }
 
-#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
+#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
 #[serde(default)]
 pub struct HighlightStyleContent {
     pub color: Option<String>,

crates/theme/src/settings.rs 🔗

@@ -86,7 +86,7 @@ impl From<UiDensity> for String {
 }
 
 /// Customizable settings for the UI and theme system.
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct ThemeSettings {
     /// The UI font size. Determines the size of text in the UI,
     /// as well as the size of a [gpui::Rems] unit.
@@ -213,7 +213,7 @@ pub(crate) struct AdjustedUiFontSize(Pixels);
 impl Global for AdjustedUiFontSize {}
 
 /// Represents the selection of a theme, which can be either static or dynamic.
-#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
+#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
 #[serde(untagged)]
 pub enum ThemeSelection {
     /// A static theme selection, represented by a single theme name.

crates/theme/src/styles/accents.rs 🔗

@@ -7,7 +7,7 @@ use crate::{
 };
 
 /// A collection of colors that are used to color indent aware lines in the editor.
-#[derive(Clone, Deserialize)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct AccentColors(pub Vec<Hsla>);
 
 impl Default for AccentColors {

crates/theme/src/styles/colors.rs 🔗

@@ -8,7 +8,7 @@ use crate::{
     AccentColors, PlayerColors, StatusColors, StatusColorsRefinement, SyntaxTheme, SystemColors,
 };
 
-#[derive(Refineable, Clone, Debug)]
+#[derive(Refineable, Clone, Debug, PartialEq)]
 #[refineable(Debug, serde::Deserialize)]
 pub struct ThemeColors {
     /// Border color. Used for most borders, is usually a high contrast color.
@@ -249,7 +249,7 @@ pub struct ThemeColors {
     pub link_text_hover: Hsla,
 }
 
-#[derive(Refineable, Clone)]
+#[derive(Refineable, Clone, PartialEq)]
 pub struct ThemeStyles {
     /// The background appearance of the window.
     pub window_background_appearance: WindowBackgroundAppearance,

crates/theme/src/styles/players.rs 🔗

@@ -7,7 +7,7 @@ use crate::{
     amber, blue, jade, lime, orange, pink, purple, red, try_parse_color, PlayerColorContent,
 };
 
-#[derive(Debug, Clone, Copy, Deserialize, Default)]
+#[derive(Debug, Clone, Copy, Deserialize, Default, PartialEq)]
 pub struct PlayerColor {
     pub cursor: Hsla,
     pub background: Hsla,
@@ -20,7 +20,7 @@ pub struct PlayerColor {
 ///
 /// The rest of the default colors crisscross back and forth on the
 /// color wheel so that the colors are as distinct as possible.
-#[derive(Clone, Deserialize)]
+#[derive(Clone, Deserialize, PartialEq)]
 pub struct PlayerColors(pub Vec<PlayerColor>);
 
 impl Default for PlayerColors {

crates/theme/src/styles/status.rs 🔗

@@ -5,7 +5,7 @@ use refineable::Refineable;
 
 use crate::{blue, grass, neutral, red, yellow};
 
-#[derive(Refineable, Clone, Debug)]
+#[derive(Refineable, Clone, Debug, PartialEq)]
 #[refineable(Debug, serde::Deserialize)]
 pub struct StatusColors {
     /// Indicates some kind of conflict, like a file changed on disk while it was open, or

crates/theme/src/styles/system.rs 🔗

@@ -2,7 +2,7 @@
 
 use gpui::{hsla, Hsla};
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct SystemColors {
     pub transparent: Hsla,
     pub mac_os_traffic_light_red: Hsla,

crates/theme/src/theme.rs 🔗

@@ -140,7 +140,7 @@ pub struct ThemeFamily {
 impl ThemeFamily {}
 
 /// A theme is the primary mechanism for defining the appearance of the UI.
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub struct Theme {
     /// The unique identifier for the theme.
     pub id: String,