Skip to main content

ferroui_base/input/text_input/
text_input_options.rs

1use super::{TextInputContentType, TextInputReturnKeyType};
2use crate::input::InputScopeNameValue;
3use crate::{ferro_property, AttachedProperty, FerroProperty, StyledElement, StyledPropertyOptions};
4use std::rc::Rc;
5
6/// Describes how a text input wants the input method of the platform to
7/// behave: the properties are attached to a text editing control (they are
8/// inherited) and gathered into a `TextInputOptions` value for the input
9/// method.
10#[derive(Clone, Debug, Default, PartialEq)]
11pub struct TextInputOptions {
12    /// The content type (mostly for determining the shape of the virtual keyboard).
13    pub content_type: TextInputContentType,
14
15    /// Determines what the Return key says and how it behaves.
16    pub return_key_type: TextInputReturnKeyType,
17
18    /// Text is multiline.
19    pub multiline: bool,
20
21    /// Text is in lower case.
22    pub lowercase: bool,
23
24    /// Text is in upper case.
25    pub uppercase: bool,
26
27    /// Automatically capitalize letters at the start of the sentence.
28    pub auto_capitalization: bool,
29
30    /// Text contains sensitive data like card numbers and should not be stored.
31    pub is_sensitive: bool,
32
33    /// Determines whether text suggestions are shown; `None` leaves the decision to the platform.
34    pub show_suggestions: Option<bool>,
35
36    /// Hints about the locales (BCP 47 language tags) the user is expected to type in.
37    pub locale_hints: Option<Rc<[String]>>,
38}
39
40crate::ferro_static_type!(TextInputOptions);
41
42crate::ferro_properties! {
43    impl TextInputOptions, also [
44        TextInputOptions::content_type_property,
45        TextInputOptions::input_scope_names_property,
46        TextInputOptions::return_key_type_property,
47        TextInputOptions::multiline_property,
48        TextInputOptions::lowercase_property,
49        TextInputOptions::uppercase_property,
50        TextInputOptions::auto_capitalization_property,
51        TextInputOptions::is_sensitive_property,
52        TextInputOptions::show_suggestions_property,
53        TextInputOptions::locale_hints_property,
54    ] {}
55}
56
57impl TextInputOptions {
58    /// Creates the options from the values of the attached properties of a
59    /// control.
60    pub fn from_styled_element(ferro_object: &StyledElement) -> TextInputOptions {
61        TextInputOptions {
62            content_type: Self::get_content_type(ferro_object),
63            return_key_type: Self::get_return_key_type(ferro_object),
64            multiline: Self::get_multiline(ferro_object),
65            auto_capitalization: Self::get_auto_capitalization(ferro_object),
66            is_sensitive: Self::get_is_sensitive(ferro_object),
67            lowercase: Self::get_lowercase(ferro_object),
68            uppercase: Self::get_uppercase(ferro_object),
69            show_suggestions: Self::get_show_suggestions(ferro_object),
70            locale_hints: Self::get_locale_hints(ferro_object),
71        }
72    }
73
74    /// The default options.
75    pub fn default_options() -> TextInputOptions {
76        TextInputOptions::default()
77    }
78
79    ferro_property!(for TextInputOptions;
80        /// Defines the `InputScopeNames` attached property: the ordered, immutable input-scope
81        /// hints of WinUI's `InputScope` (an addition, `docs/porting/winui-rich-text.md`). `None`
82        /// or an empty list leaves the input method to `ContentType`.
83        ///
84        /// Within 0.4 the value is not a field of [`TextInputOptions`]: a backend reads it from
85        /// the element, through [`TextInputMethodConnection::input_scope_names`](super::TextInputMethodConnection::input_scope_names)
86        /// of a client that opted in to the connection.
87        pub fn input_scope_names_property() -> AttachedProperty<Option<Rc<[InputScopeNameValue]>>> {
88            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
89                "InputScopeNames",
90                StyledPropertyOptions::new(None).inherits(true),
91            )
92        }
93    );
94
95    /// Sets the value of the attached `InputScopeNames` property on a control.
96    pub fn set_input_scope_names(ferro_object: &StyledElement, value: Option<Rc<[InputScopeNameValue]>>) {
97        ferro_object.set_value(Self::input_scope_names_property(), value)
98    }
99
100    /// Gets the value of the attached `InputScopeNames` property of a control.
101    pub fn get_input_scope_names(ferro_object: &StyledElement) -> Option<Rc<[InputScopeNameValue]>> {
102        ferro_object.get_value(Self::input_scope_names_property())
103    }
104
105    /// The first input scope of a control, the one a platform with a single hint uses.
106    pub fn get_effective_input_scope(ferro_object: &StyledElement) -> Option<InputScopeNameValue> {
107        Self::get_input_scope_names(ferro_object).and_then(|names| names.first().copied())
108    }
109
110    /// The content type that best matches the first input scope of a control, or its
111    /// `ContentType` without one: for a platform that has content types and no input scopes.
112    pub fn get_effective_content_type(ferro_object: &StyledElement) -> TextInputContentType {
113        Self::get_effective_input_scope(ferro_object)
114            .map_or_else(|| Self::get_content_type(ferro_object), InputScopeNameValue::content_type)
115    }
116
117    ferro_property!(for TextInputOptions;
118        /// Defines the `ContentType` attached property.
119        pub fn content_type_property() -> AttachedProperty<TextInputContentType> {
120            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
121                "ContentType",
122                StyledPropertyOptions::new(TextInputContentType::Normal).inherits(true),
123            )
124        }
125    );
126
127    /// Sets the value of the attached `ContentType` property on a control.
128    pub fn set_content_type(ferro_object: &StyledElement, value: TextInputContentType) {
129        ferro_object.set_value(Self::content_type_property(), value)
130    }
131
132    /// Gets the value of the attached `ContentType` property of a control.
133    pub fn get_content_type(ferro_object: &StyledElement) -> TextInputContentType {
134        ferro_object.get_value(Self::content_type_property())
135    }
136
137    ferro_property!(for TextInputOptions;
138        /// Defines the `ReturnKeyType` attached property.
139        pub fn return_key_type_property() -> AttachedProperty<TextInputReturnKeyType> {
140            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
141                "ReturnKeyType",
142                StyledPropertyOptions::new(TextInputReturnKeyType::Default).inherits(true),
143            )
144        }
145    );
146
147    /// Sets the value of the attached `ReturnKeyType` property on a control.
148    pub fn set_return_key_type(ferro_object: &StyledElement, value: TextInputReturnKeyType) {
149        ferro_object.set_value(Self::return_key_type_property(), value)
150    }
151
152    /// Gets the value of the attached `ReturnKeyType` property of a control.
153    pub fn get_return_key_type(ferro_object: &StyledElement) -> TextInputReturnKeyType {
154        ferro_object.get_value(Self::return_key_type_property())
155    }
156
157    ferro_property!(for TextInputOptions;
158        /// Defines the `Multiline` attached property.
159        pub fn multiline_property() -> AttachedProperty<bool> {
160            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
161                "Multiline",
162                StyledPropertyOptions::new(false).inherits(true),
163            )
164        }
165    );
166
167    /// Sets the value of the attached `Multiline` property on a control.
168    pub fn set_multiline(ferro_object: &StyledElement, value: bool) {
169        ferro_object.set_value(Self::multiline_property(), value)
170    }
171
172    /// Gets the value of the attached `Multiline` property of a control.
173    pub fn get_multiline(ferro_object: &StyledElement) -> bool {
174        ferro_object.get_value(Self::multiline_property())
175    }
176
177    ferro_property!(for TextInputOptions;
178        /// Defines the `Lowercase` attached property.
179        pub fn lowercase_property() -> AttachedProperty<bool> {
180            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
181                "Lowercase",
182                StyledPropertyOptions::new(false).inherits(true),
183            )
184        }
185    );
186
187    /// Sets the value of the attached `Lowercase` property on a control.
188    pub fn set_lowercase(ferro_object: &StyledElement, value: bool) {
189        ferro_object.set_value(Self::lowercase_property(), value)
190    }
191
192    /// Gets the value of the attached `Lowercase` property of a control.
193    pub fn get_lowercase(ferro_object: &StyledElement) -> bool {
194        ferro_object.get_value(Self::lowercase_property())
195    }
196
197    ferro_property!(for TextInputOptions;
198        /// Defines the `Uppercase` attached property.
199        pub fn uppercase_property() -> AttachedProperty<bool> {
200            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
201                "Uppercase",
202                StyledPropertyOptions::new(false).inherits(true),
203            )
204        }
205    );
206
207    /// Sets the value of the attached `Uppercase` property on a control.
208    pub fn set_uppercase(ferro_object: &StyledElement, value: bool) {
209        ferro_object.set_value(Self::uppercase_property(), value)
210    }
211
212    /// Gets the value of the attached `Uppercase` property of a control.
213    pub fn get_uppercase(ferro_object: &StyledElement) -> bool {
214        ferro_object.get_value(Self::uppercase_property())
215    }
216
217    ferro_property!(for TextInputOptions;
218        /// Defines the `AutoCapitalization` attached property.
219        pub fn auto_capitalization_property() -> AttachedProperty<bool> {
220            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
221                "AutoCapitalization",
222                StyledPropertyOptions::new(false).inherits(true),
223            )
224        }
225    );
226
227    /// Sets the value of the attached `AutoCapitalization` property on a control.
228    pub fn set_auto_capitalization(ferro_object: &StyledElement, value: bool) {
229        ferro_object.set_value(Self::auto_capitalization_property(), value)
230    }
231
232    /// Gets the value of the attached `AutoCapitalization` property of a control.
233    pub fn get_auto_capitalization(ferro_object: &StyledElement) -> bool {
234        ferro_object.get_value(Self::auto_capitalization_property())
235    }
236
237    ferro_property!(for TextInputOptions;
238        /// Defines the `IsSensitive` attached property.
239        pub fn is_sensitive_property() -> AttachedProperty<bool> {
240            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
241                "IsSensitive",
242                StyledPropertyOptions::new(false).inherits(true),
243            )
244        }
245    );
246
247    /// Sets the value of the attached `IsSensitive` property on a control.
248    pub fn set_is_sensitive(ferro_object: &StyledElement, value: bool) {
249        ferro_object.set_value(Self::is_sensitive_property(), value)
250    }
251
252    /// Gets the value of the attached `IsSensitive` property of a control.
253    pub fn get_is_sensitive(ferro_object: &StyledElement) -> bool {
254        ferro_object.get_value(Self::is_sensitive_property())
255    }
256
257    ferro_property!(for TextInputOptions;
258        /// Defines the `ShowSuggestions` attached property.
259        pub fn show_suggestions_property() -> AttachedProperty<Option<bool>> {
260            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
261                "ShowSuggestions",
262                StyledPropertyOptions::new(None).inherits(true),
263            )
264        }
265    );
266
267    /// Sets the value of the attached `ShowSuggestions` property on a control.
268    pub fn set_show_suggestions(ferro_object: &StyledElement, value: Option<bool>) {
269        ferro_object.set_value(Self::show_suggestions_property(), value)
270    }
271
272    /// Gets the value of the attached `ShowSuggestions` property of a control.
273    pub fn get_show_suggestions(ferro_object: &StyledElement) -> Option<bool> {
274        ferro_object.get_value(Self::show_suggestions_property())
275    }
276
277    ferro_property!(for TextInputOptions;
278        /// Defines the `LocaleHints` attached property.
279        pub fn locale_hints_property() -> AttachedProperty<Option<Rc<[String]>>> {
280            FerroProperty::register_attached_with::<TextInputOptions, StyledElement, _>(
281                "LocaleHints",
282                StyledPropertyOptions::new(None).inherits(true),
283            )
284        }
285    );
286
287    /// Sets the value of the attached `LocaleHints` property on a control.
288    pub fn set_locale_hints(ferro_object: &StyledElement, value: Option<Rc<[String]>>) {
289        ferro_object.set_value(Self::locale_hints_property(), value)
290    }
291
292    /// Gets the value of the attached `LocaleHints` property of a control.
293    pub fn get_locale_hints(ferro_object: &StyledElement) -> Option<Rc<[String]>> {
294        ferro_object.get_value(Self::locale_hints_property())
295    }
296}