Actually get it compiling, omg

Mikayla created

Change summary

crates/collab_ui/src/collab_panel.rs  | 38 ++++++++----
crates/gpui/examples/components.rs    |  4 
crates/gpui/src/elements.rs           |  7 ++
crates/gpui/src/elements/component.rs | 85 ++++++++++++++++++++++++++--
crates/search/src/search.rs           |  4 
crates/theme/src/components.rs        | 34 ++++++-----
6 files changed, 131 insertions(+), 41 deletions(-)

Detailed changes

crates/collab_ui/src/collab_panel.rs 🔗

@@ -8,7 +8,6 @@ use client::{
     proto::PeerId, Channel, ChannelEvent, ChannelId, ChannelStore, Client, Contact, User, UserStore,
 };
 
-use components::DisclosureExt;
 use context_menu::{ContextMenu, ContextMenuItem};
 use db::kvp::KEY_VALUE_STORE;
 use editor::{Cancel, Editor};
@@ -17,8 +16,9 @@ use fuzzy::{match_strings, StringMatchCandidate};
 use gpui::{
     actions,
     elements::{
-        Canvas, ChildView, Component, Empty, Flex, Image, Label, List, ListOffset, ListState,
-        MouseEventHandler, Orientation, OverlayPositionMode, Padding, ParentElement, Stack, Svg,
+        Canvas, ChildView, Empty, Flex, GeneralComponent, GeneralStyleableComponent, Image, Label,
+        List, ListOffset, ListState, MouseEventHandler, Orientation, OverlayPositionMode, Padding,
+        ParentElement, Stack, Svg,
     },
     geometry::{
         rect::RectF,
@@ -44,7 +44,10 @@ use workspace::{
     Workspace,
 };
 
-use crate::face_pile::FacePile;
+use crate::{
+    collab_panel::components::{DisclosureExt, DisclosureStyle},
+    face_pile::FacePile,
+};
 use channel_modal::ChannelModal;
 
 use self::contact_finder::ContactFinder;
@@ -1616,10 +1619,17 @@ impl CollabPanel {
             this.deploy_channel_context_menu(Some(e.position), channel_id, cx);
         })
         .with_cursor_style(CursorStyle::PointingHand)
-        .component()
-        .styleable()
-        .disclosable()
-        .into_element()
+        .dynamic_component()
+        .stylable()
+        .disclosable(true, Box::new(RemoveChannel { channel_id: 0 }))
+        .with_style({
+            fn style() -> DisclosureStyle<()> {
+                todo!()
+            }
+
+            style()
+        })
+        .element()
         .into_any()
     }
 
