Detailed changes
@@ -7,8 +7,8 @@ use editor::{Editor, EditorElement, EditorStyle};
use feature_flags::{AgentV2FeatureFlag, FeatureFlagViewExt as _};
use gpui::{
AnyElement, App, Context, Entity, EventEmitter, FocusHandle, Focusable, FontStyle, ListState,
- Pixels, Render, SharedString, TextStyle, WeakEntity, Window, actions, linear_color_stop,
- linear_gradient, list, prelude::*, px, relative, rems,
+ Pixels, Render, SharedString, TextStyle, WeakEntity, Window, actions, list, prelude::*, px,
+ relative, rems,
};
use menu::{Cancel, Confirm, SelectFirst, SelectLast, SelectNext, SelectPrevious};
use project::Event as ProjectEvent;
@@ -18,8 +18,8 @@ use std::mem;
use theme::{ActiveTheme, ThemeSettings};
use ui::utils::TRAFFIC_LIGHT_PADDING;
use ui::{
- AgentThreadStatus, HighlightedLabel, IconButtonShape, KeyBinding, ListItem, Tab, ThreadItem,
- Tooltip, WithScrollbar, prelude::*,
+ AgentThreadStatus, GradientFade, HighlightedLabel, IconButtonShape, KeyBinding, ListItem, Tab,
+ ThreadItem, Tooltip, WithScrollbar, prelude::*,
};
use util::path_list::PathList;
use workspace::{
@@ -803,33 +803,13 @@ impl Sidebar {
};
let color = cx.theme().colors();
- let base_bg = color.panel_background;
- let gradient_overlay = div()
- .id("gradient_overlay")
- .absolute()
- .top_0()
- .right_0()
- .w_12()
- .h_full()
- .bg(linear_gradient(
- 90.,
- linear_color_stop(base_bg, 0.6),
- linear_color_stop(base_bg.opacity(0.0), 0.),
- ))
- .group_hover(group_name.clone(), |s| {
- s.bg(linear_gradient(
- 90.,
- linear_color_stop(color.element_hover, 0.6),
- linear_color_stop(color.element_hover.opacity(0.0), 0.),
- ))
- })
- .group_active(group_name.clone(), |s| {
- s.bg(linear_gradient(
- 90.,
- linear_color_stop(color.element_active, 0.6),
- linear_color_stop(color.element_active.opacity(0.0), 0.),
- ))
- });
+ let gradient_overlay = GradientFade::new(
+ color.panel_background,
+ color.element_hover,
+ color.element_active,
+ )
+ .width(px(48.0))
+ .group_name(group_name.clone());
ListItem::new(id)
.group_name(group_name)
@@ -12,6 +12,7 @@ mod disclosure;
mod divider;
mod dropdown_menu;
mod facepile;
+mod gradient_fade;
mod group;
mod icon;
mod image;
@@ -54,6 +55,7 @@ pub use disclosure::*;
pub use divider::*;
pub use dropdown_menu::*;
pub use facepile::*;
+pub use gradient_fade::*;
pub use group::*;
pub use icon::*;
pub use image::*;
@@ -1,9 +1,9 @@
use crate::{
- DecoratedIcon, DiffStat, HighlightedLabel, IconDecoration, IconDecorationKind, SpinnerLabel,
- prelude::*,
+ DecoratedIcon, DiffStat, GradientFade, HighlightedLabel, IconDecoration, IconDecorationKind,
+ SpinnerLabel, prelude::*,
};
-use gpui::{AnyView, ClickEvent, Hsla, SharedString, linear_color_stop, linear_gradient};
+use gpui::{AnyView, ClickEvent, Hsla, SharedString};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum AgentThreadStatus {
@@ -220,24 +220,12 @@ impl RenderOnce for ThreadItem {
color.panel_background
};
- let gradient_overlay = div()
- .absolute()
- .top_0()
- .right(px(-10.0))
- .w_8()
- .h_full()
- .bg(linear_gradient(
- 90.,
- linear_color_stop(base_bg, 0.8),
- linear_color_stop(base_bg.opacity(0.0), 0.),
- ))
- .group_hover("thread-item", |s| {
- s.bg(linear_gradient(
- 90.,
- linear_color_stop(color.element_hover, 0.8),
- linear_color_stop(color.element_hover.opacity(0.0), 0.),
- ))
- });
+ let gradient_overlay =
+ GradientFade::new(base_bg, color.element_hover, color.element_active)
+ .width(px(32.0))
+ .right(px(-10.0))
+ .gradient_stop(0.8)
+ .group_name("thread-item");
v_flex()
.id(self.id.clone())
@@ -0,0 +1,88 @@
+use gpui::{Hsla, Pixels, SharedString, linear_color_stop, linear_gradient, px};
+
+use crate::prelude::*;
+
+/// A gradient overlay that fades from a solid color to transparent.
+#[derive(IntoElement)]
+pub struct GradientFade {
+ base_bg: Hsla,
+ hover_bg: Hsla,
+ active_bg: Hsla,
+ width: Pixels,
+ right: Pixels,
+ gradient_stop: f32,
+ group_name: Option<SharedString>,
+}
+
+impl GradientFade {
+ pub fn new(base_bg: Hsla, hover_bg: Hsla, active_bg: Hsla) -> Self {
+ Self {
+ base_bg,
+ hover_bg,
+ active_bg,
+ width: px(48.0),
+ right: px(0.0),
+ gradient_stop: 0.6,
+ group_name: None,
+ }
+ }
+
+ pub fn width(mut self, width: Pixels) -> Self {
+ self.width = width;
+ self
+ }
+
+ pub fn right(mut self, right: Pixels) -> Self {
+ self.right = right;
+ self
+ }
+
+ pub fn gradient_stop(mut self, stop: f32) -> Self {
+ self.gradient_stop = stop;
+ self
+ }
+
+ pub fn group_name(mut self, name: impl Into<SharedString>) -> Self {
+ self.group_name = Some(name.into());
+ self
+ }
+}
+
+impl RenderOnce for GradientFade {
+ fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
+ let stop = self.gradient_stop;
+ let hover_bg = self.hover_bg;
+ let active_bg = self.active_bg;
+
+ div()
+ .id("gradient_fade")
+ .absolute()
+ .top_0()
+ .right(self.right)
+ .w(self.width)
+ .h_full()
+ .bg(linear_gradient(
+ 90.,
+ linear_color_stop(self.base_bg, stop),
+ linear_color_stop(self.base_bg.opacity(0.0), 0.),
+ ))
+ .when_some(self.group_name.clone(), |element, group_name| {
+ element.group_hover(group_name, move |s| {
+ s.bg(linear_gradient(
+ 90.,
+ linear_color_stop(hover_bg, stop),
+ linear_color_stop(hover_bg.opacity(0.0), 0.),
+ ))
+ })
+ })
+ .when_some(self.group_name, |element, group_name| {
+ element.group_active(group_name, move |s| {
+ s.bg(linear_gradient(
+ 90.,
+ linear_color_stop(active_bg, stop),
+ linear_color_stop(active_bg.opacity(0.0), 0.),
+ ))
+ })
+ })
+ }
+}
@@ -1,13 +1,10 @@
use std::sync::Arc;
use component::{Component, ComponentScope, example_group_with_title, single_example};
-use gpui::{
- AnyElement, AnyView, ClickEvent, MouseButton, MouseDownEvent, Pixels, linear_color_stop,
- linear_gradient, px,
-};
+use gpui::{AnyElement, AnyView, ClickEvent, MouseButton, MouseDownEvent, Pixels, px};
use smallvec::SmallVec;
-use crate::{Disclosure, prelude::*};
+use crate::{Disclosure, GradientFade, prelude::*};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
pub enum ListItemSpacing {
@@ -220,34 +217,12 @@ impl RenderOnce for ListItem {
color.panel_background
};
- let end_hover_gradient_overlay = div()
- .id("gradient_overlay")
- .absolute()
- .top_0()
- .right_0()
- .w_24()
- .h_full()
- .bg(linear_gradient(
- 90.,
- linear_color_stop(base_bg, 0.6),
- linear_color_stop(base_bg.opacity(0.0), 0.),
- ))
- .when_some(self.group_name.clone(), |s, group_name| {
- s.group_hover(group_name.clone(), |s| {
- s.bg(linear_gradient(
- 90.,
- linear_color_stop(color.element_hover, 0.6),
- linear_color_stop(color.element_hover.opacity(0.0), 0.),
- ))
- })
- .group_active(group_name, |s| {
- s.bg(linear_gradient(
- 90.,
- linear_color_stop(color.element_active, 0.6),
- linear_color_stop(color.element_active.opacity(0.0), 0.),
- ))
- })
- });
+ let end_hover_gradient_overlay =
+ GradientFade::new(base_bg, color.element_hover, color.element_active)
+ .width(px(96.0))
+ .when_some(self.group_name.clone(), |fade, group| {
+ fade.group_name(group)
+ });
h_flex()
.id(self.id)