Change `TitleBar` to a view

Marshall Bowers created

Change summary

crates/storybook2/src/story_selector.rs |  5 -
crates/ui2/src/components/title_bar.rs  | 55 ++++++++++++++++----------
crates/ui2/src/components/workspace.rs  | 19 ++++----
3 files changed, 44 insertions(+), 35 deletions(-)

Detailed changes

crates/storybook2/src/story_selector.rs 🔗

@@ -153,10 +153,7 @@ impl ComponentStory {
                 ui::ThemeSelectorStory::new().into_any()
             })
             .into_any(),
-            Self::TitleBar => view(cx.entity(|cx| ()), |_, _| {
-                ui::TitleBarStory::new().into_any()
-            })
-            .into_any(),
+            Self::TitleBar => ui::TitleBarStory::view(cx).into_any(),
             Self::Toast => {
                 view(cx.entity(|cx| ()), |_, _| ui::ToastStory::new().into_any()).into_any()
             }

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

@@ -1,11 +1,12 @@
-use std::marker::PhantomData;
 use std::sync::atomic::AtomicBool;
 use std::sync::Arc;
 
+use gpui3::{view, Context, View};
+
 use crate::prelude::*;
 use crate::{
-    theme, Avatar, Button, Icon, IconButton, IconColor, PlayerStack, PlayerWithCallStatus,
-    ToolDivider, TrafficLights,
+    random_players_with_call_status, theme, Avatar, Button, Icon, IconButton, IconColor,
+    PlayerStack, PlayerWithCallStatus, ToolDivider, TrafficLights,
 };
 
 #[derive(Clone)]
@@ -15,16 +16,15 @@ pub struct Livestream {
                                  // windows
 }
 
-#[derive(Element)]
-pub struct TitleBar<S: 'static + Send + Sync + Clone> {
-    state_type: PhantomData<S>,
+#[derive(Clone)]
+pub struct TitleBar {
     /// If the window is active from the OS's perspective.
     is_active: Arc<AtomicBool>,
     livestream: Option<Livestream>,
 }
 
-impl<S: 'static + Send + Sync + Clone> TitleBar<S> {
-    pub fn new(cx: &mut ViewContext<S>) -> Self {
+impl TitleBar {
+    pub fn new(cx: &mut ViewContext<Self>) -> Self {
         let is_active = Arc::new(AtomicBool::new(true));
         let active = is_active.clone();
 
@@ -35,7 +35,6 @@ impl<S: 'static + Send + Sync + Clone> TitleBar<S> {
         // .detach();
 
         Self {
-            state_type: PhantomData,
             is_active,
             livestream: None,
         }
@@ -46,7 +45,19 @@ impl<S: 'static + Send + Sync + Clone> TitleBar<S> {
         self
     }
 
-    fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
+    pub fn view(cx: &mut WindowContext) -> View<Self> {
+        view(
+            cx.entity(|cx| {
+                Self::new(cx).set_livestream(Some(Livestream {
+                    players: random_players_with_call_status(7),
+                    channel: Some("gpui2-ui".to_string()),
+                }))
+            }),
+            Self::render,
+        )
+    }
+
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
         let theme = theme(cx);
         // let has_focus = cx.window_is_active();
         let has_focus = true;
@@ -127,23 +138,25 @@ mod stories {
 
     use super::*;
 
-    #[derive(Element)]
-    pub struct TitleBarStory<S: 'static + Send + Sync + Clone> {
-        state_type: PhantomData<S>,
+    pub struct TitleBarStory {
+        title_bar: View<TitleBar>,
     }
 
-    impl<S: 'static + Send + Sync + Clone> TitleBarStory<S> {
-        pub fn new() -> Self {
-            Self {
-                state_type: PhantomData,
-            }
+    impl TitleBarStory {
+        pub fn view(cx: &mut WindowContext) -> View<Self> {
+            view(
+                cx.entity(|cx| Self {
+                    title_bar: TitleBar::view(cx),
+                }),
+                Self::render,
+            )
         }
 
-        fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
+        fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
             Story::container(cx)
-                .child(Story::title_for::<_, TitleBar<S>>(cx))
+                .child(Story::title_for::<_, TitleBar>(cx))
                 .child(Story::label(cx, "Default"))
-                .child(TitleBar::new(cx))
+                .child(self.title_bar.clone())
         }
     }
 }

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

@@ -2,15 +2,16 @@ use chrono::DateTime;
 use gpui3::{px, relative, rems, view, Context, Size, View};
 
 use crate::{
-    hello_world_rust_editor_with_status_example, random_players_with_call_status, theme, v_stack,
-    AssistantPanel, Button, ChatMessage, ChatPanel, CollabPanel, EditorPane, Label,
-    LanguageSelector, Livestream, Pane, PaneGroup, Panel, PanelAllowedSides, PanelSide,
-    ProjectPanel, SplitDirection, StatusBar, Terminal, TitleBar, Toast, ToastOrigin,
+    hello_world_rust_editor_with_status_example, theme, v_stack, AssistantPanel, Button,
+    ChatMessage, ChatPanel, CollabPanel, EditorPane, Label, LanguageSelector, Pane, PaneGroup,
+    Panel, PanelAllowedSides, PanelSide, ProjectPanel, SplitDirection, StatusBar, Terminal,
+    TitleBar, Toast, ToastOrigin,
 };
 use crate::{prelude::*, NotificationToast};
 
 #[derive(Clone)]
 pub struct Workspace {
+    title_bar: View<TitleBar>,
     show_project_panel: bool,
     show_collab_panel: bool,
     show_chat_panel: bool,
@@ -24,8 +25,9 @@ pub struct Workspace {
 }
 
 impl Workspace {
-    pub fn new() -> Self {
+    pub fn new(cx: &mut ViewContext<Self>) -> Self {
         Self {
+            title_bar: TitleBar::view(cx),
             show_project_panel: true,
             show_collab_panel: false,
             show_chat_panel: true,
@@ -106,7 +108,7 @@ impl Workspace {
     }
 
     pub fn view(cx: &mut WindowContext) -> View<Self> {
-        view(cx.entity(|cx| Self::new()), Self::render)
+        view(cx.entity(|cx| Self::new(cx)), Self::render)
     }
 
     pub fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
@@ -167,10 +169,7 @@ impl Workspace {
             .items_start()
             .text_color(theme.lowest.base.default.foreground)
             .fill(theme.lowest.base.default.background)
-            .child(TitleBar::new(cx).set_livestream(Some(Livestream {
-                players: random_players_with_call_status(7),
-                channel: Some("gpui2-ui".to_string()),
-            })))
+            .child(self.title_bar.clone())
             .child(
                 div()
                     .flex_1()