label_like.rs

  1use gpui::{relative, AnyElement, 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 line height style of the label using a [`LineHeightStyle`].
 29    fn line_height_style(self, line_height_style: LineHeightStyle) -> Self;
 30
 31    /// Sets the color of the label using a [`Color`].
 32    fn color(self, color: Color) -> Self;
 33
 34    /// Sets the strikethrough property of the label.
 35    fn strikethrough(self, strikethrough: bool) -> Self;
 36
 37    /// Sets the italic property of the label.
 38    fn italic(self, italic: bool) -> Self;
 39}
 40
 41#[derive(IntoElement)]
 42pub struct LabelLike {
 43    size: LabelSize,
 44    line_height_style: LineHeightStyle,
 45    pub(crate) color: Color,
 46    strikethrough: bool,
 47    italic: bool,
 48    children: SmallVec<[AnyElement; 2]>,
 49}
 50
 51impl LabelLike {
 52    pub fn new() -> Self {
 53        Self {
 54            size: LabelSize::Default,
 55            line_height_style: LineHeightStyle::default(),
 56            color: Color::Default,
 57            strikethrough: false,
 58            italic: false,
 59            children: SmallVec::new(),
 60        }
 61    }
 62}
 63
 64impl LabelCommon for LabelLike {
 65    fn size(mut self, size: LabelSize) -> Self {
 66        self.size = size;
 67        self
 68    }
 69
 70    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
 71        self.line_height_style = line_height_style;
 72        self
 73    }
 74
 75    fn color(mut self, color: Color) -> Self {
 76        self.color = color;
 77        self
 78    }
 79
 80    fn strikethrough(mut self, strikethrough: bool) -> Self {
 81        self.strikethrough = strikethrough;
 82        self
 83    }
 84
 85    fn italic(mut self, italic: bool) -> Self {
 86        self.italic = italic;
 87        self
 88    }
 89}
 90
 91impl ParentElement for LabelLike {
 92    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
 93        self.children.extend(elements)
 94    }
 95}
 96
 97impl RenderOnce for LabelLike {
 98    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
 99        div()
100            .when(self.strikethrough, |this| {
101                this.relative().child(
102                    div()
103                        .absolute()
104                        .top_1_2()
105                        .w_full()
106                        .h_px()
107                        .bg(Color::Hidden.color(cx)),
108                )
109            })
110            .map(|this| match self.size {
111                LabelSize::Large => this.text_ui_lg(cx),
112                LabelSize::Default => this.text_ui(cx),
113                LabelSize::Small => this.text_ui_sm(cx),
114                LabelSize::XSmall => this.text_ui_xs(cx),
115            })
116            .when(self.line_height_style == LineHeightStyle::UiLabel, |this| {
117                this.line_height(relative(1.))
118            })
119            .when(self.italic, |this| this.italic())
120            .text_color(self.color.color(cx))
121            .children(self.children)
122    }
123}