Checkpoint: Thread `WindowContext` through to `user_settings`

Marshall Bowers created

Change summary

crates/storybook2/src/storybook2.rs          | 29 ++++++++++++++-------
crates/ui2/src/components/assistant_panel.rs |  2 
crates/ui2/src/components/chat_panel.rs      | 13 +++------
crates/ui2/src/components/icon_button.rs     |  4 +-
crates/ui2/src/components/list.rs            |  4 +-
crates/ui2/src/components/panel.rs           | 10 +++---
crates/ui2/src/components/project_panel.rs   |  2 
crates/ui2/src/components/title_bar.rs       |  4 +-
crates/ui2/src/components/workspace.rs       | 25 +++++++-----------
crates/ui2/src/elements/button.rs            |  4 +-
crates/ui2/src/elements/icon.rs              |  4 +-
crates/ui2/src/elements/label.rs             |  2 
crates/ui2/src/lib.rs                        |  8 ++++++
crates/ui2/src/prelude.rs                    |  6 ++--
crates/ui2/src/settings.rs                   | 18 ++++++-------
15 files changed, 71 insertions(+), 64 deletions(-)

Detailed changes

crates/storybook2/src/storybook2.rs 🔗

@@ -17,7 +17,7 @@ use log::LevelFilter;
 use simplelog::SimpleLogger;
 use story_selector::ComponentStory;
 use ui::prelude::*;
-use ui::themed;
+use ui::{themed, FakeSettings};
 
 use crate::assets::Assets;
 use crate::story_selector::StorySelector;
