Checkpoint

Antonio Scandurra created

Change summary

crates/gpui3/src/active.rs                | 18 +++++++++++--
crates/gpui3/src/elements/div.rs          | 32 +++++++++++++++---------
crates/gpui3/src/elements/img.rs          | 10 +++---
crates/gpui3/src/elements/svg.rs          |  8 +++---
crates/gpui3/src/hover.rs                 | 18 +++++++++++--
crates/gpui3/src/style.rs                 |  8 +++++
crates/gpui3/src/window.rs                | 10 ++++++-
crates/storybook2/src/collab_panel.rs     | 22 ++++++++--------
crates/storybook2/src/stories/text.rs     |  2 
crates/storybook2/src/stories/z_index.rs  |  2 
crates/storybook2/src/workspace.rs        | 10 +++---
crates/ui2/src/components/breadcrumb.rs   | 15 ++++++++---
crates/ui2/src/components/collab_panel.rs |  6 +---
crates/ui2/src/components/icon_button.rs  |  3 -
crates/ui2/src/components/list.rs         |  3 -
crates/ui2/src/components/notification.rs |  2 
crates/ui2/src/components/palette.rs      |  9 ++++--
crates/ui2/src/elements/input.rs          |  5 ++-
18 files changed, 117 insertions(+), 66 deletions(-)

Detailed changes

crates/gpui3/src/active.rs 🔗

@@ -1,13 +1,25 @@
-use crate::StyleRefinement;
+use crate::{SharedString, StyleRefinement};
 
 pub trait Active {
-    fn set_active_style(&mut self, style: StyleRefinement);
+    fn set_active_style(&mut self, group_name: Option<SharedString>, style: StyleRefinement);
 
     fn active(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
     where
         Self: Sized,
     {
-        self.set_active_style(f(StyleRefinement::default()));
+        self.set_active_style(None, f(StyleRefinement::default()));
+        self
+    }
+
+    fn group_active(
+        mut self,
+        group_name: impl Into<SharedString>,
+        f: impl FnOnce(StyleRefinement) -> StyleRefinement,
+    ) -> Self
+    where
+        Self: Sized,
+    {
+        self.set_active_style(Some(group_name.into()), f(StyleRefinement::default()));
         self
     }
 }

crates/gpui3/src/elements/div.rs 🔗

@@ -386,16 +386,16 @@ where
                     );
                     this.paint_event_listeners(bounds, element_state.pending_click.clone(), cx);
                 });
-            });
 
