233 lines · 6.3 KB · Rust
RawDownload
use crate::prelude::*;use gpui::{FontWeight, StyleRefinement, UnderlineStyle};use settings::Settings;use smallvec::SmallVec;use theme::ThemeSettings; /// Sets the size of a label#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]pub enum LabelSize {    /// The default size of a label.    #[default]    Default,    /// The large size of a label.    Large,    /// The small size of a label.    Small,    /// The extra small size of a label.    XSmall,} /// Sets the line height of a label#[derive(Default, PartialEq, Copy, Clone)]pub enum LineHeightStyle {    /// The default line height style of a label,    /// set by either the UI's default line height,    /// or the developer's default buffer line height.    #[default]    TextLabel,    /// Sets the line height to 1.    UiLabel,} /// A common set of traits all labels must implement.pub trait LabelCommon {    /// Sets the size of the label using a [`LabelSize`].    fn size(self, size: LabelSize) -> Self;     /// Sets the font weight of the label.    fn weight(self, weight: FontWeight) -> Self;     /// Sets the line height style of the label using a [`LineHeightStyle`].    fn line_height_style(self, line_height_style: LineHeightStyle) -> Self;     /// Sets the color of the label using a [`Color`].    fn color(self, color: Color) -> Self;     /// Sets the strikethrough property of the label.    fn strikethrough(self) -> Self;     /// Sets the italic property of the label.    fn italic(self) -> Self;     /// Sets the underline property of the label    fn underline(self) -> Self;     /// Sets the alpha property of the label, overwriting the alpha value of the color.    fn alpha(self, alpha: f32) -> Self;     /// Truncates overflowing text with an ellipsis (`…`) if needed.    fn text_ellipsis(self) -> Self;     /// Sets the label to render as a single line.    fn single_line(self) -> Self;     /// Sets the font to the buffer's    fn buffer_font(self, cx: &App) -> Self;} /// A label-like element that can be used to create a custom label when/// prebuilt labels are not sufficient. Use this sparingly, as it is/// unconstrained and may make the UI feel less consistent.////// This is also used to build the prebuilt labels.#[derive(IntoElement)]pub struct LabelLike {    pub(super) base: Div,    size: LabelSize,    weight: Option<FontWeight>,    line_height_style: LineHeightStyle,    pub(crate) color: Color,    strikethrough: bool,    italic: bool,    children: SmallVec<[AnyElement; 2]>,    alpha: Option<f32>,    underline: bool,    single_line: bool,    text_ellipsis: bool,} impl Default for LabelLike {    fn default() -> Self {        Self::new()    }} impl LabelLike {    /// Creates a new, fully custom label.    /// Prefer using [`Label`] or [`HighlightedLabel`] where possible.    pub fn new() -> Self {        Self {            base: div(),            size: LabelSize::Default,            weight: None,            line_height_style: LineHeightStyle::default(),            color: Color::Default,            strikethrough: false,            italic: false,            children: SmallVec::new(),            alpha: None,            underline: false,            single_line: false,            text_ellipsis: false,        }    }} // Style methods.impl LabelLike {    fn style(&mut self) -> &mut StyleRefinement {        self.base.style()    }     gpui::margin_style_methods!({        visibility: pub    });} impl LabelCommon for LabelLike {    fn size(mut self, size: LabelSize) -> Self {        self.size = size;        self    }     fn weight(mut self, weight: FontWeight) -> Self {        self.weight = Some(weight);        self    }     fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {        self.line_height_style = line_height_style;        self    }     fn color(mut self, color: Color) -> Self {        self.color = color;        self    }     fn strikethrough(mut self) -> Self {        self.strikethrough = true;        self    }     fn italic(mut self) -> Self {        self.italic = true;        self    }     fn underline(mut self) -> Self {        self.underline = true;        self    }     fn alpha(mut self, alpha: f32) -> Self {        self.alpha = Some(alpha);        self    }     fn text_ellipsis(mut self) -> Self {        self.text_ellipsis = true;        self    }     fn single_line(mut self) -> Self {        self.single_line = true;        self    }     fn buffer_font(mut self, cx: &App) -> Self {        self.base = self            .base            .font(theme::ThemeSettings::get_global(cx).buffer_font.clone());        self    }} impl ParentElement for LabelLike {    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {        self.children.extend(elements)    }} impl RenderOnce for LabelLike {    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {        let mut color = self.color.color(cx);        if let Some(alpha) = self.alpha {            color.fade_out(1.0 - alpha);        }         self.base            .map(|this| match self.size {                LabelSize::Large => this.text_ui_lg(cx),                LabelSize::Default => this.text_ui(cx),                LabelSize::Small => this.text_ui_sm(cx),                LabelSize::XSmall => this.text_ui_xs(cx),            })            .when(self.line_height_style == LineHeightStyle::UiLabel, |this| {                this.line_height(relative(1.))            })            .when(self.italic, |this| this.italic())            .when(self.underline, |mut this| {                this.text_style()                    .get_or_insert_with(Default::default)                    .underline = Some(UnderlineStyle {                    thickness: px(1.),                    color: None,                    wavy: false,                });                this            })            .when(self.strikethrough, |this| this.line_through())            .when(self.single_line, |this| this.whitespace_nowrap())            .when(self.text_ellipsis, |this| {                this.overflow_x_hidden().text_ellipsis()            })            .text_color(color)            .font_weight(                self.weight                    .unwrap_or(ThemeSettings::get_global(cx).ui_font.weight),            )            .children(self.children)    }}