Skip to main content

ferroui_controls/markup_types/
contracts.rs

1//! Markup metadata of the contracts of this crate that are types of
2//! members markup can set: each is published under the name of the
3//! interface of the managed original, with the handle types the members of
4//! this port use for it.
5//!
6//! A contract whose handle does not compare (`PartialEq`) cannot be held in
7//! an untyped value yet; it is declared so that the type is known by name.
8
9use crate::chrome::IWindowDrawnDecorationsTemplate;
10use crate::primitives::IPopupHost;
11use crate::selection::ISelectionModel;
12use crate::templates::{
13    IControlTemplate, IDataTemplate, IRecyclingDataTemplate, ITemplateOf, ITreeDataTemplate, ITypedDataTemplate,
14};
15use crate::documents::Inline;
16use crate::{Control, Panel};
17use ferroui_base::data::core::ValueTypes;
18use ferroui_base::ferro_markup_type;
19use ferroui_base::metadata::{IAddChild, MarkupType, MarkupTyped};
20use ferroui_base::styling::ITemplate;
21use ferroui_base::Ref;
22use std::rc::Rc;
23
24// FerroUI.Metadata
25
26// The instantiations of `IAddChild<T>` for the children of this crate. The
27// contract belongs to the base crate, so each is declared on a marker.
28
29/// Carries the metadata of `IAddChild<T>` for a child type of this crate.
30#[doc(hidden)]
31pub struct AddChildOf<T>(std::marker::PhantomData<T>);
32
33ferro_markup_type!(interface AddChildOf<Ref<Control>> as "IAddChild`1" {
34    namespace: "FerroUI.Metadata",
35    handles: [Rc<dyn IAddChild<Ref<Control>>>, Option<Rc<dyn IAddChild<Ref<Control>>>>],
36    this: Rc<dyn IAddChild<Ref<Control>>>,
37    generic: "IAddChild`1" [Ref<Control>],
38    methods: [
39        fn AddChild(Ref<Control>) => |this: &Rc<dyn IAddChild<Ref<Control>>>, child: Ref<Control>| this.add_child(child),
40    ],
41});
42
43ferro_markup_type!(interface AddChildOf<Ref<Inline>> as "IAddChild`1" {
44    namespace: "FerroUI.Metadata",
45    handles: [Rc<dyn IAddChild<Ref<Inline>>>, Option<Rc<dyn IAddChild<Ref<Inline>>>>],
46    this: Rc<dyn IAddChild<Ref<Inline>>>,
47    generic: "IAddChild`1" [Ref<Inline>],
48    methods: [
49        fn AddChild(Ref<Inline>) => |this: &Rc<dyn IAddChild<Ref<Inline>>>, child: Ref<Inline>| this.add_child(child),
50    ],
51});
52
53// FerroUI.Controls.Templates
54
55ferro_markup_type!(interface dyn IDataTemplate as "IDataTemplate" {
56    namespace: "FerroUI.Controls.Templates",
57    handles: [Rc<dyn IDataTemplate>, Option<Rc<dyn IDataTemplate>>],
58});
59
60ferro_markup_type!(interface dyn ITreeDataTemplate as "ITreeDataTemplate" {
61    namespace: "FerroUI.Controls.Templates",
62    handles: [Rc<dyn ITreeDataTemplate>, Option<Rc<dyn ITreeDataTemplate>>],
63    interfaces: [Rc<dyn IDataTemplate>],
64});
65
66ferro_markup_type!(interface dyn IRecyclingDataTemplate as "IRecyclingDataTemplate" {
67    namespace: "FerroUI.Controls.Templates",
68    handles: [Rc<dyn IRecyclingDataTemplate>, Option<Rc<dyn IRecyclingDataTemplate>>],
69    interfaces: [Rc<dyn IDataTemplate>],
70});
71
72// `DataType` (with `[DataType]`) is left out: the port identifies the type by a
73// `TypeId`, and a type-typed member is published as a runtime type only.
74ferro_markup_type!(interface dyn ITypedDataTemplate as "ITypedDataTemplate" {
75    namespace: "FerroUI.Controls.Templates",
76    handles: [Rc<dyn ITypedDataTemplate>, Option<Rc<dyn ITypedDataTemplate>>],
77    interfaces: [Rc<dyn IDataTemplate>],
78});
79
80ferro_markup_type!(interface dyn IControlTemplate as "IControlTemplate" {
81    namespace: "FerroUI.Controls.Templates",
82    handles: [Rc<dyn IControlTemplate>, Option<Rc<dyn IControlTemplate>>],
83    attributes: [ControlTemplateScope],
84});
85
86// The instantiations of `ITemplate<TControl>` that are types of properties.
87
88ferro_markup_type!(interface dyn ITemplateOf<Option<Ref<Control>>> as "ITemplate`1" {
89    namespace: "FerroUI.Controls",
90    handles: [Rc<dyn ITemplateOf<Option<Ref<Control>>>>, Option<Rc<dyn ITemplateOf<Option<Ref<Control>>>>>],
91    interfaces: [Rc<dyn ITemplate>],
92    generic: "ITemplate`1" [Option<Ref<Control>>],
93});
94
95ferro_markup_type!(interface dyn ITemplateOf<Ref<Control>> as "ITemplate`1" {
96    namespace: "FerroUI.Controls",
97    handles: [Rc<dyn ITemplateOf<Ref<Control>>>, Option<Rc<dyn ITemplateOf<Ref<Control>>>>],
98    interfaces: [Rc<dyn ITemplate>],
99    generic: "ITemplate`1" [Ref<Control>],
100});
101
102ferro_markup_type!(interface dyn ITemplateOf<Option<Ref<Panel>>> as "ITemplate`1" {
103    namespace: "FerroUI.Controls",
104    handles: [Rc<dyn ITemplateOf<Option<Ref<Panel>>>>, Option<Rc<dyn ITemplateOf<Option<Ref<Panel>>>>>],
105    interfaces: [Rc<dyn ITemplate>],
106    generic: "ITemplate`1" [Option<Ref<Panel>>],
107});
108
109// FerroUI.Controls.Chrome
110
111ferro_markup_type!(interface dyn IWindowDrawnDecorationsTemplate as "IWindowDrawnDecorationsTemplate" {
112    namespace: "FerroUI.Controls.Chrome",
113    handles: [Rc<dyn IWindowDrawnDecorationsTemplate>, Option<Rc<dyn IWindowDrawnDecorationsTemplate>>],
114    attributes: [ControlTemplateScope],
115});
116
117// FerroUI.Controls.Selection
118
119ferro_markup_type!(interface dyn ISelectionModel as "ISelectionModel" {
120    namespace: "FerroUI.Controls.Selection",
121    handles: [Rc<dyn ISelectionModel>, Option<Rc<dyn ISelectionModel>>],
122});
123
124// FerroUI.Controls.Primitives
125
126ferro_markup_type!(interface dyn IPopupHost as "IPopupHost" {
127    namespace: "FerroUI.Controls.Primitives",
128    handles: [Rc<dyn IPopupHost>, Option<Rc<dyn IPopupHost>>],
129});
130
131// System.Collections
132
133// The collection handle of the items controls is the enumerable of the managed original
134// (`IEnumerable? ItemsSource`): a collection created in markup is assignable to a property
135// that holds the handle.
136// Deviation (DEVIATIONS.md, Run-time type system of markup): upstream assigns any enumerable;
137// here a collection is cast to the handle by the cast registered for its type.
138ferro_markup_type!(interface crate::ItemsSource as "IEnumerable" {
139    namespace: "System.Collections",
140    handles: [crate::ItemsSource, Option<crate::ItemsSource>],
141});
142
143/// The types declared in this file.
144// FerroUI.Controls.Notifications: the data type of the notification templates of the themes.
145ferro_markup_type!(interface dyn crate::notifications::INotification as "INotification" {
146    namespace: "FerroUI.Controls.Notifications",
147    handles: [
148        Rc<dyn crate::notifications::INotification>,
149        Option<Rc<dyn crate::notifications::INotification>>
150    ],
151    this: Rc<dyn crate::notifications::INotification>,
152    properties: [
153        Title: Option<String> { get: |n: &Rc<dyn crate::notifications::INotification>| n.title() },
154        Message: Option<String> { get: |n: &Rc<dyn crate::notifications::INotification>| n.message() },
155        Type: crate::notifications::NotificationType { get: |n: &Rc<dyn crate::notifications::INotification>| n.type_() },
156    ],
157});
158
159pub(super) const TYPES: &[&MarkupType] = &[
160    <dyn crate::notifications::INotification as MarkupTyped>::MARKUP,
161    <AddChildOf<Ref<Control>> as MarkupTyped>::MARKUP,
162    <AddChildOf<Ref<Inline>> as MarkupTyped>::MARKUP,
163    <dyn IDataTemplate as MarkupTyped>::MARKUP,
164    <dyn ITreeDataTemplate as MarkupTyped>::MARKUP,
165    <dyn IRecyclingDataTemplate as MarkupTyped>::MARKUP,
166    <dyn ITypedDataTemplate as MarkupTyped>::MARKUP,
167    <dyn IControlTemplate as MarkupTyped>::MARKUP,
168    <dyn ITemplateOf<Option<Ref<Control>>> as MarkupTyped>::MARKUP,
169    <dyn ITemplateOf<Ref<Control>> as MarkupTyped>::MARKUP,
170    <dyn ITemplateOf<Option<Ref<Panel>>> as MarkupTyped>::MARKUP,
171    <dyn IWindowDrawnDecorationsTemplate as MarkupTyped>::MARKUP,
172    <dyn ISelectionModel as MarkupTyped>::MARKUP,
173    <dyn IPopupHost as MarkupTyped>::MARKUP,
174    <crate::ItemsSource as MarkupTyped>::MARKUP,
175];
176
177/// Registers the nullable forms of the contract handles that can be held in
178/// untyped values with the untyped value conversions of the current thread.
179pub(super) fn register_value_types() {
180    ValueTypes::register_nullable::<Rc<dyn crate::notifications::INotification>>();
181    ValueTypes::register_nullable::<Rc<dyn IAddChild<Ref<Control>>>>();
182    ValueTypes::register_nullable::<Rc<dyn IAddChild<Ref<Inline>>>>();
183    ValueTypes::register_nullable::<Rc<dyn IDataTemplate>>();
184    ValueTypes::register_nullable::<Rc<dyn IControlTemplate>>();
185    ValueTypes::register_nullable::<Rc<dyn ITemplateOf<Option<Ref<Control>>>>>();
186    ValueTypes::register_nullable::<Rc<dyn ITemplateOf<Ref<Control>>>>();
187    ValueTypes::register_nullable::<Rc<dyn ITemplateOf<Option<Ref<Panel>>>>>();
188    ValueTypes::register_nullable::<Rc<dyn IWindowDrawnDecorationsTemplate>>();
189    ValueTypes::register_nullable::<Rc<dyn ISelectionModel>>();
190    ValueTypes::register_nullable::<Rc<dyn IPopupHost>>();
191    // The data template contracts derive from the data template.
192    ValueTypes::register_nullable::<Rc<dyn ITreeDataTemplate>>();
193    ValueTypes::register_nullable::<Rc<dyn IRecyclingDataTemplate>>();
194    ValueTypes::register_nullable::<Rc<dyn ITypedDataTemplate>>();
195    ValueTypes::register_cast::<Rc<dyn ITreeDataTemplate>, Rc<dyn IDataTemplate>>(|t| t.clone());
196    ValueTypes::register_cast::<Rc<dyn IRecyclingDataTemplate>, Rc<dyn IDataTemplate>>(|t| t.clone());
197    ValueTypes::register_cast::<Rc<dyn ITypedDataTemplate>, Rc<dyn IDataTemplate>>(|t| t.clone());
198    // A typed template is a template.
199    ValueTypes::register_cast::<Rc<dyn ITemplateOf<Option<Ref<Control>>>>, Rc<dyn ITemplate>>(|t| t.clone());
200    ValueTypes::register_cast::<Rc<dyn ITemplateOf<Ref<Control>>>, Rc<dyn ITemplate>>(|t| t.clone());
201    ValueTypes::register_cast::<Rc<dyn ITemplateOf<Option<Ref<Panel>>>>, Rc<dyn ITemplate>>(|t| t.clone());
202}