diff --git a/crates/gpui3/src/active.rs b/crates/gpui3/src/active.rs index 707e83e587..93cdb9d8bb 100644 --- a/crates/gpui3/src/active.rs +++ b/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, 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, + f: impl FnOnce(StyleRefinement) -> StyleRefinement, + ) -> Self + where + Self: Sized, + { + self.set_active_style(Some(group_name.into()), f(StyleRefinement::default())); self } } diff --git a/crates/gpui3/src/elements/div.rs b/crates/gpui3/src/elements/div.rs index 09cf0ec96b..8b6785eddb 100644 --- a/crates/gpui3/src/elements/div.rs +++ b/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, style: StyleRefinement) { + if let Some(group) = group { + self.group_hover = Some(GroupStyle { group, style }); + } else { + self.hover_style = style; + } } } @@ -465,8 +469,12 @@ impl Active for Div 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, style: StyleRefinement) { + if let Some(group) = group { + self.group_active = Some(GroupStyle { group, style }); + } else { + self.active_style = style; + } } } diff --git a/crates/gpui3/src/elements/img.rs b/crates/gpui3/src/elements/img.rs index 7b1f374b9b..e7775fc434 100644 --- a/crates/gpui3/src/elements/img.rs +++ b/crates/gpui3/src/elements/img.rs @@ -90,7 +90,7 @@ where element_state: &mut Self::ElementState, cx: &mut ViewContext, ) { - 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, style: StyleRefinement) { + self.base.set_hover_style(group, style); } } @@ -157,7 +157,7 @@ impl Active for Img 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, style: StyleRefinement) { + self.base.set_active_style(group, style) } } diff --git a/crates/gpui3/src/elements/svg.rs b/crates/gpui3/src/elements/svg.rs index cc511c3fb7..7ccd2a2c68 100644 --- a/crates/gpui3/src/elements/svg.rs +++ b/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, style: StyleRefinement) { + self.base.set_hover_style(group, style); } } @@ -132,7 +132,7 @@ impl Active for Svg 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, style: StyleRefinement) { + self.base.set_active_style(group, style) } } diff --git a/crates/gpui3/src/hover.rs b/crates/gpui3/src/hover.rs index 7c47eda84d..f69cd84f65 100644 --- a/crates/gpui3/src/hover.rs +++ b/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, 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, + f: impl FnOnce(StyleRefinement) -> StyleRefinement, + ) -> Self + where + Self: Sized, + { + self.set_hover_style(Some(group_name.into()), f(StyleRefinement::default())); self } } diff --git a/crates/gpui3/src/style.rs b/crates/gpui3/src/style.rs index f472e05c91..eb2330fc16 100644 --- a/crates/gpui3/src/style.rs +++ b/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, } +impl Styled for StyleRefinement { + fn style(&mut self) -> &mut StyleRefinement { + self + } +} + #[derive(Clone, Debug)] pub struct BoxShadow { pub color: Hsla, diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index 42786c0033..7ca09e3698 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -1167,7 +1167,13 @@ impl From for ElementId { } impl From 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()) } } diff --git a/crates/storybook2/src/collab_panel.rs b/crates/storybook2/src/collab_panel.rs index ab1bd6a157..8f2eb14a54 100644 --- a/crates/storybook2/src/collab_panel.rs +++ b/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), ) diff --git a/crates/storybook2/src/stories/text.rs b/crates/storybook2/src/stories/text.rs index 1f35d63725..1f461ed569 100644 --- a/crates/storybook2/src/stories/text.rs +++ b/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<()>, diff --git a/crates/storybook2/src/stories/z_index.rs b/crates/storybook2/src/stories/z_index.rs index 074d523e25..fda3cf5d28 100644 --- a/crates/storybook2/src/stories/z_index.rs +++ b/crates/storybook2/src/stories/z_index.rs @@ -59,7 +59,7 @@ impl ZIndexStory { } } -trait Styles: StyleHelpers { +trait Styles: Styled + Sized { // Trailing `_` is so we don't collide with `block` style `StyleHelpers`. fn block_(self) -> Self { self.absolute() diff --git a/crates/storybook2/src/workspace.rs b/crates/storybook2/src/workspace.rs index 29c098297c..2d32c3b8c1 100644 --- a/crates/storybook2/src/workspace.rs +++ b/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)), ), ) } diff --git a/crates/ui2/src/components/breadcrumb.rs b/crates/ui2/src/components/breadcrumb.rs index aa1327b7ac..58a9f76759 100644 --- a/crates/ui2/src/components/breadcrumb.rs +++ b/crates/ui2/src/components/breadcrumb.rs @@ -31,7 +31,11 @@ impl Breadcrumb { .text_color(HighlightColor::Default.hsla(theme)) } - fn render(&mut self, view_state: &mut S, cx: &mut ViewContext) -> impl Element { + fn render( + &mut self, + view_state: &mut S, + cx: &mut ViewContext, + ) -> impl Element { let theme = theme(cx); let symbols_len = self.symbols.len(); @@ -43,8 +47,7 @@ impl Breadcrumb { .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) -> impl Element { + fn render( + &mut self, + view_state: &mut S, + cx: &mut ViewContext, + ) -> impl Element { let theme = theme(cx); Story::container(cx) diff --git a/crates/ui2/src/components/collab_panel.rs b/crates/ui2/src/components/collab_panel.rs index 0e268664a9..7512707de7 100644 --- a/crates/ui2/src/components/collab_panel.rs +++ b/crates/ui2/src/components/collab_panel.rs @@ -137,10 +137,8 @@ impl CollabPanel { .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() diff --git a/crates/ui2/src/components/icon_button.rs b/crates/ui2/src/components/icon_button.rs index cf8110e1e4..f7562cbeec 100644 --- a/crates/ui2/src/components/icon_button.rs +++ b/crates/ui2/src/components/icon_button.rs @@ -91,8 +91,7 @@ impl IconButton { .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)) diff --git a/crates/ui2/src/components/list.rs b/crates/ui2/src/components/list.rs index 5093097e6b..d02740aa55 100644 --- a/crates/ui2/src/components/list.rs +++ b/crates/ui2/src/components/list.rs @@ -412,8 +412,7 @@ impl ListEntry { .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()) diff --git a/crates/ui2/src/components/notification.rs b/crates/ui2/src/components/notification.rs index 97ceb714a3..724571496f 100644 --- a/crates/ui2/src/components/notification.rs +++ b/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, diff --git a/crates/ui2/src/components/palette.rs b/crates/ui2/src/components/palette.rs index dad7ef06c3..08c8c93e98 100644 --- a/crates/ui2/src/components/palette.rs +++ b/crates/ui2/src/components/palette.rs @@ -89,8 +89,7 @@ impl Palette { .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) -> impl Element { + fn render( + &mut self, + _view: &mut S, + cx: &mut ViewContext, + ) -> impl Element { Story::container(cx) .child(Story::title_for::<_, Palette>(cx)) .child(Story::label(cx, "Default")) diff --git a/crates/ui2/src/elements/input.rs b/crates/ui2/src/elements/input.rs index ef144c201e..f80fdd9517 100644 --- a/crates/ui2/src/elements/input.rs +++ b/crates/ui2/src/elements/input.rs @@ -88,8 +88,9 @@ impl Input { .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))