ferroui_controls/documents/
text_element.rs1use super::IInlineHost;
2use crate::{Border, Control};
3use ferroui_base::media::{
4 Brushes, FontFamily, FontFeatureCollection, FontStretch, FontStyle, FontWeight, IBrush,
5};
6use ferroui_base::{
7 ferro_class, ferro_property, AttachedProperty, FerroObjectImpl, FerroObjectImplExt, FerroProperty,
8 FerroPropertyChangedEventArgs, StyledElement, StyledElementImpl, StyledProperty, StyledPropertyOptions,
9};
10use std::cell::RefCell;
11use std::rc::Rc;
12
13#[repr(C)]
19pub struct TextElement {
20 base: StyledElement,
21 inline_host: RefCell<Option<Rc<dyn IInlineHost>>>,
22}
23
24ferro_class! {
25 TextElement: StyledElement, virtuals TextElementImpl: StyledElementImpl {
26 #[doc(hidden)]
28 fn on_inline_host_changed(this, old_value: Option<&Rc<dyn IInlineHost>>, new_value: Option<&Rc<dyn IInlineHost>>);
29 }
30}
31
32ferroui_base::ferro_impl_classes!(TextElement: StyledElementImpl);
33
34impl FerroObjectImpl for TextElement {
35 fn on_property_changed(this: &Self, change: &FerroPropertyChangedEventArgs<'_>) {
36 Self::parent_on_property_changed(this, change);
37
38 match change.property().name() {
39 "Background" | "FontFamily" | "FontSize" | "FontStyle" | "FontWeight" | "FontStretch"
40 | "Foreground" => {
41 if let Some(host) = this.inline_host() {
42 host.invalidate();
43 }
44 }
45 _ => {}
46 }
47 }
48}
49
50impl TextElementImpl for TextElement {
51 fn on_inline_host_changed(
52 _this: &Self,
53 _old_value: Option<&Rc<dyn IInlineHost>>,
54 _new_value: Option<&Rc<dyn IInlineHost>>,
55 ) {
56 }
57}
58
59ferroui_base::ferro_properties! { impl TextElement {
60 ferro_property!(
61 pub fn background_property() -> StyledProperty<Option<Rc<dyn IBrush>>> {
63 Border::background_property().add_owner::<TextElement>()
64 }
65 );
66
67 ferro_property!(
68 pub fn font_family_property() -> AttachedProperty<FontFamily> {
70 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
71 "FontFamily",
72 StyledPropertyOptions::new(FontFamily::default_family()).inherits(true),
73 )
74 }
75 );
76
77 ferro_property!(
78 pub fn font_features_property() -> AttachedProperty<Option<FontFeatureCollection>> {
80 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
81 "FontFeatures",
82 StyledPropertyOptions::new(None).inherits(true),
83 )
84 }
85 );
86
87 ferro_property!(
88 pub fn font_size_property() -> AttachedProperty<f64> {
90 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
91 "FontSize",
92 StyledPropertyOptions::new(12.0)
93 .inherits(true)
94 .validate(|font_size: &f64| *font_size > 0.0 && !font_size.is_nan() && !font_size.is_infinite()),
95 )
96 }
97 );
98
99 ferro_property!(
100 pub fn font_style_property() -> AttachedProperty<FontStyle> {
102 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
103 "FontStyle",
104 StyledPropertyOptions::new(FontStyle::default()).inherits(true),
105 )
106 }
107 );
108
109 ferro_property!(
110 pub fn font_weight_property() -> AttachedProperty<FontWeight> {
112 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
113 "FontWeight",
114 StyledPropertyOptions::new(FontWeight::Normal).inherits(true),
115 )
116 }
117 );
118
119 ferro_property!(
120 pub fn font_stretch_property() -> AttachedProperty<FontStretch> {
122 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
123 "FontStretch",
124 StyledPropertyOptions::new(FontStretch::Normal).inherits(true),
125 )
126 }
127 );
128
129 ferro_property!(
130 pub fn foreground_property() -> AttachedProperty<Option<Rc<dyn IBrush>>> {
132 FerroProperty::register_attached_with::<TextElement, TextElement, _>(
133 "Foreground",
134 StyledPropertyOptions::new(Some(Brushes::black() as Rc<dyn IBrush>)).inherits(true),
135 )
136 }
137 );
138
139 ferro_property!(
140 pub fn letter_spacing_property() -> AttachedProperty<f64> {
142 FerroProperty::register_attached_with::<TextElement, Control, _>(
143 "LetterSpacing",
144 StyledPropertyOptions::new(0.0).inherits(true),
145 )
146 }
147 );
148} }
149
150impl TextElement {
151 pub fn construct() -> Self {
153 Self { base: StyledElement::construct(), inline_host: RefCell::new(None) }
154 }
155
156 pub fn background(&self) -> Option<Rc<dyn IBrush>> {
158 self.get_value(Self::background_property())
159 }
160
161 pub fn set_background(&self, value: Option<Rc<dyn IBrush>>) {
162 self.set_value(Self::background_property(), value)
163 }
164
165 pub fn font_family(&self) -> FontFamily {
167 self.get_value(Self::font_family_property())
168 }
169
170 pub fn set_font_family(&self, value: FontFamily) {
171 self.set_value(Self::font_family_property(), value)
172 }
173
174 pub fn font_features(&self) -> Option<FontFeatureCollection> {
176 self.get_value(Self::font_features_property())
177 }
178
179 pub fn set_font_features(&self, value: Option<FontFeatureCollection>) {
180 self.set_value(Self::font_features_property(), value)
181 }
182
183 pub fn font_size(&self) -> f64 {
185 self.get_value(Self::font_size_property())
186 }
187
188 pub fn set_font_size(&self, value: f64) {
189 self.set_value(Self::font_size_property(), value)
190 }
191
192 pub fn font_style(&self) -> FontStyle {
194 self.get_value(Self::font_style_property())
195 }
196
197 pub fn set_font_style(&self, value: FontStyle) {
198 self.set_value(Self::font_style_property(), value)
199 }
200
201 pub fn font_weight(&self) -> FontWeight {
203 self.get_value(Self::font_weight_property())
204 }
205
206 pub fn set_font_weight(&self, value: FontWeight) {
207 self.set_value(Self::font_weight_property(), value)
208 }
209
210 pub fn font_stretch(&self) -> FontStretch {
212 self.get_value(Self::font_stretch_property())
213 }
214
215 pub fn set_font_stretch(&self, value: FontStretch) {
216 self.set_value(Self::font_stretch_property(), value)
217 }
218
219 pub fn foreground(&self) -> Option<Rc<dyn IBrush>> {
221 self.get_value(Self::foreground_property())
222 }
223
224 pub fn set_foreground(&self, value: Option<Rc<dyn IBrush>>) {
225 self.set_value(Self::foreground_property(), value)
226 }
227
228 pub fn letter_spacing(&self) -> f64 {
230 self.get_value(Self::letter_spacing_property())
231 }
232
233 pub fn set_letter_spacing(&self, value: f64) {
234 self.set_value(Self::letter_spacing_property(), value)
235 }
236
237 pub fn get_font_family(control: &Control) -> FontFamily {
239 control.get_value(Self::font_family_property())
240 }
241
242 pub fn set_font_family_on(control: &Control, value: FontFamily) {
244 control.set_value(Self::font_family_property(), value)
245 }
246
247 pub fn get_font_features(control: &Control) -> Option<FontFeatureCollection> {
249 control.get_value(Self::font_features_property())
250 }
251
252 pub fn set_font_features_on(control: &Control, value: Option<FontFeatureCollection>) {
254 control.set_value(Self::font_features_property(), value)
255 }
256
257 pub fn get_letter_spacing(control: &Control) -> f64 {
259 control.get_value(Self::letter_spacing_property())
260 }
261
262 pub fn set_letter_spacing_on(control: &Control, value: f64) {
264 control.set_value(Self::letter_spacing_property(), value)
265 }
266
267 pub fn get_font_size(control: &Control) -> f64 {
269 control.get_value(Self::font_size_property())
270 }
271
272 pub fn set_font_size_on(control: &Control, value: f64) {
274 control.set_value(Self::font_size_property(), value)
275 }
276
277 pub fn get_font_style(control: &Control) -> FontStyle {
279 control.get_value(Self::font_style_property())
280 }
281
282 pub fn set_font_style_on(control: &Control, value: FontStyle) {
284 control.set_value(Self::font_style_property(), value)
285 }
286
287 pub fn get_font_weight(control: &Control) -> FontWeight {
289 control.get_value(Self::font_weight_property())
290 }
291
292 pub fn set_font_weight_on(control: &Control, value: FontWeight) {
294 control.set_value(Self::font_weight_property(), value)
295 }
296
297 pub fn get_font_stretch(control: &Control) -> FontStretch {
299 control.get_value(Self::font_stretch_property())
300 }
301
302 pub fn set_font_stretch_on(control: &Control, value: FontStretch) {
304 control.set_value(Self::font_stretch_property(), value)
305 }
306
307 pub fn get_foreground(control: &Control) -> Option<Rc<dyn IBrush>> {
309 control.get_value(Self::foreground_property())
310 }
311
312 pub fn set_foreground_on(control: &Control, value: Option<Rc<dyn IBrush>>) {
314 control.set_value(Self::foreground_property(), value)
315 }
316
317 pub(crate) fn inline_host(&self) -> Option<Rc<dyn IInlineHost>> {
319 self.inline_host.borrow().clone()
320 }
321
322 pub(crate) fn set_inline_host(&self, value: Option<Rc<dyn IInlineHost>>) {
323 let old_value = self.inline_host.replace(value.clone());
324 self.on_inline_host_changed(old_value.as_ref(), value.as_ref());
325 }
326}