Pull the settings from the global state

Marshall Bowers created

Change summary

crates/storybook2/src/storybook2.rs |  4 
crates/ui2/src/settings.rs          | 84 +++++++++++++++++++++++++++++-
2 files changed, 82 insertions(+), 6 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, FakeSettings};
+use ui::{themed, with_settings, FakeSettings};
 
 use crate::assets::Assets;
 use crate::story_selector::StorySelector;
@@ -100,7 +100,7 @@ impl StoryWrapper {
     }
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
-        cx.with_global(self.settings.clone(), |cx| {
+        with_settings(self.settings.clone(), cx, |cx| {
             themed(self.theme.clone(), cx, |cx| {
                 div()
                     .flex()

crates/ui2/src/settings.rs 🔗

@@ -1,13 +1,14 @@
 use std::ops::Deref;
 
-use gpui3::{rems, AbsoluteLength, WindowContext};
+use gpui3::{
+    rems, AbsoluteLength, AnyElement, BorrowAppContext, Bounds, LayoutId, Pixels, WindowContext,
+};
 
-use crate::DisclosureControlStyle;
+use crate::prelude::*;
 
 /// Returns the user settings.
 pub fn user_settings(cx: &WindowContext) -> FakeSettings {
-    // cx.global::<FakeSettings>().clone()
-    FakeSettings::default()
+    cx.global::<FakeSettings>().clone()
 }
 
 #[derive(Clone)]
@@ -67,3 +68,78 @@ impl Default for FakeSettings {
 }
 
 impl FakeSettings {}
+
+pub fn with_settings<E, F>(
+    settings: FakeSettings,
+    cx: &mut ViewContext<E::ViewState>,
+    build_child: F,
+) -> WithSettings<E>
+where
+    E: Element,
+    F: FnOnce(&mut ViewContext<E::ViewState>) -> E,
+{
+    let child = cx.with_global(theme.clone(), |cx| build_child(cx));
+    WithSettings { settings, child }
+}
+
+pub struct WithSettings<E> {
+    pub(crate) settings: FakeSettings,
+    pub(crate) child: E,
+}
+
+impl<E> IntoAnyElement<E::ViewState> for WithSettings<E>
+where
+    E: Element,
+{
+    fn into_any(self) -> AnyElement<E::ViewState> {
+        AnyElement::new(self)
+    }
+}
+
+impl<E: Element> Element for WithSettings<E> {
+    type ViewState = E::ViewState;
+    type ElementState = E::ElementState;
+
+    fn id(&self) -> Option<gpui3::ElementId> {
+        None
+    }
+
+    fn initialize(
+        &mut self,
+        view_state: &mut Self::ViewState,
+        element_state: Option<Self::ElementState>,
+        cx: &mut ViewContext<Self::ViewState>,
+    ) -> Self::ElementState {
+        cx.with_global(self.settings.clone(), |cx| {
+            self.child.initialize(view_state, element_state, cx)
+        })
+    }
+
+    fn layout(
+        &mut self,
+        view_state: &mut E::ViewState,
+        element_state: &mut Self::ElementState,
+        cx: &mut ViewContext<E::ViewState>,
+    ) -> LayoutId
+    where
+        Self: Sized,
+    {
+        cx.with_global(self.settings.clone(), |cx| {
+            self.child.layout(view_state, element_state, cx)
+        })
+    }
+
+    fn paint(
+        &mut self,
+        bounds: Bounds<Pixels>,
+        view_state: &mut Self::ViewState,
+        frame_state: &mut Self::ElementState,
+        cx: &mut ViewContext<Self::ViewState>,
+    ) where
+        Self: Sized,
+    {
+        cx.with_global(self.settings.clone(), |cx| {
+            self.child.paint(bounds, view_state, frame_state, cx);
+        });
+    }
+}