decorated_icon.rs

  1use gpui::{AnyElement, IntoElement, Point};
  2
  3use crate::{IconDecoration, IconDecorationKind, prelude::*};
  4
  5#[derive(IntoElement, RegisterComponent)]
  6pub struct DecoratedIcon {
  7    icon: Icon,
  8    decoration: Option<IconDecoration>,
  9}
 10
 11impl DecoratedIcon {
 12    pub const fn new(icon: Icon, decoration: Option<IconDecoration>) -> Self {
 13        Self { icon, decoration }
 14    }
 15}
 16
 17impl RenderOnce for DecoratedIcon {
 18    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
 19        div()
 20            .relative()
 21            .size(self.icon.size)
 22            .child(self.icon)
 23            .children(self.decoration)
 24    }
 25}
 26
 27impl Component for DecoratedIcon {
 28    fn scope() -> ComponentScope {
 29        ComponentScope::Images
 30    }
 31
 32    fn description() -> Option<&'static str> {
 33        Some(
 34            "An icon with an optional decoration overlay (like an X, triangle, or dot) that can be positioned relative to the icon",
 35        )
 36    }
 37
 38    fn preview(_window: &mut Window, cx: &mut App) -> Option<AnyElement> {
 39        let decoration_x = IconDecoration::new(
 40            IconDecorationKind::X,
 41            cx.theme().colors().surface_background,
 42            cx,
 43        )
 44        .color(cx.theme().status().error)
 45        .position(Point {
 46            x: px(-2.),
 47            y: px(-2.),
 48        });
 49
 50        let decoration_triangle = IconDecoration::new(
 51            IconDecorationKind::Triangle,
 52            cx.theme().colors().surface_background,
 53            cx,
 54        )
 55        .color(cx.theme().status().error)
 56        .position(Point {
 57            x: px(-2.),
 58            y: px(-2.),
 59        });
 60
 61        let decoration_dot = IconDecoration::new(
 62            IconDecorationKind::Dot,
 63            cx.theme().colors().surface_background,
 64            cx,
 65        )
 66        .color(cx.theme().status().error)
 67        .position(Point {
 68            x: px(-2.),
 69            y: px(-2.),
 70        });
 71
 72        Some(
 73            v_flex()
 74                .gap_6()
 75                .children(vec![example_group_with_title(
 76                    "Decorations",
 77                    vec![
 78                        single_example(
 79                            "No Decoration",
 80                            DecoratedIcon::new(Icon::new(IconName::FileDoc), None)
 81                                .into_any_element(),
 82                        ),
 83                        single_example(
 84                            "X Decoration",
 85                            DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_x))
 86                                .into_any_element(),
 87                        ),
 88                        single_example(
 89                            "Triangle Decoration",
 90                            DecoratedIcon::new(
 91                                Icon::new(IconName::FileDoc),
 92                                Some(decoration_triangle),
 93                            )
 94                            .into_any_element(),
 95                        ),
 96                        single_example(
 97                            "Dot Decoration",
 98                            DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_dot))
 99                                .into_any_element(),
100                        ),
101                    ],
102                )])
103                .into_any_element(),
104        )
105    }
106}