gpui_component/plot/
label.rs1use std::fmt::Debug;
2
3use gpui::{
4 point, px, App, Bounds, FontWeight, Hsla, Pixels, Point, SharedString, TextAlign, TextRun,
5 Window,
6};
7
8use super::origin_point;
9
10pub const TEXT_SIZE: f32 = 10.;
11pub const TEXT_GAP: f32 = 2.;
12pub const TEXT_HEIGHT: f32 = TEXT_SIZE + TEXT_GAP;
13
14pub struct Text {
15 pub text: SharedString,
16 pub origin: Point<Pixels>,
17 pub color: Hsla,
18 pub font_size: Pixels,
19 pub font_weight: FontWeight,
20 pub align: TextAlign,
21}
22
23impl Text {
24 pub fn new<T>(text: impl Into<SharedString>, origin: Point<T>, color: Hsla) -> Self
25 where
26 T: Default + Clone + Copy + Debug + PartialEq + Into<Pixels>,
27 {
28 let origin = point(origin.x.into(), origin.y.into());
29
30 Self {
31 text: text.into(),
32 origin,
33 color,
34 font_size: TEXT_SIZE.into(),
35 font_weight: FontWeight::NORMAL,
36 align: TextAlign::Left,
37 }
38 }
39
40 pub fn font_size(mut self, font_size: impl Into<Pixels>) -> Self {
42 self.font_size = font_size.into();
43 self
44 }
45
46 pub fn font_weight(mut self, font_weight: FontWeight) -> Self {
48 self.font_weight = font_weight;
49 self
50 }
51
52 pub fn align(mut self, align: TextAlign) -> Self {
54 self.align = align;
55 self
56 }
57}
58
59impl<I> From<I> for Label
60where
61 I: Iterator<Item = Text>,
62{
63 fn from(items: I) -> Self {
64 Self::new(items.collect())
65 }
66}
67
68#[derive(Default)]
69pub struct Label(Vec<Text>);
70
71impl Label {
72 pub fn new(items: Vec<Text>) -> Self {
73 Self(items)
74 }
75
76 pub fn paint(&self, bounds: &Bounds<Pixels>, window: &mut Window, cx: &mut App) {
78 for Text {
79 text,
80 origin,
81 color,
82 font_size,
83 font_weight,
84 align,
85 } in self.0.iter()
86 {
87 let origin = origin_point(origin.x, origin.y, bounds.origin);
88
89 let text_run = TextRun {
90 len: text.len(),
91 font: window.text_style().highlight(*font_weight).font(),
92 color: *color,
93 background_color: None,
94 underline: None,
95 strikethrough: None,
96 };
97
98 if let Ok(text) =
99 window
100 .text_system()
101 .shape_text(text.clone(), *font_size, &[text_run], None, None)
102 {
103 for line in text {
104 let origin = match align {
105 TextAlign::Left => origin,
106 TextAlign::Right => origin - point(line.size(*font_size).width, px(0.)),
107 _ => origin - point(line.size(*font_size).width / 2., px(0.)),
108 };
109
110 let _ = line.paint(origin, *font_size, *align, None, window, cx);
111 }
112 }
113 }
114 }
115}