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