Detailed changes
@@ -5,7 +5,7 @@ use gpui::{
WindowBounds, WindowHandle, WindowKind, WindowOptions,
};
use theme::ActiveTheme;
-use ui::{h_stack, v_stack, Button, Clickable, Color, Icon, IconElement, Label};
+use ui::{prelude::*, Button, Icon, IconElement, Label};
const COPILOT_SIGN_UP_URL: &'static str = "https://github.com/features/copilot";
@@ -36,7 +36,7 @@ use std::{
};
use theme::ActiveTheme;
pub use toolbar_controls::ToolbarControls;
-use ui::{h_stack, Color, HighlightedLabel, Icon, IconElement, Label};
+use ui::{h_stack, prelude::*, HighlightedLabel, Icon, IconElement, Label};
use util::TryFutureExt;
use workspace::{
item::{BreadcrumbText, Item, ItemEvent, ItemHandle},
@@ -32,7 +32,7 @@ use std::{
};
use text::Selection;
use theme::{ActiveTheme, Theme};
-use ui::{h_stack, Color, Label};
+use ui::{h_stack, prelude::*, Label};
use util::{paths::PathExt, paths::FILE_ROW_COLUMN_DELIMITER, ResultExt, TryFutureExt};
use workspace::{
item::{BreadcrumbText, FollowEvent, FollowableItemHandle},
@@ -6,7 +6,7 @@ use gpui::{
};
use text::{Bias, Point};
use theme::ActiveTheme;
-use ui::{h_stack, v_stack, Color, Label, StyledExt};
+use ui::{h_stack, prelude::*, v_stack, Label};
use util::paths::FILE_ROW_COLUMN_DELIMITER;
actions!(Toggle);
@@ -1,183 +1,7 @@
-use std::ops::Range;
+mod highlighted_label;
+mod label;
+mod label_like;
-use crate::prelude::*;
-use crate::styled_ext::StyledExt;
-use gpui::{relative, Div, HighlightStyle, IntoElement, StyledText, WindowContext};
-
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
-pub enum LabelSize {
- #[default]
- Default,
- Small,
-}
-
-#[derive(Default, PartialEq, Copy, Clone)]
-pub enum LineHeightStyle {
- #[default]
- TextLabel,
- /// Sets the line height to 1
- UILabel,
-}
-
-#[derive(IntoElement, Clone)]
-pub struct Label {
- label: SharedString,
- size: LabelSize,
- line_height_style: LineHeightStyle,
- color: Color,
- strikethrough: bool,
-}
-
-impl RenderOnce for Label {
- type Rendered = Div;
-
- fn render(self, cx: &mut WindowContext) -> Self::Rendered {
- div()
- .when(self.strikethrough, |this| {
- this.relative().child(
- div()
- .absolute()
- .top_1_2()
- .w_full()
- .h_px()
- .bg(Color::Hidden.color(cx)),
- )
- })
- .map(|this| match self.size {
- LabelSize::Default => this.text_ui(),
- LabelSize::Small => this.text_ui_sm(),
- })
- .when(self.line_height_style == LineHeightStyle::UILabel, |this| {
- this.line_height(relative(1.))
- })
- .text_color(self.color.color(cx))
- .child(self.label.clone())
- }
-}
-
-impl Label {
- pub fn new(label: impl Into<SharedString>) -> Self {
- Self {
- label: label.into(),
- size: LabelSize::Default,
- line_height_style: LineHeightStyle::default(),
- color: Color::Default,
- strikethrough: false,
- }
- }
-
- pub fn size(mut self, size: LabelSize) -> Self {
- self.size = size;
- self
- }
-
- pub fn color(mut self, color: Color) -> Self {
- self.color = color;
- self
- }
-
- pub fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
- self.line_height_style = line_height_style;
- self
- }
-
- pub fn set_strikethrough(mut self, strikethrough: bool) -> Self {
- self.strikethrough = strikethrough;
- self
- }
-}
-
-#[derive(IntoElement)]
-pub struct HighlightedLabel {
- label: SharedString,
- size: LabelSize,
- color: Color,
- highlight_indices: Vec<usize>,
- strikethrough: bool,
-}
-
-impl RenderOnce for HighlightedLabel {
- type Rendered = Div;
-
- fn render(self, cx: &mut WindowContext) -> Self::Rendered {
- let highlight_color = cx.theme().colors().text_accent;
-
- let mut highlight_indices = self.highlight_indices.iter().copied().peekable();
- let mut highlights: Vec<(Range<usize>, HighlightStyle)> = Vec::new();
-
- while let Some(start_ix) = highlight_indices.next() {
- let mut end_ix = start_ix;
-
- loop {
- end_ix = end_ix + self.label[end_ix..].chars().next().unwrap().len_utf8();
- if let Some(&next_ix) = highlight_indices.peek() {
- if next_ix == end_ix {
- end_ix = next_ix;
- highlight_indices.next();
- continue;
- }
- }
- break;
- }
-
- highlights.push((
- start_ix..end_ix,
- HighlightStyle {
- color: Some(highlight_color),
- ..Default::default()
- },
- ));
- }
-
- let mut text_style = cx.text_style().clone();
- text_style.color = self.color.color(cx);
-
- div()
- .flex()
- .when(self.strikethrough, |this| {
- this.relative().child(
- div()
- .absolute()
- .top_px()
- .my_auto()
- .w_full()
- .h_px()
- .bg(Color::Hidden.color(cx)),
- )
- })
- .map(|this| match self.size {
- LabelSize::Default => this.text_ui(),
- LabelSize::Small => this.text_ui_sm(),
- })
- .child(StyledText::new(self.label).with_highlights(&text_style, highlights))
- }
-}
-
-impl HighlightedLabel {
- /// shows a label with the given characters highlighted.
- /// characters are identified by utf8 byte position.
- pub fn new(label: impl Into<SharedString>, highlight_indices: Vec<usize>) -> Self {
- Self {
- label: label.into(),
- size: LabelSize::Default,
- color: Color::Default,
- highlight_indices,
- strikethrough: false,
- }
- }
-
- pub fn size(mut self, size: LabelSize) -> Self {
- self.size = size;
- self
- }
-
- pub fn color(mut self, color: Color) -> Self {
- self.color = color;
- self
- }
-
- pub fn set_strikethrough(mut self, strikethrough: bool) -> Self {
- self.strikethrough = strikethrough;
- self
- }
-}
+pub use highlighted_label::*;
+pub use label::*;
+pub use label_like::*;
@@ -0,0 +1,86 @@
+use std::ops::Range;
+
+use gpui::{HighlightStyle, StyledText};
+
+use crate::{prelude::*, LabelCommon, LabelLike, LabelSize, LineHeightStyle};
+
+#[derive(IntoElement)]
+pub struct HighlightedLabel {
+ base: LabelLike,
+ label: SharedString,
+ highlight_indices: Vec<usize>,
+}
+
+impl HighlightedLabel {
+ /// Constructs a label with the given characters highlighted.
+ /// Characters are identified by UTF-8 byte position.
+ pub fn new(label: impl Into<SharedString>, highlight_indices: Vec<usize>) -> Self {
+ Self {
+ base: LabelLike::new(),
+ label: label.into(),
+ highlight_indices,
+ }
+ }
+}
+
+impl LabelCommon for HighlightedLabel {
+ fn size(mut self, size: LabelSize) -> Self {
+ self.base = self.base.size(size);
+ self
+ }
+
+ fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
+ self.base = self.base.line_height_style(line_height_style);
+ self
+ }
+
+ fn color(mut self, color: Color) -> Self {
+ self.base = self.base.color(color);
+ self
+ }
+
+ fn strikethrough(mut self, strikethrough: bool) -> Self {
+ self.base = self.base.strikethrough(strikethrough);
+ self
+ }
+}
+
+impl RenderOnce for HighlightedLabel {
+ type Rendered = LabelLike;
+
+ fn render(self, cx: &mut WindowContext) -> Self::Rendered {
+ let highlight_color = cx.theme().colors().text_accent;
+
+ let mut highlight_indices = self.highlight_indices.iter().copied().peekable();
+ let mut highlights: Vec<(Range<usize>, HighlightStyle)> = Vec::new();
+
+ while let Some(start_ix) = highlight_indices.next() {
+ let mut end_ix = start_ix;
+
+ loop {
+ end_ix = end_ix + self.label[end_ix..].chars().next().unwrap().len_utf8();
+ if let Some(&next_ix) = highlight_indices.peek() {
+ if next_ix == end_ix {
+ end_ix = next_ix;
+ highlight_indices.next();
+ continue;
+ }
+ }
+ break;
+ }
+
+ highlights.push((
+ start_ix..end_ix,
+ HighlightStyle {
+ color: Some(highlight_color),
+ ..Default::default()
+ },
+ ));
+ }
+
+ let mut text_style = cx.text_style().clone();
+ text_style.color = self.base.color.color(cx);
+
+ LabelLike::new().child(StyledText::new(self.label).with_highlights(&text_style, highlights))
+ }
+}
@@ -0,0 +1,48 @@
+use gpui::WindowContext;
+
+use crate::{prelude::*, LabelCommon, LabelLike, LabelSize, LineHeightStyle};
+
+#[derive(IntoElement)]
+pub struct Label {
+ base: LabelLike,
+ label: SharedString,
+}
+
+impl Label {
+ pub fn new(label: impl Into<SharedString>) -> Self {
+ Self {
+ base: LabelLike::new(),
+ label: label.into(),
+ }
+ }
+}
+
+impl LabelCommon for Label {
+ fn size(mut self, size: LabelSize) -> Self {
+ self.base = self.base.size(size);
+ self
+ }
+
+ fn line_height_style(mut self, line_height_style: LineHeightStyle) -> Self {
+ self.base = self.base.line_height_style(line_height_style);
+ self
+ }
+
+ fn color(mut self, color: Color) -> Self {
+ self.base = self.base.color(color);
+ self
+ }
+
+ fn strikethrough(mut self, strikethrough: bool) -> Self {
+ self.base = self.base.strikethrough(strikethrough);
+ self
+ }
+}
+
+impl RenderOnce for Label {
+ type Rendered = LabelLike;
+
+ fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
+ self.base.child(self.label)
+ }
+}
@@ -0,0 +1,102 @@
+use gpui::{relative, AnyElement, Div, Styled};
+use smallvec::SmallVec;
+
+use crate::prelude::*;
+
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
+pub enum LabelSize {
+ #[default]
+ Default,
+ Small,
+}
+
+#[derive(Default, PartialEq, Copy, Clone)]
+pub enum LineHeightStyle {
+ #[default]
+ TextLabel,
+ /// Sets the line height to 1
+ UILabel,
+}
+
+pub trait LabelCommon {
+ fn size(self, size: LabelSize) -> Self;
+ fn line_height_style(self, line_height_style: LineHeightStyle) -> Self;
+ fn color(self, color: Color) -> Self;
+ fn strikethrough(self, strikethrough: bool) -> Self;
+}
+
+#[derive(IntoElement)]
+pub struct LabelLike {
+ size: LabelSize,
+ line_height_style: LineHeightStyle,
+ pub(crate) color: Color,
+ strikethrough: bool,
+ children: SmallVec<[AnyElement; 2]>,
+}
+
+impl LabelLike {
+ pub fn new() -> Self {
+ Self {
+ size: LabelSize::Default,
+ line_height_style: LineHeightStyle::default(),
+ color: Color::Default,
+ strikethrough: false,
+ children: SmallVec::new(),
+ }
+ }
+}
+
+impl LabelCommon for LabelLike {
+ fn size(mut self, size: LabelSize) -> Self {
+ self.size = size;
+ 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, strikethrough: bool) -> Self {
+ self.strikethrough = strikethrough;
+ self
+ }
+}
+
+impl ParentElement for LabelLike {
+ fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
+ &mut self.children
+ }
+}
+
+impl RenderOnce for LabelLike {
+ type Rendered = Div;
+
+ fn render(self, cx: &mut WindowContext) -> Self::Rendered {
+ div()
+ .when(self.strikethrough, |this| {
+ this.relative().child(
+ div()
+ .absolute()
+ .top_1_2()
+ .w_full()
+ .h_px()
+ .bg(Color::Hidden.color(cx)),
+ )
+ })
+ .map(|this| match self.size {
+ LabelSize::Default => this.text_ui(),
+ LabelSize::Small => this.text_ui_sm(),
+ })
+ .when(self.line_height_style == LineHeightStyle::UILabel, |this| {
+ this.line_height(relative(1.))
+ })
+ .text_color(self.color.color(cx))
+ .children(self.children)
+ }
+}
@@ -9,5 +9,5 @@ pub use crate::disableable::*;
pub use crate::fixed::*;
pub use crate::selectable::*;
pub use crate::{h_stack, v_stack};
-pub use crate::{ButtonCommon, Color, StyledExt};
+pub use crate::{ButtonCommon, Color, LabelCommon, StyledExt};
pub use theme::ActiveTheme;