-            style.apply_text_style(cx, |cx| {
-                style.apply_overflow(bounds, cx, |cx| {
-                    cx.stack(z_index + 1, |cx| {
-                        for child in &mut this.children {
-                            child.paint(view_state, None, cx);
-                        }
+                cx.stack(1, |cx| {
+                    style.apply_text_style(cx, |cx| {
+                        style.apply_overflow(bounds, cx, |cx| {
+                            for child in &mut this.children {
+                                child.paint(view_state, None, cx);
+                            }
+                        })
                     })
-                })
+                });
             });
 
             if let Some(group) = this.group.as_ref() {
@@ -454,8 +454,12 @@ where
     V: 'static + Send + Sync,
     K: ElementIdentity,
 {
-    fn set_hover_style(&mut self, style: StyleRefinement) {
-        self.hover_style = style;
+    fn set_hover_style(&mut self, group: Option<SharedString>, style: StyleRefinement) {
+        if let Some(group) = group {
+            self.group_hover = Some(GroupStyle { group, style });
+        } else {
+            self.hover_style = style;
+        }
     }
 }
 
@@ -465,8 +469,12 @@ impl<V> Active for Div<V, IdentifiedElement>
 where
     V: 'static + Send + Sync,
 {
-    fn set_active_style(&mut self, style: StyleRefinement) {
-        self.active_style = style;
+    fn set_active_style(&mut self, group: Option<SharedString>, style: StyleRefinement) {
+        if let Some(group) = group {
+            self.group_active = Some(GroupStyle { group, style });
+        } else {
+            self.active_style = style;
+        }
     }
 }
 

crates/gpui3/src/elements/img.rs 🔗

@@ -90,7 +90,7 @@ where
         element_state: &mut Self::ElementState,
         cx: &mut ViewContext<Self::ViewState>,
     ) {
-        cx.stack(1, |cx| {
+        cx.stack(0, |cx| {
             self.base.paint(bounds, view, element_state, cx);
         });
 
@@ -146,8 +146,8 @@ where
     V: 'static + Send + Sync,
     K: ElementIdentity,
 {
-    fn set_hover_style(&mut self, style: StyleRefinement) {
-        self.base.set_hover_style(style);
+    fn set_hover_style(&mut self, group: Option<SharedString>, style: StyleRefinement) {
+        self.base.set_hover_style(group, style);
     }
 }
 
@@ -157,7 +157,7 @@ impl<V> Active for Img<V, IdentifiedElement>
 where
     V: 'static + Send + Sync,
 {
-    fn set_active_style(&mut self, style: StyleRefinement) {
-        self.base.set_active_style(style)
+    fn set_active_style(&mut self, group: Option<SharedString>, style: StyleRefinement) {
+        self.base.set_active_style(group, style)
     }
 }

crates/gpui3/src/elements/svg.rs 🔗

@@ -121,8 +121,8 @@ where
     V: 'static + Send + Sync,
     K: ElementIdentity,
 {
-    fn set_hover_style(&mut self, style: StyleRefinement) {
-        self.base.set_hover_style(style);
+    fn set_hover_style(&mut self, group: Option<SharedString>, style: StyleRefinement) {
+        self.base.set_hover_style(group, style);
     }
 }
 
@@ -132,7 +132,7 @@ impl<V> Active for Svg<V, IdentifiedElement>
 where
     V: 'static + Send + Sync,
 {
-    fn set_active_style(&mut self, style: StyleRefinement) {
-        self.base.set_active_style(style)
+    fn set_active_style(&mut self, group: Option<SharedString>, style: StyleRefinement) {
+        self.base.set_active_style(group, style)
     }
 }

crates/gpui3/src/hover.rs 🔗

@@ -1,13 +1,25 @@
-use crate::StyleRefinement;
+use crate::{SharedString, StyleRefinement};
 
 pub trait Hover {
-    fn set_hover_style(&mut self, style: StyleRefinement);
+    fn set_hover_style(&mut self, group_name: Option<SharedString>, style: StyleRefinement);
 
     fn hover(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
     where
         Self: Sized,
     {
-        self.set_hover_style(f(StyleRefinement::default()));
+        self.set_hover_style(None, f(StyleRefinement::default()));
+        self
+    }
+
+    fn group_hover(
+        mut self,
+        group_name: impl Into<SharedString>,
+        f: impl FnOnce(StyleRefinement) -> StyleRefinement,
+    ) -> Self
+    where
+        Self: Sized,
+    {
+        self.set_hover_style(Some(group_name.into()), f(StyleRefinement::default()));
         self
     }
 }

crates/gpui3/src/style.rs 🔗

@@ -2,7 +2,7 @@ use crate::{
     black, phi, point, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds, ContentMask,
     Corners, CornersRefinement, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures,
     FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems, Result,
-    SharedString, Size, SizeRefinement, TextRun, ViewContext, WindowContext,
+    SharedString, Size, SizeRefinement, Styled, TextRun, ViewContext, WindowContext,
 };
 use refineable::{Cascade, Refineable};
 use smallvec::SmallVec;
@@ -101,6 +101,12 @@ pub struct Style {
     pub z_index: Option<u32>,
 }
 
+impl Styled for StyleRefinement {
+    fn style(&mut self) -> &mut StyleRefinement {
+        self
+    }
+}
+
 #[derive(Clone, Debug)]
 pub struct BoxShadow {
     pub color: Hsla,

crates/gpui3/src/window.rs 🔗

@@ -1167,7 +1167,13 @@ impl From<i32> for ElementId {
 }
 
 impl From<SharedString> for ElementId {
-    fn from(id: SharedString) -> Self {
-        ElementId::Name(id)
+    fn from(name: SharedString) -> Self {
+        ElementId::Name(name)
+    }
+}
+
+impl From<&'static str> for ElementId {
+    fn from(name: &'static str) -> Self {
+        ElementId::Name(name.into())
     }
 }

crates/storybook2/src/collab_panel.rs 🔗

@@ -1,6 +1,6 @@
 use gpui3::{
-    div, svg, view, AppContext, Context, Element, ElementId, IntoAnyElement, ParentElement,
-    ScrollState, SharedString, StyleHelpers, Styled, View, ViewContext, WindowContext,
+    div, svg, view, Active, AppContext, Context, Element, ElementId, Hover, IntoAnyElement,
+    ParentElement, ScrollState, SharedString, Styled, View, ViewContext, WindowContext,
 };
 use ui::{theme, Theme};
 
@@ -132,8 +132,7 @@ impl CollabPanel {
             .flex()
             .justify_between()
             .items_center()
-            .active()
-            .fill(theme.highest.accent.default.background)
+            .active(|style| style.fill(theme.highest.accent.default.background))
             .child(div().flex().gap_1().text_sm().child(label))
             .child(
                 div().flex().h_full().gap_1().items_center().child(
@@ -174,18 +173,19 @@ impl CollabPanel {
                     .text_sm()
                     .child(
                         div()
-                            .id(0)
+                            .id("avatar")
                             // .uri(avatar_uri)
                             .size_3p5()
                             .rounded_full()
                             .fill(theme.middle.positive.default.foreground)
                             .shadow()
-                            .group_hover("")
-                            .fill(theme.middle.negative.default.foreground)
-                            .hover()
-                            .fill(theme.middle.warning.default.foreground)
-                            .group_active("")
-                            .fill(theme.middle.accent.default.foreground),
+                            .group_hover("", |style| {
+                                style.fill(theme.middle.negative.default.foreground)
+                            })
+                            .hover(|style| style.fill(theme.middle.warning.default.foreground))
+                            .group_active("", |style| {
+                                style.fill(theme.middle.accent.default.foreground)
+                            }),
                     )
                     .child(label),
             )

crates/storybook2/src/stories/text.rs 🔗

@@ -1,4 +1,4 @@
-use gpui3::{div, view, white, Context, ParentElement, StyleHelpers, View, WindowContext};
+use gpui3::{div, view, white, Context, ParentElement, Styled, View, WindowContext};
 
 pub struct TextStory {
     text: View<()>,

crates/storybook2/src/stories/z_index.rs 🔗

@@ -59,7 +59,7 @@ impl<S: 'static + Send + Sync> ZIndexStory<S> {
     }
 }
 
-trait Styles: StyleHelpers {
+trait Styles: Styled + Sized {
     // Trailing `_` is so we don't collide with `block` style `StyleHelpers`.
     fn block_(self) -> Self {
         self.absolute()

crates/storybook2/src/workspace.rs 🔗

@@ -3,7 +3,7 @@ use crate::{
     themes::rose_pine,
 };
 use gpui3::{
-    div, img, svg, view, Context, Element, ParentElement, StyleHelpers, Styled, View, ViewContext,
+    div, img, svg, view, Context, Element, Hover, ParentElement, Styled, View, ViewContext,
     WindowContext,
 };
 use ui::{theme, themed};
@@ -42,10 +42,10 @@ impl Workspace {
                     div()
                         .size_5()
                         .fill(theme.middle.negative.default.foreground)
-                        .group_hover("")
-                        .fill(theme.middle.positive.default.foreground)
-                        .hover()
-                        .fill(theme.middle.variant.default.foreground),
+                        .group_hover("", |style| {
+                            style.fill(theme.middle.positive.default.foreground)
+                        })
+                        .hover(|style| style.fill(theme.middle.variant.default.foreground)),
                 ),
         )
     }

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

@@ -31,7 +31,11 @@ impl<S: 'static + Send + Sync + Clone> Breadcrumb<S> {
             .text_color(HighlightColor::Default.hsla(theme))
     }
 
-    fn render(&mut self, view_state: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
+    fn render(
+        &mut self,
+        view_state: &mut S,
+        cx: &mut ViewContext<S>,
+    ) -> impl Element<ViewState = S> {
         let theme = theme(cx);
 
         let symbols_len = self.symbols.len();
@@ -43,8 +47,7 @@ impl<S: 'static + Send + Sync + Clone> Breadcrumb<S> {
             .text_sm()
             .text_color(theme.middle.base.default.foreground)
             .rounded_md()
-            .hover()
-            .fill(theme.highest.base.hovered.background)
+            .hover(|style| style.fill(theme.highest.base.hovered.background))
             .child(self.path.clone().to_str().unwrap().to_string())
             .child(if !self.symbols.is_empty() {
                 self.render_separator(&theme)
@@ -99,7 +102,11 @@ mod stories {
             }
         }
 
-        fn render(&mut self, view_state: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
+        fn render(
+            &mut self,
+            view_state: &mut S,
+            cx: &mut ViewContext<S>,
+        ) -> impl Element<ViewState = S> {
             let theme = theme(cx);
 
             Story::container(cx)

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

@@ -137,10 +137,8 @@ impl<S: 'static + Send + Sync + Clone> CollabPanel<S> {
             .px_2()
             .flex()
             .items_center()
-            .hover()
-            .fill(theme.lowest.variant.hovered.background)
-            // .active()
-            // .fill(theme.lowest.variant.pressed.background)
+            .hover(|style| style.fill(theme.lowest.variant.hovered.background))
+            // .active(|style| style.fill(theme.lowest.variant.pressed.background))
             .child(
                 div()
                     .flex()

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

@@ -91,8 +91,7 @@ impl<S: 'static + Send + Sync> IconButton<S> {
             .items_center()
             .justify_center()
             .rounded_md()
-            .hover()
-            .fill(theme.highest.base.hovered.background)
+            .hover(|style| style.fill(theme.highest.base.hovered.background))
             // .active()
             // .fill(theme.highest.base.pressed.background)
             .child(IconElement::new(self.icon).color(icon_color))

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

@@ -412,8 +412,7 @@ impl<S: 'static + Send + Sync + Clone> ListEntry<S> {
                             .h_full()
                             .flex()
                             .justify_center()
-                            .group_hover("")
-                            .fill(color.border_focused)
+                            .group_hover("", |style| style.fill(color.border_focused))
                             .child(
                                 h_stack()
                                     .child(div().w_px().h_full())

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

@@ -1,6 +1,6 @@
 use std::marker::PhantomData;
 
-use gpui3::{Element, ParentElement, ViewContext};
+use gpui3::{Element, ParentElement, Styled, ViewContext};
 
 use crate::{
     h_stack, v_stack, Button, Icon, IconButton, IconElement, Label, ThemeColor, Toast, ToastOrigin,

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

@@ -89,8 +89,7 @@ impl<S: 'static + Send + Sync + Clone> Palette<S> {
                                     .px_2()
                                     .py_0p5()
                                     .rounded_lg()
-                                    .hover()
-                                    .fill(theme.lowest.base.hovered.background)
+                                    .hover(|style| style.fill(theme.lowest.base.hovered.background))
                                     // .active()
                                     // .fill(theme.lowest.base.pressed.background)
                                     .child(item.clone())
@@ -172,7 +171,11 @@ mod stories {
             }
         }
 
-        fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
+        fn render(
+            &mut self,
+            _view: &mut S,
+            cx: &mut ViewContext<S>,
+        ) -> impl Element<ViewState = S> {
             Story::container(cx)
                 .child(Story::title_for::<_, Palette<S>>(cx))
                 .child(Story::label(cx, "Default"))

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

@@ -88,8 +88,9 @@ impl<S: 'static + Send + Sync> Input<S> {
             .border()
             .border_color(border_color_default)
             .fill(background_color_default)
-            .hover(|h| {
-                h.border_color(border_color_hover)
+            .hover(|style| {
+                style
+                    .border_color(border_color_hover)
                     .fill(background_color_active)
             })
             // .active(|a| .border_color(border_color_active))