@@ -2531,7 +2541,7 @@ fn render_icon_button(style: &IconButton, svg_path: &'static str) -> impl Elemen
 mod components {
 
     use gpui::{
-        elements::{Empty, Flex, GeneralComponent, ParentElement, StyleableComponent},
+        elements::{Empty, Flex, GeneralComponent, GeneralStyleableComponent, ParentElement},
         Action, Element,
     };
     use theme::components::{
@@ -2539,13 +2549,13 @@ mod components {
     };
 
     #[derive(Clone)]
-    struct DisclosureStyle<S> {
+    pub struct DisclosureStyle<S> {
         disclosure: ToggleIconButtonStyle,
         spacing: f32,
         content: S,
     }
 
-    struct Disclosable<C, S> {
+    pub struct Disclosable<C, S> {
         disclosed: bool,
         action: Box<dyn Action>,
         content: C,
@@ -2563,7 +2573,7 @@ mod components {
         }
     }
 
-    impl<C: StyleableComponent> StyleableComponent for Disclosable<C, ()> {
+    impl<C: GeneralStyleableComponent> GeneralStyleableComponent for Disclosable<C, ()> {
         type Style = DisclosureStyle<C::Style>;
 
         type Output = Disclosable<C, Self::Style>;
@@ -2578,7 +2588,7 @@ mod components {
         }
     }
 
-    impl<C: StyleableComponent> GeneralComponent for Disclosable<C, DisclosureStyle<C::Style>> {
+    impl<C: GeneralStyleableComponent> GeneralComponent for Disclosable<C, DisclosureStyle<C::Style>> {
         fn render<V: gpui::View>(
             self,
             v: &mut V,
@@ -2605,7 +2615,7 @@ mod components {
             Self: Sized;
     }
 
-    impl<C: StyleableComponent> DisclosureExt for C {
+    impl<C: GeneralStyleableComponent> DisclosureExt for C {
         fn disclosable(self, disclosed: bool, action: Box<dyn Action>) -> Disclosable<Self, ()> {
             Disclosable::new(disclosed, self, action)
         }

crates/gpui/examples/components.rs 🔗

@@ -72,7 +72,7 @@ impl View for TestView {
                         TextStyle::for_color(Color::blue()),
                     )
                     .with_style(ButtonStyle::fill(Color::yellow()))
-                    .element(),
+                    .c_element(),
                 )
                 .with_child(
                     ToggleableButton::new(self.is_doubling, move |_, v: &mut Self, cx| {
@@ -84,7 +84,7 @@ impl View for TestView {
                         inactive: ButtonStyle::fill(Color::red()),
                         active: ButtonStyle::fill(Color::green()),
                     })
-                    .element(),
+                    .c_element(),
                 )
                 .expanded()
                 .contained()

crates/gpui/src/elements.rs 🔗

@@ -236,6 +236,13 @@ pub trait Element<V: View>: 'static {
     {
         ElementAdapter::new(self.into_any())
     }
+
+    fn dynamic_component(self) -> DynamicElementAdapter
+    where
+        Self: Sized,
+    {
+        DynamicElementAdapter::new(self.into_any())
+    }
 }
 
 pub trait RenderElement {

crates/gpui/src/elements/component.rs 🔗

@@ -1,4 +1,4 @@
-use std::marker::PhantomData;
+use std::{any::Any, marker::PhantomData};
 
 use pathfinder_geometry::{rect::RectF, vector::Vector2F};
 
@@ -11,15 +11,43 @@ use super::Empty;
 
 pub trait GeneralComponent {
     fn render<V: View>(self, v: &mut V, cx: &mut ViewContext<V>) -> AnyElement<V>;
+
     fn element<V: View>(self) -> ComponentAdapter<V, Self>
     where
         Self: Sized,
     {
         ComponentAdapter::new(self)
     }
+
+    fn stylable(self) -> GeneralStylableComponentAdapter<Self>
+    where
+        Self: Sized,
+    {
+        GeneralStylableComponentAdapter::new(self)
+    }
+}
+
+pub struct GeneralStylableComponentAdapter<C: GeneralComponent> {
+    component: C,
+}
+
+impl<C: GeneralComponent> GeneralStylableComponentAdapter<C> {
+    pub fn new(component: C) -> Self {
+        Self { component }
+    }
+}
+
+impl<C: GeneralComponent> GeneralStyleableComponent for GeneralStylableComponentAdapter<C> {
+    type Style = ();
+
+    type Output = C;
+
+    fn with_style(self, _: Self::Style) -> Self::Output {
+        self.component
+    }
 }
 
-pub trait StyleableComponent {
+pub trait GeneralStyleableComponent {
     type Style: Clone;
     type Output: GeneralComponent;
 
@@ -32,7 +60,7 @@ impl GeneralComponent for () {
     }
 }
 
-impl StyleableComponent for () {
+impl GeneralStyleableComponent for () {
     type Style = ();
     type Output = ();
 
@@ -41,17 +69,34 @@ impl StyleableComponent for () {
     }
 }
 
+pub trait StyleableComponent<V: View> {
+    type Style: Clone;
+    type Output: Component<V>;
+
+    fn c_with_style(self, style: Self::Style) -> Self::Output;
+}
+
+impl<V: View, C: GeneralStyleableComponent> StyleableComponent<V> for C {
+    type Style = C::Style;
+
+    type Output = C::Output;
+
+    fn c_with_style(self, style: Self::Style) -> Self::Output {
+        self.with_style(style)
+    }
+}
+
 pub trait Component<V: View> {
     fn render(self, v: &mut V, cx: &mut ViewContext<V>) -> AnyElement<V>;
 
-    fn element(self) -> ComponentAdapter<V, Self>
+    fn c_element(self) -> ComponentAdapter<V, Self>
     where
         Self: Sized,
     {
         ComponentAdapter::new(self)
     }
 
-    fn styleable(self) -> StylableComponentAdapter<Self, V>
+    fn c_styleable(self) -> StylableComponentAdapter<Self, V>
     where
         Self: Sized,
     {
@@ -65,7 +110,7 @@ impl<V: View, C: GeneralComponent> Component<V> for C {
     }
 }
 
-// StylableComponent -> GeneralComponent
+// StylableComponent -> Component
 pub struct StylableComponentAdapter<C: Component<V>, V: View> {
     component: C,
     phantom: std::marker::PhantomData<V>,
@@ -80,16 +125,40 @@ impl<C: Component<V>, V: View> StylableComponentAdapter<C, V> {
     }
 }
 
-impl<C: GeneralComponent, V: View> StyleableComponent for StylableComponentAdapter<C, V> {
+impl<C: Component<V>, V: View> StyleableComponent<V> for StylableComponentAdapter<C, V> {
     type Style = ();
 
     type Output = C;
 
-    fn with_style(self, _: Self::Style) -> Self::Output {
+    fn c_with_style(self, _: Self::Style) -> Self::Output {
         self.component
     }
 }
 
+// Element -> GeneralComponent
+
+pub struct DynamicElementAdapter {
+    element: Box<dyn Any>,
+}
+
+impl DynamicElementAdapter {
+    pub fn new<V: View>(element: AnyElement<V>) -> Self {
+        DynamicElementAdapter {
+            element: Box::new(element) as Box<dyn Any>,
+        }
+    }
+}
+
+impl GeneralComponent for DynamicElementAdapter {
+    fn render<V: View>(self, _: &mut V, _: &mut ViewContext<V>) -> AnyElement<V> {
+        let element = self
+            .element
+            .downcast::<AnyElement<V>>()
+            .expect("Don't move elements out of their view :(");
+        *element
+    }
+}
+
 // Element -> Component
 pub struct ElementAdapter<V: View> {
     element: AnyElement<V>,

crates/search/src/search.rs 🔗

@@ -2,7 +2,7 @@ use bitflags::bitflags;
 pub use buffer_search::BufferSearchBar;
 use gpui::{
     actions,
-    elements::{Component, StyleableComponent, TooltipStyle},
+    elements::{Component, GeneralStyleableComponent, TooltipStyle},
     Action, AnyElement, AppContext, Element, View,
 };
 pub use mode::SearchMode;
@@ -96,7 +96,7 @@ impl SearchOptions {
             .with_contents(Svg::new(self.icon()))
             .toggleable(active)
             .with_style(button_style)
-            .element()
+            .c_element()
             .into_any()
     }
 }

crates/theme/src/components.rs 🔗

@@ -1,4 +1,4 @@
-use gpui::elements::StyleableComponent;
+use gpui::elements::GeneralStyleableComponent;
 
 use crate::{Interactive, Toggleable};
 
@@ -6,18 +6,18 @@ use self::{action_button::ButtonStyle, svg::SvgStyle, toggle::Toggle};
 
 pub type ToggleIconButtonStyle = Toggleable<Interactive<ButtonStyle<SvgStyle>>>;
 
-pub trait ComponentExt<C: StyleableComponent> {
+pub trait ComponentExt<C: GeneralStyleableComponent> {
     fn toggleable(self, active: bool) -> Toggle<C, ()>;
 }
 
-impl<C: StyleableComponent> ComponentExt<C> for C {
+impl<C: GeneralStyleableComponent> ComponentExt<C> for C {
     fn toggleable(self, active: bool) -> Toggle<C, ()> {
         Toggle::new(self, active)
     }
 }
 
 pub mod toggle {
-    use gpui::elements::{GeneralComponent, StyleableComponent};
+    use gpui::elements::{GeneralComponent, GeneralStyleableComponent};
 
     use crate::Toggleable;
 
@@ -27,7 +27,7 @@ pub mod toggle {
         component: C,
     }
 
-    impl<C: StyleableComponent> Toggle<C, ()> {
+    impl<C: GeneralStyleableComponent> Toggle<C, ()> {
         pub fn new(component: C, active: bool) -> Self {
             Toggle {
                 active,
@@ -37,7 +37,7 @@ pub mod toggle {
         }
     }
 
-    impl<C: StyleableComponent> StyleableComponent for Toggle<C, ()> {
+    impl<C: GeneralStyleableComponent> GeneralStyleableComponent for Toggle<C, ()> {
         type Style = Toggleable<C::Style>;
 
         type Output = Toggle<C, Self::Style>;
@@ -51,7 +51,7 @@ pub mod toggle {
         }
     }
 
-    impl<C: StyleableComponent> GeneralComponent for Toggle<C, Toggleable<C::Style>> {
+    impl<C: GeneralStyleableComponent> GeneralComponent for Toggle<C, Toggleable<C::Style>> {
         fn render<V: gpui::View>(
             self,
             v: &mut V,
@@ -69,7 +69,8 @@ pub mod action_button {
 
     use gpui::{
         elements::{
-            ContainerStyle, GeneralComponent, MouseEventHandler, StyleableComponent, TooltipStyle,
+            ContainerStyle, GeneralComponent, GeneralStyleableComponent, MouseEventHandler,
+            TooltipStyle,
         },
         platform::{CursorStyle, MouseButton},
         Action, Element, TypeTag, View,
@@ -121,7 +122,10 @@ pub mod action_button {
             self
         }
 
-        pub fn with_contents<C: StyleableComponent>(self, contents: C) -> ActionButton<C, ()> {
+        pub fn with_contents<C: GeneralStyleableComponent>(
+            self,
+            contents: C,
+        ) -> ActionButton<C, ()> {
             ActionButton {
                 action: self.action,
                 tag: self.tag,
@@ -132,7 +136,7 @@ pub mod action_button {
         }
     }
 
-    impl<C: StyleableComponent> StyleableComponent for ActionButton<C, ()> {
+    impl<C: GeneralStyleableComponent> GeneralStyleableComponent for ActionButton<C, ()> {
         type Style = Interactive<ButtonStyle<C::Style>>;
         type Output = ActionButton<C, ButtonStyle<C::Style>>;
 
@@ -148,7 +152,7 @@ pub mod action_button {
         }
     }
 
-    impl<C: StyleableComponent> GeneralComponent for ActionButton<C, ButtonStyle<C::Style>> {
+    impl<C: GeneralStyleableComponent> GeneralComponent for ActionButton<C, ButtonStyle<C::Style>> {
         fn render<V: View>(self, v: &mut V, cx: &mut gpui::ViewContext<V>) -> gpui::AnyElement<V> {
             let mut button = MouseEventHandler::new_dynamic(self.tag, 0, cx, |state, cx| {
                 let style = self.style.style_for(state);
@@ -195,7 +199,7 @@ pub mod svg {
     use std::borrow::Cow;
 
     use gpui::{
-        elements::{GeneralComponent, StyleableComponent},
+        elements::{GeneralComponent, GeneralStyleableComponent},
         Element,
     };
     use schemars::JsonSchema;
@@ -261,7 +265,7 @@ pub mod svg {
         }
     }
 
-    impl StyleableComponent for Svg<()> {
+    impl GeneralStyleableComponent for Svg<()> {
         type Style = SvgStyle;
 
         type Output = Svg<SvgStyle>;
@@ -294,7 +298,7 @@ pub mod label {
     use std::borrow::Cow;
 
     use gpui::{
-        elements::{GeneralComponent, LabelStyle, StyleableComponent},
+        elements::{GeneralComponent, GeneralStyleableComponent, LabelStyle},
         Element,
     };
 
@@ -312,7 +316,7 @@ pub mod label {
         }
     }
 
-    impl StyleableComponent for Label<()> {
+    impl GeneralStyleableComponent for Label<()> {
         type Style = LabelStyle;
 
         type Output = Label<LabelStyle>;