1use crate::{
2 element::{Element, IntoElement, Layout},
3 layout_context::LayoutContext,
4 paint_context::PaintContext,
5};
6use anyhow::Result;
7use gpui::text_layout::LineLayout;
8use parking_lot::Mutex;
9use std::sync::Arc;
10
11impl<V: 'static, S: Into<ArcCow<'static, str>>> IntoElement<V> for S {
12 type Element = Text;
13
14 fn into_element(self) -> Self::Element {
15 Text { text: self.into() }
16 }
17}
18
19pub struct Text {
20 text: ArcCow<'static, str>,
21}
22
23impl<V: 'static> Element<V> for Text {
24 type Layout = Arc<Mutex<Option<TextLayout>>>;
25
26 fn layout(
27 &mut self,
28 view: &mut V,
29 cx: &mut LayoutContext<V>,
30 ) -> Result<Layout<V, Self::Layout>> {
31 // let rem_size = cx.rem_pixels();
32 // let fonts = cx.platform().fonts();
33 // let text_style = cx.text_style();
34 // let line_height = cx.font_cache().line_height(text_style.font_size);
35 // let layout_engine = cx.layout_engine().expect("no layout engine present");
36 // let text = self.text.clone();
37 // let layout = Arc::new(Mutex::new(None));
38
39 // let style: Style = Style::default().refined(&self.metadata.style);
40 // let node_id = layout_engine.add_measured_node(style.to_taffy(rem_size), {
41 // let layout = layout.clone();
42 // move |params| {
43 // let line_layout = fonts.layout_line(
44 // text.as_ref(),
45 // text_style.font_size,
46 // &[(text.len(), text_style.to_run())],
47 // );
48
49 // let size = Size {
50 // width: line_layout.width,
51 // height: line_height,
52 // };
53
54 // layout.lock().replace(TextLayout {
55 // line_layout: Arc::new(line_layout),
56 // line_height,
57 // });
58
59 // size
60 // }
61 // })?;
62
63 // Ok((node_id, layout))
64 todo!()
65 }
66
67 fn paint<'a>(
68 &mut self,
69 view: &mut V,
70 layout: &mut Layout<V, Self::Layout>,
71 cx: &mut PaintContext<V>,
72 ) {
73 // ) {
74 // let element_layout_lock = layout.from_element.lock();
75 // let element_layout = element_layout_lock
76 // .as_ref()
77 // .expect("layout has not been performed");
78 // let line_layout = element_layout.line_layout.clone();
79 // let line_height = element_layout.line_height;
80 // drop(element_layout_lock);
81
82 // let text_style = cx.text_style();
83 // let line =
84 // gpui::text_layout::Line::new(line_layout, &[(self.text.len(), text_style.to_run())]);
85 // line.paint(
86 // cx.scene,
87 // layout.from_engine.bounds.origin(),
88 // layout.from_engine.bounds,
89 // line_height,
90 // cx.legacy_cx,
91 // );
92 todo!()
93 }
94}
95
96pub struct TextLayout {
97 line_layout: Arc<LineLayout>,
98 line_height: f32,
99}
100
101pub enum ArcCow<'a, T: ?Sized> {
102 Borrowed(&'a T),
103 Owned(Arc<T>),
104}
105
106impl<'a, T: ?Sized> Clone for ArcCow<'a, T> {
107 fn clone(&self) -> Self {
108 match self {
109 Self::Borrowed(borrowed) => Self::Borrowed(borrowed),
110 Self::Owned(owned) => Self::Owned(owned.clone()),
111 }
112 }
113}
114
115impl<'a, T: ?Sized> From<&'a T> for ArcCow<'a, T> {
116 fn from(s: &'a T) -> Self {
117 Self::Borrowed(s)
118 }
119}
120
121impl<T> From<Arc<T>> for ArcCow<'_, T> {
122 fn from(s: Arc<T>) -> Self {
123 Self::Owned(s)
124 }
125}
126
127impl From<String> for ArcCow<'_, str> {
128 fn from(value: String) -> Self {
129 Self::Owned(value.into())
130 }
131}
132
133impl<T: ?Sized> std::ops::Deref for ArcCow<'_, T> {
134 type Target = T;
135
136 fn deref(&self) -> &Self::Target {
137 match self {
138 ArcCow::Borrowed(s) => s,
139 ArcCow::Owned(s) => s.as_ref(),
140 }
141 }
142}
143
144impl<T: ?Sized> AsRef<T> for ArcCow<'_, T> {
145 fn as_ref(&self) -> &T {
146 match self {
147 ArcCow::Borrowed(borrowed) => borrowed,
148 ArcCow::Owned(owned) => owned.as_ref(),
149 }
150 }
151}