label_like.rs

  1use gpui::{relative, AnyElement, FontWeight, StyleRefinement, 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    pub(super) base: Div,
 47    size: LabelSize,
 48    weight: FontWeight,
 49    line_height_style: LineHeightStyle,
 50    pub(crate) color: Color,
 51    strikethrough: bool,
 52    italic: bool,
 53    children: SmallVec<[AnyElement; 2]>,
 54}
 55
 56impl LabelLike {
 57    pub fn new() -> Self {
 58        Self {
 59            base: div(),
 60            size: LabelSize::Default,
 61            weight: FontWeight::default(),
 62            line_height_style: LineHeightStyle::default(),
 63            color: Color::Default,
 64            strikethrough: false,
 65            italic: false,
 66            children: SmallVec::new(),
 67        }
 68    }
 69}
 70
 71// Style methods.
 72impl LabelLike {
 73    fn style(&mut self) -> &mut StyleRefinement {
 74        self.base.style()
 75    }
 76
 77    gpui::margin_style_methods!({
 78        visibility: pub
 79    });
 80}
 81
 82impl LabelCommon for LabelLike {
 83    fn size(mut self, size: LabelSize) -> Self {
 84        self.size = size;
 85        self
 86    }
 87
 88    fn weight(mut self, weight: FontWeight) -> Self {
 89        self.weight = weight;
 90        self
 91    }
 92
 93    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
 94        self.line_height_style = line_height_style;
 95        self
 96    }
 97
 98    fn color(mut self, color: Color) -> Self {
 99        self.color = color;
100        self
101    }
102
103    fn strikethrough(mut self, strikethrough: bool) -> Self {
104        self.strikethrough = strikethrough;
105        self
106    }
107
108    fn italic(mut self, italic: bool) -> Self {
109        self.italic = italic;
110        self
111    }
112}
113
114impl ParentElement for LabelLike {
115    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
116        self.children.extend(elements)
117    }
118}
119
120impl RenderOnce for LabelLike {
121    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
122        self.base
123            .when(self.strikethrough, |this| {
124                this.relative().child(
125                    div()
126                        .absolute()
127                        .top_1_2()
128                        .w_full()
129                        .h_px()
130                        .bg(Color::Hidden.color(cx)),
131                )
132            })
133            .map(|this| match self.size {
134                LabelSize::Large => this.text_ui_lg(cx),
135                LabelSize::Default => this.text_ui(cx),
136                LabelSize::Small => this.text_ui_sm(cx),
137                LabelSize::XSmall => this.text_ui_xs(cx),
138            })
139            .when(self.line_height_style == LineHeightStyle::UiLabel, |this| {
140                this.line_height(relative(1.))
141            })
142            .when(self.italic, |this| this.italic())
143            .text_color(self.color.color(cx))
144            .font_weight(self.weight)
145            .children(self.children)
146    }
147}