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    Small,
 11    XSmall,
 12}
 13
 14#[derive(Default, PartialEq, Copy, Clone)]
 15pub enum LineHeightStyle {
 16    #[default]
 17    TextLabel,
 18    /// Sets the line height to 1.
 19    UiLabel,
 20}
 21
 22/// A common set of traits all labels must implement.
 23pub trait LabelCommon {
 24    /// Sets the size of the label using a [`LabelSize`].
 25    fn size(self, size: LabelSize) -> Self;
 26
 27    /// Sets the line height style of the label using a [`LineHeightStyle`].
 28    fn line_height_style(self, line_height_style: LineHeightStyle) -> Self;
 29
 30    /// Sets the color of the label using a [`Color`].
 31    fn color(self, color: Color) -> Self;
 32
 33    /// Sets the strikethrough property of the label.
 34    fn strikethrough(self, strikethrough: bool) -> Self;
 35}
 36
 37#[derive(IntoElement)]
 38pub struct LabelLike {
 39    size: LabelSize,
 40    line_height_style: LineHeightStyle,
 41    pub(crate) color: Color,
 42    strikethrough: bool,
 43    children: SmallVec<[AnyElement; 2]>,
 44}
 45
 46impl LabelLike {
 47    pub fn new() -> Self {
 48        Self {
 49            size: LabelSize::Default,
 50            line_height_style: LineHeightStyle::default(),
 51            color: Color::Default,
 52            strikethrough: false,
 53            children: SmallVec::new(),
 54        }
 55    }
 56}
 57
 58impl LabelCommon for LabelLike {
 59    fn size(mut self, size: LabelSize) -> Self {
 60        self.size = size;
 61        self
 62    }
 63
 64    fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
 65        self.line_height_style = line_height_style;
 66        self
 67    }
 68
 69    fn color(mut self, color: Color) -> Self {
 70        self.color = color;
 71        self
 72    }
 73
 74    fn strikethrough(mut self, strikethrough: bool) -> Self {
 75        self.strikethrough = strikethrough;
 76        self
 77    }
 78}
 79
 80impl ParentElement for LabelLike {
 81    fn extend(&mut self, elements: impl Iterator<Item = AnyElement>) {
 82        self.children.extend(elements)
 83    }
 84}
 85
 86impl RenderOnce for LabelLike {
 87    fn render(self, cx: &mut WindowContext) -> impl IntoElement {
 88        div()
 89            .when(self.strikethrough, |this| {
 90                this.relative().child(
 91                    div()
 92                        .absolute()
 93                        .top_1_2()
 94                        .w_full()
 95                        .h_px()
 96                        .bg(Color::Hidden.color(cx)),
 97                )
 98            })
 99            .map(|this| match self.size {
100                LabelSize::Default => this.text_ui(),
101                LabelSize::Small => this.text_ui_sm(),
102                LabelSize::XSmall => this.text_ui_xs(),
103            })
104            .when(self.line_height_style == LineHeightStyle::UiLabel, |this| {
105                this.line_height(relative(1.))
106            })
107            .text_color(self.color.color(cx))
108            .children(self.children)
109    }
110}