label_like.rs

  1use gpui::{relative, AnyElement, FontWeight, Styled};
  2use smallvec::SmallVec;
  3
  4use crate::prelude::*;
  5
  6#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
  7pub enum LabelSize {
  8    #[default]
  9    Default,
 10    Large,
 11    Small,
 12    XSmall,
 13}
 14
 15#[derive(Default, PartialEq, Copy, Clone)]
 16pub enum LineHeightStyle {
 17    #[default]
 18    TextLabel,
 19    /// Sets the line height to 1.
 20    UiLabel,
 21}
 22
 23/// A common set of traits all labels must implement.
 24pub trait LabelCommon {
 25    /// Sets the size of the label using a [`LabelSize`].
 26    fn size(self, size: LabelSize) -> Self;
 27
 28    /// Sets the font weight of the label.
 29    fn weight(self, weight: FontWeight) -> Self;
 30
 31    /// Sets the line height style of the label using a [`LineHeightStyle`].
 32    fn line_height_style(self, line_height_style: LineHeightStyle) -> Self;
 33
 34    /// Sets the color of the label using a [`Color`].
 35    fn color(self, color: Color) -> Self;
 36
 37    /// Sets the strikethrough property of the label.
 38    fn strikethrough(self, strikethrough: bool) -> Self;
 39
 40    /// Sets the italic property of the label.
 41    fn italic(self, italic: bool) -> Self;
 42}
 43
 44#[derive(IntoElement)]
 45pub struct LabelLike {
 46    size: LabelSize,
 47    weight: FontWeight,
 48    line_height_style: LineHeightStyle,
 49    pub(crate) color: Color,
 50    strikethrough: bool,
 51    italic: bool,
 52    children: SmallVec<[AnyElement; 2]>,
 53}
 54
 55impl LabelLike {
 56    pub fn new() -> Self {
 57        Self {
 58            size: LabelSize::Default,
 59            weight: FontWeight::default(),
 60            line_height_style: LineHeightStyle::default(),
 61            color: Color::Default,
 62            strikethrough: false,
 63            italic: false,
 64            children: SmallVec::new(),
 65        }
 66    }
 67}
 68
 69impl LabelCommon for LabelLike {
 70    fn size(mut self, size: LabelSize) -> Self {
 71        self.size = size;
 72        self
 73    }
 74
 75    fn weight(mut self, weight: FontWeight) -> Self {
 76        self.weight = weight;
 77        self
 78    }
 79
 80    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
 81        self.line_height_style = line_height_style;
 82        self
 83    }
 84
 85    fn color(mut self, color: Color) -> Self {
 86        self.color = color;
 87        self
 88    }
 89
 90    fn strikethrough(mut self, strikethrough: bool) -> Self {
 91        self.strikethrough = strikethrough;
 92        self
 93    }
 94
 95    fn italic(mut self, italic: bool) -> Self {
 96        self.italic = italic;
 97        self
 98    }
 99}
100
101impl ParentElement for LabelLike {
102    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
103        self.children.extend(elements)
104    }
105}
106
107impl RenderOnce for LabelLike {
108    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
109        div()
110            .when(self.strikethrough, |this| {
111                this.relative().child(
112                    div()
113                        .absolute()
114                        .top_1_2()
115                        .w_full()
116                        .h_px()
117                        .bg(Color::Hidden.color(cx)),
118                )
119            })
120            .map(|this| match self.size {
121                LabelSize::Large => this.text_ui_lg(cx),
122                LabelSize::Default => this.text_ui(cx),
123                LabelSize::Small => this.text_ui_sm(cx),
124                LabelSize::XSmall => this.text_ui_xs(cx),
125            })
126            .when(self.line_height_style == LineHeightStyle::UiLabel, |this| {
127                this.line_height(relative(1.))
128            })
129            .when(self.italic, |this| this.italic())
130            .text_color(self.color.color(cx))
131            .font_weight(self.weight)
132            .children(self.children)
133    }
134}