@@ -68,8 +68,10 @@ fn main() {
             move |cx| {
                 view(
                     cx.entity(|cx| {
-                        cx.with_global(theme.clone(), |cx| {
-                            StoryWrapper::new(selector.story(cx), theme)
+                        cx.with_global(FakeSettings::default(), |cx| {
+                            cx.with_global(theme.clone(), |cx| {
+                                StoryWrapper::new(selector.story(cx), theme)
+                            })
                         })
                     }),
                     StoryWrapper::render,
@@ -85,20 +87,27 @@ fn main() {
 pub struct StoryWrapper {
     story: AnyView,
     theme: Theme,
+    settings: FakeSettings,
 }
 
 impl StoryWrapper {
     pub(crate) fn new(story: AnyView, theme: Theme) -> Self {
-        Self { story, theme }
+        Self {
+            story,
+            theme,
+            settings: FakeSettings::default(),
+        }
     }
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
-        themed(self.theme.clone(), cx, |cx| {
-            div()
-                .flex()
-                .flex_col()
-                .size_full()
-                .child(self.story.clone())
+        cx.with_global(self.settings.clone(), |cx| {
+            themed(self.theme.clone(), cx, |cx| {
+                div()
+                    .flex()
+                    .flex_col()
+                    .size_full()
+                    .child(self.story.clone())
+            })
         })
     }
 }

crates/ui2/src/components/assistant_panel.rs 🔗

@@ -29,7 +29,7 @@ impl<S: 'static + Send + Sync + Clone> AssistantPanel<S> {
     fn render(&mut self, view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
         let theme = theme(cx);
 
-        Panel::new(self.scroll_state.clone())
+        Panel::new(cx)
             .children(vec![div()
                 .flex()
                 .flex_col()

crates/ui2/src/components/chat_panel.rs 🔗

@@ -138,13 +138,10 @@ mod stories {
             Story::container(cx)
                 .child(Story::title_for::<_, ChatPanel<S>>(cx))
                 .child(Story::label(cx, "Default"))
-                .child(
-                    Panel::new(ScrollState::default())
-                        .child(ChatPanel::new(ScrollState::default())),
-                )
+                .child(Panel::new(cx).child(ChatPanel::new(ScrollState::default())))
                 .child(Story::label(cx, "With Mesages"))
-                .child(Panel::new(ScrollState::default()).child(
-                    ChatPanel::new(ScrollState::default()).messages(vec![
+                .child(
+                    Panel::new(cx).child(ChatPanel::new(ScrollState::default()).messages(vec![
                         ChatMessage::new(
                             "osiewicz".to_string(),
                             "is this thing on?".to_string(),
@@ -159,8 +156,8 @@ mod stories {
                                 .unwrap()
                                 .naive_local(),
                         ),
-                    ]),
-                ))
+                    ])),
+                )
         }
     }
 }

crates/ui2/src/components/icon_button.rs 🔗

@@ -78,8 +78,8 @@ impl<S: 'static + Send + Sync> IconButton<S> {
         let mut button = h_stack()
             .justify_center()
             .rounded_md()
-            .py(ui_size(0.25))
-            .px(ui_size(6. / 14.))
+            .py(ui_size(cx, 0.25))
+            .px(ui_size(cx, 6. / 14.))
             .when(self.variant == ButtonVariant::Filled, |this| {
                 this.bg(color.filled_element)
             })

crates/ui2/src/components/list.rs 🔗

@@ -363,7 +363,7 @@ impl<S: 'static + Send + Sync + Clone> ListEntry<S> {
         let theme = theme(cx);
         let system_color = SystemColor::new();
         let color = ThemeColor::new(cx);
-        let setting = user_settings();
+        let settings = user_settings(cx);
 
         let left_content = match self.left_content.clone() {
             Some(LeftContent::Icon(i)) => Some(
@@ -395,7 +395,7 @@ impl<S: 'static + Send + Sync + Clone> ListEntry<S> {
                     // .ml(rems(0.75 * self.indent_level as f32))
                     .children((0..self.indent_level).map(|_| {
                         div()
-                            .w(*setting.list_indent_depth)
+                            .w(*settings.list_indent_depth)
                             .h_full()
                             .flex()
                             .justify_center()

crates/ui2/src/components/panel.rs 🔗

@@ -53,15 +53,15 @@ pub struct Panel<S: 'static + Send + Sync> {
 }
 
 impl<S: 'static + Send + Sync> Panel<S> {
-    pub fn new(scroll_state: ScrollState) -> Self {
-        let setting = user_settings();
+    pub fn new(cx: &mut WindowContext) -> Self {
+        let settings = user_settings(cx);
 
         Self {
             state_type: PhantomData,
-            scroll_state,
+            scroll_state: ScrollState::default(),
             current_side: PanelSide::default(),
             allowed_sides: PanelAllowedSides::default(),
-            initial_width: *setting.default_panel_size,
+            initial_width: *settings.default_panel_size,
             width: None,
             children: SmallVec::new(),
         }
@@ -175,7 +175,7 @@ mod stories {
                 .child(Story::title_for::<_, Panel<S>>(cx))
                 .child(Story::label(cx, "Default"))
                 .child(
-                    Panel::new(ScrollState::default()).child(
+                    Panel::new(cx).child(
                         div()
                             .overflow_y_scroll(ScrollState::default())
                             .children((0..100).map(|ix| Label::new(format!("Item {}", ix + 1)))),

crates/ui2/src/components/project_panel.rs 🔗

@@ -87,7 +87,7 @@ mod stories {
                 .child(Story::title_for::<_, ProjectPanel<S>>(cx))
                 .child(Story::label(cx, "Default"))
                 .child(
-                    Panel::new(ScrollState::default())
+                    Panel::new(cx)
                         .child(ProjectPanel::new(ScrollState::default())),
                 )
         }

crates/ui2/src/components/title_bar.rs 🔗

@@ -95,7 +95,7 @@ impl TitleBar {
     fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
         let theme = theme(cx);
         let color = ThemeColor::new(cx);
-        let setting = user_settings();
+        let settings = user_settings(cx);
 
         // let has_focus = cx.window_is_active();
         let has_focus = true;
@@ -127,7 +127,7 @@ impl TitleBar {
                             .flex()
                             .items_center()
                             .gap_1()
-                            .when(*setting.titlebar.show_project_owner, |this| {
+                            .when(*settings.titlebar.show_project_owner, |this| {
                                 this.child(Button::new("iamnbutler"))
                             })
                             .child(Button::new("zed"))

crates/ui2/src/components/workspace.rs 🔗

@@ -165,7 +165,7 @@ impl Workspace {
                     .border_color(theme.lowest.base.default.border)
                     .children(
                         Some(
-                            Panel::new(self.left_panel_scroll_state.clone())
+                            Panel::new(cx)
                                 .side(PanelSide::Left)
                                 .child(ProjectPanel::new(ScrollState::default())),
                         )
@@ -173,7 +173,7 @@ impl Workspace {
                     )
                     .children(
                         Some(
-                            Panel::new(self.left_panel_scroll_state.clone())
+                            Panel::new(cx)
                                 .child(CollabPanel::new(ScrollState::default()))
                                 .side(PanelSide::Left),
                         )
@@ -196,7 +196,7 @@ impl Workspace {
                             )
                             .children(
                                 Some(
-                                    Panel::new(self.bottom_panel_scroll_state.clone())
+                                    Panel::new(cx)
                                         .child(Terminal::new())
                                         .allowed_sides(PanelAllowedSides::BottomOnly)
                                         .side(PanelSide::Bottom),
@@ -205,10 +205,8 @@ impl Workspace {
                             ),
                     )
                     .children(
-                        Some(
-                            Panel::new(self.right_panel_scroll_state.clone())
-                                .side(PanelSide::Right)
-                                .child(ChatPanel::new(ScrollState::default()).messages(vec![
+                        Some(Panel::new(cx).side(PanelSide::Right).child(
+                            ChatPanel::new(ScrollState::default()).messages(vec![
                                     ChatMessage::new(
                                         "osiewicz".to_string(),
                                         "is this thing on?".to_string(),
@@ -223,24 +221,21 @@ impl Workspace {
                                             .unwrap()
                                             .naive_local(),
                                     ),
-                                ])),
-                        )
+                                ]),
+                        ))
                         .filter(|_| self.is_chat_panel_open()),
                     )
                     .children(
                         Some(
-                            Panel::new(self.right_panel_scroll_state.clone())
+                            Panel::new(cx)
                                 .side(PanelSide::Right)
                                 .child(div().w_96().h_full().child("Notifications")),
                         )
                         .filter(|_| self.is_notifications_panel_open()),
                     )
                     .children(
-                        Some(
-                            Panel::new(self.right_panel_scroll_state.clone())
-                                .child(AssistantPanel::new()),
-                        )
-                        .filter(|_| self.is_assistant_panel_open()),
+                        Some(Panel::new(cx).child(AssistantPanel::new()))
+                            .filter(|_| self.is_assistant_panel_open()),
                     ),
             )
             .child(StatusBar::new())

crates/ui2/src/elements/button.rs 🔗

@@ -149,11 +149,11 @@ impl<S: 'static + Send + Sync + Clone> Button<S> {
     fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
         let icon_color = self.icon_color();
         let border_color = self.border_color(cx);
-        let setting = user_settings();
+        let settings = user_settings(cx);
 
         let mut el = h_stack()
             .p_1()
-            .text_size(ui_size(1.))
+            .text_size(ui_size(cx, 1.))
             .rounded_md()
             .border()
             .border_color(border_color)

crates/ui2/src/elements/icon.rs 🔗

@@ -180,8 +180,8 @@ impl<S: 'static + Send + Sync> IconElement<S> {
         let theme = theme(cx);
         let fill = self.color.color(theme);
         let svg_size = match self.size {
-            IconSize::Small => ui_size(12. / 14.),
-            IconSize::Medium => ui_size(15. / 14.),
+            IconSize::Small => ui_size(cx, 12. / 14.),
+            IconSize::Medium => ui_size(cx, 15. / 14.),
         };
 
         svg()

crates/ui2/src/elements/label.rs 🔗

@@ -96,7 +96,7 @@ impl<S: 'static + Send + Sync + Clone> Label<S> {
                         .bg(LabelColor::Hidden.hsla(cx)),
                 )
             })
-            .text_size(ui_size(1.))
+            .text_size(ui_size(cx, 1.))
             .when(self.line_height_style == LineHeightStyle::UILabel, |this| {
                 this.line_height(relative(1.))
             })

crates/ui2/src/lib.rs 🔗

@@ -14,6 +14,14 @@ pub use elements::*;
 pub use prelude::*;
 pub use static_data::*;
 
+// This needs to be fully qualified with `crate::` otherwise we get a panic
+// at:
+//   thread '<unnamed>' panicked at crates/gpui3/src/platform/mac/platform.rs:66:81:
+//   called `Option::unwrap()` on a `None` value
+//
+// AFAICT this is something to do with conflicting names between crates and modules that
+// interfaces with declaring the `ClassDecl`.
+pub use crate::settings::*;
 pub use crate::theme::*;
 
 #[cfg(feature = "stories")]

crates/ui2/src/prelude.rs 🔗

@@ -142,12 +142,12 @@ impl HighlightColor {
     }
 }
 
-pub fn ui_size(size: f32) -> Rems {
+pub fn ui_size(cx: &mut WindowContext, size: f32) -> Rems {
     const UI_SCALE_RATIO: f32 = 0.875;
 
-    let setting = user_settings();
+    let settings = user_settings(cx);
 
-    rems(*setting.ui_scale * UI_SCALE_RATIO * size)
+    rems(*settings.ui_scale * UI_SCALE_RATIO * size)
 }
 
 #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)]

crates/ui2/src/settings.rs 🔗

@@ -1,15 +1,13 @@
 use std::ops::Deref;
 
-use gpui3::{rems, AbsoluteLength};
+use gpui3::{rems, AbsoluteLength, WindowContext};
 
 use crate::DisclosureControlStyle;
 
-// This is a fake static example of user settings overriding the default settings
-pub fn user_settings() -> Settings {
-    let mut settings = Settings::default();
-    settings.list_indent_depth = SettingValue::UserDefined(rems(0.5).into());
-    // settings.ui_scale = SettingValue::UserDefined(2.);
-    settings
+/// Returns the user settings.
+pub fn user_settings(cx: &WindowContext) -> FakeSettings {
+    // cx.global::<FakeSettings>().clone()
+    FakeSettings::default()
 }
 
 #[derive(Clone)]
@@ -48,7 +46,7 @@ impl Default for TitlebarSettings {
 
 // These should be merged into settings
 #[derive(Clone)]
-pub struct Settings {
+pub struct FakeSettings {
     pub default_panel_size: SettingValue<AbsoluteLength>,
     pub list_disclosure_style: SettingValue<DisclosureControlStyle>,
     pub list_indent_depth: SettingValue<AbsoluteLength>,
@@ -56,7 +54,7 @@ pub struct Settings {
     pub ui_scale: SettingValue<f32>,
 }
 
-impl Default for Settings {
+impl Default for FakeSettings {
     fn default() -> Self {
         Self {
             titlebar: TitlebarSettings::default(),
@@ -68,4 +66,4 @@ impl Default for Settings {
     }
 }
 
-impl Settings {}
+impl FakeSettings {}