Skip to main content

ferroui_base/markup_types/
values.rs

1//! Markup metadata of the value types of this crate and of the types that
2//! convert from text: their `Parse(string)`, their public constructors and
3//! their static values, as the managed original declares them.
4
5use crate::animation::easings::Easing;
6use crate::animation::{Cue, IterationCount, IterationType, TimeSpan};
7use crate::data::core::ValueTypes;
8use crate::data::CultureInfoIetfLanguageTagConverter;
9use crate::utilities::{CultureInfo, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, Decimal, NumberStyles};
10use crate::ferro_markup_type;
11use crate::input::{Cursor, Key, KeyGesture, KeyModifiers, StandardCursorType};
12use crate::media::{
13    BoxShadow, BoxShadows, Color, FontFamily, FontFeature, FontFeatureCollection, FontWeight, HslColor, HsvColor,
14    TextDecorationCollection, TextDecorations,
15};
16use crate::metadata::{MarkupType, MarkupTyped};
17use crate::styling::ThemeVariant;
18use crate::utilities::{FormatError, Uri, UriKind};
19use crate::{
20    CornerRadius, Matrix, PixelPoint, PixelRect, PixelSize, PixelVector, Point, Rect, RelativePoint, RelativeRect,
21    RelativeScalar, RelativeUnit, RoundedRect, Size, Thickness, Vector, Vector3D,
22};
23use std::rc::Rc;
24
25// FerroUI
26
27ferro_markup_type!(struct Thickness {
28    namespace: "FerroUI",
29    handles: [Thickness],
30    parse: Thickness::parse,
31    constructors: [
32        () => Thickness::default,
33        (f64) => Thickness::uniform,
34        (f64, f64) => Thickness::symmetric,
35        (f64, f64, f64, f64) => Thickness::new,
36    ],
37    properties: [
38        Left: f64 { get: |t: &Thickness| t.left },
39        Top: f64 { get: |t: &Thickness| t.top },
40        Right: f64 { get: |t: &Thickness| t.right },
41        Bottom: f64 { get: |t: &Thickness| t.bottom },
42        IsUniform: bool { get: |t: &Thickness| t.is_uniform() },
43    ],
44});
45
46ferro_markup_type!(struct Point {
47    namespace: "FerroUI",
48    handles: [Point],
49    parse: Point::parse,
50    constructors: [() => Point::default, (f64, f64) => Point::new],
51    properties: [
52        X: f64 { get: |p: &Point| p.x },
53        Y: f64 { get: |p: &Point| p.y },
54    ],
55});
56
57ferro_markup_type!(struct Vector {
58    namespace: "FerroUI",
59    handles: [Vector],
60    parse: Vector::parse,
61    constructors: [() => Vector::default, (f64, f64) => Vector::new],
62    properties: [
63        X: f64 { get: |v: &Vector| v.x },
64        Y: f64 { get: |v: &Vector| v.y },
65        Length: f64 { get: |v: &Vector| v.length() },
66        SquaredLength: f64 { get: |v: &Vector| v.squared_length() },
67    ],
68});
69
70ferro_markup_type!(struct Size {
71    namespace: "FerroUI",
72    handles: [Size],
73    parse: Size::parse,
74    constructors: [() => Size::default, (f64, f64) => Size::new],
75    properties: [
76        Width: f64 { get: |s: &Size| s.width },
77        Height: f64 { get: |s: &Size| s.height },
78        AspectRatio: f64 { get: |s: &Size| s.aspect_ratio() },
79    ],
80});
81
82ferro_markup_type!(struct Rect {
83    namespace: "FerroUI",
84    handles: [Rect],
85    parse: Rect::parse,
86    constructors: [
87        () => Rect::default,
88        (f64, f64, f64, f64) => Rect::new,
89        (Size) => Rect::from_size,
90        (Point, Size) => Rect::from_position_size,
91        (Point, Point) => Rect::from_points,
92    ],
93    properties: [
94        X: f64 { get: |r: &Rect| r.x },
95        Y: f64 { get: |r: &Rect| r.y },
96        Width: f64 { get: |r: &Rect| r.width },
97        Height: f64 { get: |r: &Rect| r.height },
98        Position: Point { get: |r: &Rect| r.position() },
99        Size: Size { get: |r: &Rect| r.size() },
100        Right: f64 { get: |r: &Rect| r.right() },
101        Bottom: f64 { get: |r: &Rect| r.bottom() },
102        Left: f64 { get: |r: &Rect| r.left() },
103        Top: f64 { get: |r: &Rect| r.top() },
104        TopLeft: Point { get: |r: &Rect| r.top_left() },
105        TopRight: Point { get: |r: &Rect| r.top_right() },
106        BottomLeft: Point { get: |r: &Rect| r.bottom_left() },
107        BottomRight: Point { get: |r: &Rect| r.bottom_right() },
108        Center: Point { get: |r: &Rect| r.center() },
109    ],
110});
111
112ferro_markup_type!(struct Matrix {
113    namespace: "FerroUI",
114    handles: [Matrix],
115    parse: Matrix::parse,
116    constructors: [
117        () => Matrix::default,
118        (f64, f64, f64, f64, f64, f64) => Matrix::new,
119        (f64, f64, f64, f64, f64, f64, f64, f64, f64) => Matrix::new_3x3,
120    ],
121    properties: [
122        M11: f64 { get: |m: &Matrix| m.m11 },
123        M12: f64 { get: |m: &Matrix| m.m12 },
124        M13: f64 { get: |m: &Matrix| m.m13 },
125        M21: f64 { get: |m: &Matrix| m.m21 },
126        M22: f64 { get: |m: &Matrix| m.m22 },
127        M23: f64 { get: |m: &Matrix| m.m23 },
128        M31: f64 { get: |m: &Matrix| m.m31 },
129        M32: f64 { get: |m: &Matrix| m.m32 },
130        M33: f64 { get: |m: &Matrix| m.m33 },
131        IsIdentity: bool { get: |m: &Matrix| m.is_identity() },
132        HasInverse: bool { get: |m: &Matrix| m.has_inverse() },
133    ],
134});
135
136ferro_markup_type!(struct CornerRadius {
137    namespace: "FerroUI",
138    handles: [CornerRadius],
139    parse: CornerRadius::parse,
140    constructors: [
141        () => CornerRadius::default,
142        (f64) => CornerRadius::uniform,
143        (f64, f64) => CornerRadius::top_bottom,
144        (f64, f64, f64, f64) => CornerRadius::new,
145    ],
146    properties: [
147        TopLeft: f64 { get: |c: &CornerRadius| c.top_left },
148        TopRight: f64 { get: |c: &CornerRadius| c.top_right },
149        BottomRight: f64 { get: |c: &CornerRadius| c.bottom_right },
150        BottomLeft: f64 { get: |c: &CornerRadius| c.bottom_left },
151        IsUniform: bool { get: |c: &CornerRadius| c.is_uniform() },
152    ],
153});
154
155ferro_markup_type!(struct RelativePoint {
156    namespace: "FerroUI",
157    handles: [RelativePoint],
158    parse: RelativePoint::parse,
159    constructors: [
160        () => RelativePoint::default,
161        (f64, f64, RelativeUnit) => RelativePoint::new,
162        (Point, RelativeUnit) => RelativePoint::from_point,
163    ],
164    properties: [
165        Point: Point { get: |r: &RelativePoint| r.point },
166        Unit: RelativeUnit { get: |r: &RelativePoint| r.unit },
167    ],
168});
169
170ferro_markup_type!(struct RelativeRect {
171    namespace: "FerroUI",
172    handles: [RelativeRect],
173    parse: RelativeRect::parse,
174    constructors: [
175        () => RelativeRect::default,
176        (f64, f64, f64, f64, RelativeUnit) => RelativeRect::new,
177        (Rect, RelativeUnit) => RelativeRect::from_rect,
178        (Size, RelativeUnit) => RelativeRect::from_size,
179        (Point, Size, RelativeUnit) => RelativeRect::from_position_size,
180        (Point, Point, RelativeUnit) => RelativeRect::from_points,
181    ],
182    properties: [
183        Unit: RelativeUnit { get: |r: &RelativeRect| r.unit },
184        Rect: Rect { get: |r: &RelativeRect| r.rect },
185    ],
186});
187
188ferro_markup_type!(struct RelativeScalar {
189    namespace: "FerroUI",
190    handles: [RelativeScalar],
191    parse: RelativeScalar::parse,
192    constructors: [() => RelativeScalar::default, (f64, RelativeUnit) => RelativeScalar::new],
193    properties: [
194        Scalar: f64 { get: |r: &RelativeScalar| r.scalar },
195        Unit: RelativeUnit { get: |r: &RelativeScalar| r.unit },
196    ],
197});
198
199ferro_markup_type!(struct PixelPoint {
200    namespace: "FerroUI",
201    handles: [PixelPoint],
202    parse: PixelPoint::parse,
203    constructors: [() => PixelPoint::default, (i32, i32) => PixelPoint::new],
204    properties: [
205        X: i32 { get: |p: &PixelPoint| p.x },
206        Y: i32 { get: |p: &PixelPoint| p.y },
207    ],
208});
209
210ferro_markup_type!(struct PixelSize {
211    namespace: "FerroUI",
212    handles: [PixelSize],
213    parse: PixelSize::parse,
214    constructors: [() => PixelSize::default, (i32, i32) => PixelSize::new],
215    properties: [
216        Width: i32 { get: |p: &PixelSize| p.width },
217        Height: i32 { get: |p: &PixelSize| p.height },
218        AspectRatio: f64 { get: |p: &PixelSize| p.aspect_ratio() },
219    ],
220});
221
222ferro_markup_type!(struct PixelRect {
223    namespace: "FerroUI",
224    handles: [PixelRect],
225    parse: PixelRect::parse,
226    constructors: [
227        () => PixelRect::default,
228        (i32, i32, i32, i32) => PixelRect::new,
229        (PixelSize) => PixelRect::from_size,
230        (PixelPoint, PixelSize) => PixelRect::from_position_size,
231        (PixelPoint, PixelPoint) => PixelRect::from_points,
232    ],
233    properties: [
234        X: i32 { get: |p: &PixelRect| p.x },
235        Y: i32 { get: |p: &PixelRect| p.y },
236        Width: i32 { get: |p: &PixelRect| p.width },
237        Height: i32 { get: |p: &PixelRect| p.height },
238        Position: PixelPoint { get: |p: &PixelRect| p.position() },
239        Size: PixelSize { get: |p: &PixelRect| p.size() },
240        Right: i32 { get: |p: &PixelRect| p.right() },
241        Bottom: i32 { get: |p: &PixelRect| p.bottom() },
242        TopLeft: PixelPoint { get: |p: &PixelRect| p.top_left() },
243        TopRight: PixelPoint { get: |p: &PixelRect| p.top_right() },
244        BottomLeft: PixelPoint { get: |p: &PixelRect| p.bottom_left() },
245        BottomRight: PixelPoint { get: |p: &PixelRect| p.bottom_right() },
246        Center: PixelPoint { get: |p: &PixelRect| p.center() },
247    ],
248});
249
250ferro_markup_type!(struct PixelVector {
251    namespace: "FerroUI",
252    handles: [PixelVector],
253    constructors: [() => PixelVector::default, (i32, i32) => PixelVector::new],
254    properties: [
255        X: i32 { get: |p: &PixelVector| p.x },
256        Y: i32 { get: |p: &PixelVector| p.y },
257        Length: f64 { get: |p: &PixelVector| p.length() },
258    ],
259});
260
261ferro_markup_type!(struct Vector3D {
262    namespace: "FerroUI",
263    handles: [Vector3D],
264    parse: Vector3D::parse,
265    constructors: [() => Vector3D::default, (f64, f64, f64) => Vector3D::new],
266    properties: [
267        X: f64 { get: |v: &Vector3D| v.x },
268        Y: f64 { get: |v: &Vector3D| v.y },
269        Z: f64 { get: |v: &Vector3D| v.z },
270        Length: f64 { get: |v: &Vector3D| v.length() },
271    ],
272});
273
274ferro_markup_type!(struct RoundedRect {
275    namespace: "FerroUI",
276    handles: [RoundedRect],
277    constructors: [
278        () => RoundedRect::default,
279        (Rect) => RoundedRect::from_rect,
280        (Rect, f64) => RoundedRect::from_radius,
281        (Rect, f64, f64) => RoundedRect::from_radius_xy,
282        (Rect, Vector) => RoundedRect::from_uniform_radii,
283        (Rect, CornerRadius) => RoundedRect::from_corner_radius,
284    ],
285});
286
287// FerroUI.Media
288
289ferro_markup_type!(struct Color {
290    namespace: "FerroUI.Media",
291    handles: [Color],
292    parse: Color::parse,
293    constructors: [() => Color::default, (u8, u8, u8, u8) => Color::new],
294    methods: [
295        static fn FromArgb(u8, u8, u8, u8) -> Color => Color::from_argb,
296        static fn FromRgb(u8, u8, u8) -> Color => Color::from_rgb,
297        static fn FromUInt32(u32) -> Color => Color::from_uint32,
298    ],
299    properties: [
300        A: u8 { get: |c: &Color| c.a },
301        R: u8 { get: |c: &Color| c.r },
302        G: u8 { get: |c: &Color| c.g },
303        B: u8 { get: |c: &Color| c.b },
304    ],
305});
306
307ferro_markup_type!(struct HslColor {
308    namespace: "FerroUI.Media",
309    handles: [HslColor],
310    parse: HslColor::parse,
311    constructors: [
312        () => HslColor::default,
313        (f64, f64, f64, f64) => HslColor::new,
314        (Color) => HslColor::from_color,
315    ],
316    methods: [
317        static fn FromAhsl(f64, f64, f64, f64) -> HslColor => HslColor::from_ahsl,
318        static fn FromHsl(f64, f64, f64) -> HslColor => HslColor::from_hsl,
319    ],
320    properties: [
321        A: f64 { get: |h: &HslColor| h.a },
322        H: f64 { get: |h: &HslColor| h.h },
323        S: f64 { get: |h: &HslColor| h.s },
324        L: f64 { get: |h: &HslColor| h.l },
325    ],
326});
327
328ferro_markup_type!(struct HsvColor {
329    namespace: "FerroUI.Media",
330    handles: [HsvColor],
331    parse: HsvColor::parse,
332    constructors: [
333        () => HsvColor::default,
334        (f64, f64, f64, f64) => HsvColor::new,
335        (Color) => HsvColor::from_color,
336    ],
337    methods: [
338        static fn FromAhsv(f64, f64, f64, f64) -> HsvColor => HsvColor::from_ahsv,
339        static fn FromHsv(f64, f64, f64) -> HsvColor => HsvColor::from_hsv,
340    ],
341    properties: [
342        A: f64 { get: |h: &HsvColor| h.a },
343        H: f64 { get: |h: &HsvColor| h.h },
344        S: f64 { get: |h: &HsvColor| h.s },
345        V: f64 { get: |h: &HsvColor| h.v },
346    ],
347});
348
349// An enumeration in the managed original (any weight from 1 to 999 is a
350// value of it); the named weights are its members.
351ferro_markup_type!(struct FontWeight {
352    namespace: "FerroUI.Media",
353    handles: [FontWeight],
354    parse: |s: &str| s.parse::<FontWeight>(),
355    fields: [
356        Thin: FontWeight => || FontWeight::Thin,
357        ExtraLight: FontWeight => || FontWeight::ExtraLight,
358        UltraLight: FontWeight => || FontWeight::UltraLight,
359        Light: FontWeight => || FontWeight::Light,
360        SemiLight: FontWeight => || FontWeight::SemiLight,
361        Normal: FontWeight => || FontWeight::Normal,
362        Regular: FontWeight => || FontWeight::Regular,
363        Medium: FontWeight => || FontWeight::Medium,
364        DemiBold: FontWeight => || FontWeight::DemiBold,
365        SemiBold: FontWeight => || FontWeight::SemiBold,
366        Bold: FontWeight => || FontWeight::Bold,
367        ExtraBold: FontWeight => || FontWeight::ExtraBold,
368        UltraBold: FontWeight => || FontWeight::UltraBold,
369        Black: FontWeight => || FontWeight::Black,
370        Heavy: FontWeight => || FontWeight::Heavy,
371        Solid: FontWeight => || FontWeight::Solid,
372        ExtraBlack: FontWeight => || FontWeight::ExtraBlack,
373        UltraBlack: FontWeight => || FontWeight::UltraBlack,
374    ],
375    constructors: [() => FontWeight::default],
376});
377
378ferro_markup_type!(class FontFamily {
379    namespace: "FerroUI.Media",
380    handles: [FontFamily, Option<FontFamily>],
381    parse: FontFamily::parse,
382    constructors: [
383        (String) => |name: String| FontFamily::new(&name),
384        (Option<Uri>, String) => |base_uri: Option<Uri>, name: String| FontFamily::with_base_uri(base_uri.as_ref(), &name),
385    ],
386    static_properties: [Default: FontFamily { get: FontFamily::default_family }],
387    properties: [
388        // The primary family name.
389        Name: String { get: |family: &FontFamily| family.name().to_string() },
390    ],
391});
392
393ferro_markup_type!(class FontFeature {
394    namespace: "FerroUI.Media",
395    handles: [FontFeature, Option<FontFeature>],
396    parse: |s: &str| Ok::<_, FormatError>(FontFeature::parse(s)),
397});
398
399ferro_markup_type!(class FontFeatureCollection {
400    namespace: "FerroUI.Media",
401    handles: [FontFeatureCollection, Option<FontFeatureCollection>],
402    base: crate::collections::FerroList<FontFeature>,
403    parse: FontFeatureCollection::parse,
404    constructors: [() => FontFeatureCollection::new],
405    methods: [fn Add(FontFeature) => |c: &FontFeatureCollection, item: FontFeature| c.add(item)],
406});
407
408ferro_markup_type!(class TextDecorationCollection {
409    namespace: "FerroUI.Media",
410    handles: [TextDecorationCollection, Option<TextDecorationCollection>],
411    base: crate::collections::FerroList<crate::Ref<crate::media::TextDecoration>>,
412    parse: TextDecorationCollection::parse,
413    constructors: [() => TextDecorationCollection::new],
414    methods: [
415        fn Add(crate::Ref<crate::media::TextDecoration>) =>
416            |c: &TextDecorationCollection, item: crate::Ref<crate::media::TextDecoration>| c.add(item),
417    ],
418});
419
420ferro_markup_type!(static TextDecorations {
421    namespace: "FerroUI.Media",
422    static_properties: [
423        Underline: TextDecorationCollection { get: TextDecorations::underline },
424        Strikethrough: TextDecorationCollection { get: TextDecorations::strikethrough },
425        Overline: TextDecorationCollection { get: TextDecorations::overline },
426        Baseline: TextDecorationCollection { get: TextDecorations::baseline },
427    ],
428});
429
430ferro_markup_type!(struct BoxShadow {
431    namespace: "FerroUI.Media",
432    handles: [BoxShadow],
433    parse: BoxShadow::parse,
434    properties: [
435        OffsetX: f64 { get: |b: &BoxShadow| b.offset_x },
436        OffsetY: f64 { get: |b: &BoxShadow| b.offset_y },
437        Blur: f64 { get: |b: &BoxShadow| b.blur },
438        Spread: f64 { get: |b: &BoxShadow| b.spread },
439        Color: Color { get: |b: &BoxShadow| b.color },
440        IsInset: bool { get: |b: &BoxShadow| b.is_inset },
441    ],
442    constructors: [() => BoxShadow::default],
443});
444
445ferro_markup_type!(struct BoxShadows {
446    namespace: "FerroUI.Media",
447    handles: [BoxShadows],
448    parse: BoxShadows::parse,
449    constructors: [() => BoxShadows::default, (BoxShadow) => BoxShadows::new],
450});
451
452// FerroUI.Input
453
454ferro_markup_type!(class KeyGesture {
455    namespace: "FerroUI.Input",
456    handles: [KeyGesture, Option<KeyGesture>],
457    parse: KeyGesture::parse,
458    constructors: [
459        (Key) => KeyGesture::from_key,
460        (Key, KeyModifiers) => KeyGesture::new,
461    ],
462    properties: [
463        Key: Key { get: |k: &KeyGesture| k.key() },
464        KeyModifiers: KeyModifiers { get: |k: &KeyGesture| k.key_modifiers() },
465    ],
466});
467
468ferro_markup_type!(class Cursor {
469    this: Rc<Cursor>,
470    namespace: "FerroUI.Input",
471    handles: [Rc<Cursor>, Option<Rc<Cursor>>],
472    parse: Cursor::parse,
473    constructors: [(StandardCursorType) => Cursor::new],
474    fields: [Default: Rc<Cursor> => Cursor::default_cursor],
475});
476
477// FerroUI.Animation
478
479ferro_markup_type!(struct Cue {
480    namespace: "FerroUI.Animation",
481    handles: [Cue],
482    parse: Cue::parse,
483    properties: [
484        CueValue: f64 { get: |c: &Cue| c.cue_value() },
485    ],
486    constructors: [() => Cue::default],
487});
488
489ferro_markup_type!(struct IterationCount {
490    namespace: "FerroUI.Animation",
491    handles: [IterationCount],
492    parse: IterationCount::parse,
493    constructors: [
494        () => IterationCount::default,
495        (u64) => IterationCount::new,
496        (u64, IterationType) => IterationCount::with_type,
497    ],
498    properties: [
499        Value: u64 { get: |i: &IterationCount| i.value() },
500        RepeatType: IterationType { get: |i: &IterationCount| i.repeat_type() },
501        IsInfinite: bool { get: |i: &IterationCount| i.is_infinite() },
502    ],
503});
504
505// FerroUI.Animation.Easings
506
507ferro_markup_type!(class Easing {
508    namespace: "FerroUI.Animation.Easings",
509    handles: [Easing, Option<Easing>],
510    parse: Easing::parse,
511});
512
513// FerroUI.Styling
514
515ferro_markup_type!(class ThemeVariant {
516    namespace: "FerroUI.Styling",
517    handles: [ThemeVariant, Option<ThemeVariant>],
518    parse: |s: &str| s.parse::<ThemeVariant>(),
519    constructors: [
520        // The key is any object in the managed original.
521        try (Option<crate::BoxedValue>, Option<ThemeVariant>) =>
522            |key: Option<crate::BoxedValue>, inherit_variant: Option<ThemeVariant>| {
523                super::plain::resource_key(key).map(|key| ThemeVariant::new(key, inherit_variant))
524            },
525    ],
526    properties: [
527        // The key is any object in the managed original.
528        Key: Option<crate::BoxedValue> { get: |variant: &ThemeVariant| super::plain::resource_key_value(variant.key()) },
529        InheritVariant: Option<ThemeVariant> { get: ThemeVariant::inherit_variant },
530    ],
531    static_properties: [
532        Default: ThemeVariant { get: ThemeVariant::default },
533        Light: ThemeVariant { get: ThemeVariant::light },
534        Dark: ThemeVariant { get: ThemeVariant::dark },
535    ],
536});
537
538// System
539
540ferro_markup_type!(struct TimeSpan {
541    namespace: "System",
542    handles: [TimeSpan],
543    parse: TimeSpan::parse,
544    constructors: [() => TimeSpan::default, (i64) => TimeSpan::from_ticks],
545    methods: [
546        static fn FromTicks(i64) -> TimeSpan => TimeSpan::from_ticks,
547        static fn FromSeconds(f64) -> TimeSpan => TimeSpan::from_seconds,
548        static fn FromMilliseconds(f64) -> TimeSpan => TimeSpan::from_milliseconds,
549        static fn FromMinutes(f64) -> TimeSpan => TimeSpan::from_minutes,
550    ],
551    properties: [
552        Ticks: i64 { get: |t: &TimeSpan| t.ticks() },
553        TotalSeconds: f64 { get: |t: &TimeSpan| t.total_seconds() },
554        TotalMilliseconds: f64 { get: |t: &TimeSpan| t.total_milliseconds() },
555    ],
556});
557
558// The dates of the runtime library, written in the invariant culture.
559ferro_markup_type!(struct DateTime {
560    namespace: "System",
561    handles: [DateTime],
562    parse: |s: &str| DateTime::parse(s, &CultureInfo::invariant_culture()),
563    constructors: [() => DateTime::default],
564    // `static DateTime Now { get; }` and the like are static properties of the managed
565    // original; `MinValue` and `MaxValue` are its static read-only fields.
566    fields: [
567        MinValue: DateTime => || DateTime::MIN_VALUE,
568        MaxValue: DateTime => || DateTime::MAX_VALUE,
569    ],
570    static_properties: [
571        Now: DateTime { get: DateTime::now },
572        UtcNow: DateTime { get: DateTime::utc_now },
573        Today: DateTime { get: DateTime::today },
574    ],
575    // The components of a date, read by bindings (`{Binding Source={x:Static sys:DateTime.Today},
576    // Path=Day}` in the control theme of the calendar date picker).
577    properties: [
578        Date: DateTime { get: |d: &DateTime| d.date() },
579        Day: i32 { get: |d: &DateTime| d.day() },
580        DayOfWeek: DayOfWeek { get: |d: &DateTime| d.day_of_week() },
581        DayOfYear: i32 { get: |d: &DateTime| d.day_of_year() },
582        Hour: i32 { get: |d: &DateTime| d.hour() },
583        Kind: DateTimeKind { get: |d: &DateTime| d.kind() },
584        Millisecond: i32 { get: |d: &DateTime| d.millisecond() },
585        Minute: i32 { get: |d: &DateTime| d.minute() },
586        Month: i32 { get: |d: &DateTime| d.month() },
587        Second: i32 { get: |d: &DateTime| d.second() },
588        Ticks: i64 { get: |d: &DateTime| d.ticks() },
589        TimeOfDay: TimeSpan { get: |d: &DateTime| d.time_of_day() },
590        Year: i32 { get: |d: &DateTime| d.year() },
591    ],
592});
593
594ferro_markup_type!(struct DateTimeOffset {
595    namespace: "System",
596    handles: [DateTimeOffset],
597    parse: |s: &str| DateTimeOffset::parse(s, &CultureInfo::invariant_culture()),
598    constructors: [() => DateTimeOffset::default],
599});
600
601// The culture of the runtime library. Its conversion from text is the one of the converter
602// of the `ConverterCulture` property of the bindings: an IETF language tag.
603ferro_markup_type!(class CultureInfo {
604    namespace: "System.Globalization",
605    handles: [CultureInfo, Option<CultureInfo>],
606    parse: CultureInfoIetfLanguageTagConverter::convert_from,
607    static_properties: [
608        InvariantCulture: CultureInfo { get: CultureInfo::invariant_culture },
609        CurrentCulture: CultureInfo { get: CultureInfo::current_culture },
610    ],
611    properties: [
612        Name: String { get: |culture: &CultureInfo| culture.name().to_string() },
613    ],
614});
615
616ferro_markup_type!(class Uri {
617    namespace: "System",
618    handles: [Uri, Option<Uri>],
619    parse: |s: &str| Uri::new(s, UriKind::RelativeOrAbsolute),
620    constructors: [
621        try (String) => |uri: String| Uri::new(&uri, UriKind::Absolute),
622        try (String, UriKind) => |uri: String, kind: UriKind| Uri::new(&uri, kind),
623    ],
624});
625
626/// The types declared in this file.
627pub(super) const TYPES: &[&MarkupType] = &[
628    <Thickness as MarkupTyped>::MARKUP,
629    <Point as MarkupTyped>::MARKUP,
630    <Vector as MarkupTyped>::MARKUP,
631    <Size as MarkupTyped>::MARKUP,
632    <Rect as MarkupTyped>::MARKUP,
633    <Matrix as MarkupTyped>::MARKUP,
634    <CornerRadius as MarkupTyped>::MARKUP,
635    <RelativePoint as MarkupTyped>::MARKUP,
636    <RelativeRect as MarkupTyped>::MARKUP,
637    <RelativeScalar as MarkupTyped>::MARKUP,
638    <PixelPoint as MarkupTyped>::MARKUP,
639    <PixelSize as MarkupTyped>::MARKUP,
640    <PixelRect as MarkupTyped>::MARKUP,
641    <PixelVector as MarkupTyped>::MARKUP,
642    <Vector3D as MarkupTyped>::MARKUP,
643    <RoundedRect as MarkupTyped>::MARKUP,
644    <Color as MarkupTyped>::MARKUP,
645    <HslColor as MarkupTyped>::MARKUP,
646    <HsvColor as MarkupTyped>::MARKUP,
647    <FontWeight as MarkupTyped>::MARKUP,
648    <FontFamily as MarkupTyped>::MARKUP,
649    <FontFeature as MarkupTyped>::MARKUP,
650    <FontFeatureCollection as MarkupTyped>::MARKUP,
651    <TextDecorationCollection as MarkupTyped>::MARKUP,
652    <TextDecorations as MarkupTyped>::MARKUP,
653    <BoxShadow as MarkupTyped>::MARKUP,
654    <BoxShadows as MarkupTyped>::MARKUP,
655    <KeyGesture as MarkupTyped>::MARKUP,
656    <Cursor as MarkupTyped>::MARKUP,
657    <Cue as MarkupTyped>::MARKUP,
658    <IterationCount as MarkupTyped>::MARKUP,
659    <Easing as MarkupTyped>::MARKUP,
660    <ThemeVariant as MarkupTyped>::MARKUP,
661    <TimeSpan as MarkupTyped>::MARKUP,
662    <DateTime as MarkupTyped>::MARKUP,
663    <DateTimeOffset as MarkupTyped>::MARKUP,
664    <CultureInfo as MarkupTyped>::MARKUP,
665    // Declared next to the types.
666    <Decimal as MarkupTyped>::MARKUP,
667    <NumberStyles as MarkupTyped>::MARKUP,
668    <Uri as MarkupTyped>::MARKUP,
669];
670
671/// Registers the nullable forms of the value types with the untyped value
672/// conversions of the current thread.
673pub(super) fn register_value_types() {
674    ValueTypes::register_nullable::<Thickness>();
675    ValueTypes::register_nullable::<Point>();
676    ValueTypes::register_nullable::<Vector>();
677    ValueTypes::register_nullable::<Size>();
678    ValueTypes::register_nullable::<Rect>();
679    ValueTypes::register_nullable::<Matrix>();
680    ValueTypes::register_nullable::<CornerRadius>();
681    ValueTypes::register_nullable::<RelativePoint>();
682    ValueTypes::register_nullable::<RelativeRect>();
683    ValueTypes::register_nullable::<RelativeScalar>();
684    ValueTypes::register_nullable::<PixelPoint>();
685    ValueTypes::register_nullable::<PixelSize>();
686    ValueTypes::register_nullable::<PixelRect>();
687    ValueTypes::register_nullable::<PixelVector>();
688    ValueTypes::register_nullable::<Vector3D>();
689    ValueTypes::register_nullable::<RoundedRect>();
690    ValueTypes::register_nullable::<Color>();
691    ValueTypes::register_nullable::<HslColor>();
692    ValueTypes::register_nullable::<HsvColor>();
693    ValueTypes::register_nullable::<FontWeight>();
694    ValueTypes::register_nullable::<FontFamily>();
695    ValueTypes::register_nullable::<FontFeature>();
696    ValueTypes::register_nullable::<FontFeatureCollection>();
697    ValueTypes::register_nullable::<TextDecorationCollection>();
698    ValueTypes::register_nullable::<BoxShadow>();
699    ValueTypes::register_nullable::<BoxShadows>();
700    ValueTypes::register_nullable::<KeyGesture>();
701    ValueTypes::register_nullable::<Cue>();
702    ValueTypes::register_nullable::<IterationCount>();
703    ValueTypes::register_nullable::<Easing>();
704    ValueTypes::register_nullable::<ThemeVariant>();
705    ValueTypes::register_nullable::<TimeSpan>();
706    ValueTypes::register_nullable::<Uri>();
707    ValueTypes::register_nullable::<CultureInfo>();
708    ValueTypes::register_nullable::<Rc<Cursor>>();
709
710    // The text of a value (its `ToString()` in the managed original, what a string format
711    // or a binding to text shows): the value types that define one.
712    ValueTypes::register_display::<Thickness>();
713    ValueTypes::register_display::<Point>();
714    ValueTypes::register_display::<Vector>();
715    ValueTypes::register_display::<Size>();
716    ValueTypes::register_display::<Rect>();
717    ValueTypes::register_display::<Matrix>();
718    ValueTypes::register_display::<CornerRadius>();
719    ValueTypes::register_display::<RelativePoint>();
720    ValueTypes::register_display::<RelativeScalar>();
721    ValueTypes::register_display::<PixelPoint>();
722    ValueTypes::register_display::<PixelSize>();
723    ValueTypes::register_display::<PixelRect>();
724    ValueTypes::register_display::<PixelVector>();
725    ValueTypes::register_display::<Vector3D>();
726    ValueTypes::register_display::<Color>();
727    ValueTypes::register_display::<HslColor>();
728    ValueTypes::register_display::<HsvColor>();
729    ValueTypes::register_display::<FontWeight>();
730    ValueTypes::register_display::<FontFamily>();
731    ValueTypes::register_display::<FontFeature>();
732    ValueTypes::register_display::<BoxShadow>();
733    ValueTypes::register_display::<BoxShadows>();
734    ValueTypes::register_display::<KeyGesture>();
735    ValueTypes::register_display::<IterationCount>();
736    ValueTypes::register_display::<ThemeVariant>();
737    ValueTypes::register_display::<TimeSpan>();
738    ValueTypes::register_display::<DateTime>();
739    ValueTypes::register_display::<DateTimeOffset>();
740    ValueTypes::register_display::<Decimal>();
741    ValueTypes::register_nullable::<DateTime>();
742    ValueTypes::register_nullable::<DateTimeOffset>();
743    ValueTypes::register_nullable::<Decimal>();
744    ValueTypes::register_nullable::<NumberStyles>();
745    ValueTypes::register_display::<Uri>();
746    ValueTypes::register_display::<CultureInfo>();
747    ValueTypes::register_display::<Rc<Cursor>>();
748}