1use crate::documents::{Inline, InlineCollection};
7use crate::primitives::popup_positioning::{
8 CustomPopupPlacement, PopupAnchor, PopupGravity, PopupPositionerConstraintAdjustment,
9};
10use crate::primitives::CustomPopupPlacementCallbackValue;
11use crate::templates::{DataTemplates, IDataTemplate};
12use crate::{ItemsSourceView, NativeMenuItemBase, Page, StateTriggerBase, TableViewColumn, VisualState, VisualStateGroup};
13use ferroui_base::collections::FerroList;
14use crate::{
15 ColumnDefinition, ColumnDefinitions, Control, Controls, ItemCollection, RowDefinition, RowDefinitions, TrayIcon,
16 TrayIcons, WindowIcon,
17};
18use super::classes::RoutedEventOf;
19use crate::ScrollChangedEventArgs;
20use ferroui_base::data::core::ValueTypes;
21use ferroui_base::interactivity::{IRoutedEventArgs, RoutedEvent};
22use ferroui_base::animation::TimeSpan;
23use ferroui_base::Vector;
24use ferroui_base::ferro_markup_type;
25use ferroui_base::metadata::{MarkupDelegate, MarkupType, MarkupTyped};
26use ferroui_base::{BoxedValue, Point, Rect, Ref, Size, Thickness, Visual};
27use std::cell::RefCell;
28use std::rc::Rc;
29
30fn list_capacity<T: Clone>(list: &FerroList<T>) -> i32 {
32 i32::try_from(list.capacity()).unwrap_or(i32::MAX)
33}
34
35fn set_list_capacity<T: Clone>(list: &FerroList<T>, capacity: i32) -> Result<(), &'static str> {
38 match usize::try_from(capacity) {
39 Ok(capacity) if capacity >= list.count() => Ok(list.set_capacity(capacity)),
40 _ => Err("capacity was less than the current size."),
41 }
42}
43
44ferro_markup_type!(class Controls {
47 namespace: "FerroUI.Controls",
48 handles: [Controls, Option<Controls>],
49 base: FerroList<Ref<Control>>,
50 constructors: [() => Controls::new],
51 methods: [fn Add(Ref<Control>) => |controls: &Controls, item: Ref<Control>| controls.add(item)],
52});
53
54ferro_markup_type!(class RowDefinitions {
55 namespace: "FerroUI.Controls",
56 handles: [RowDefinitions, Option<RowDefinitions>],
57 base: FerroList<Ref<RowDefinition>>,
58 parse: RowDefinitions::parse,
59 constructors: [
60 () => RowDefinitions::new,
61 try (String) => |s: String| RowDefinitions::parse(&s),
62 ],
63 methods: [fn Add(Ref<RowDefinition>) => |definitions: &RowDefinitions, item: Ref<RowDefinition>| definitions.add(item)],
64 attributes: [FerroList(Separators = [",", " "])],
66});
67
68ferro_markup_type!(class ColumnDefinitions {
69 namespace: "FerroUI.Controls",
70 handles: [ColumnDefinitions, Option<ColumnDefinitions>],
71 base: FerroList<Ref<ColumnDefinition>>,
72 parse: ColumnDefinitions::parse,
73 constructors: [
74 () => ColumnDefinitions::new,
75 try (String) => |s: String| ColumnDefinitions::parse(&s),
76 ],
77 methods: [
78 fn Add(Ref<ColumnDefinition>) =>
79 |definitions: &ColumnDefinitions, item: Ref<ColumnDefinition>| definitions.add(item),
80 ],
81 attributes: [FerroList(Separators = [",", " "])],
83});
84
85ferro_markup_type!(class ItemCollection {
86 namespace: "FerroUI.Controls",
87 handles: [ItemCollection, Option<ItemCollection>],
88 methods: [fn Add(Option<BoxedValue>) -> i32 => |items: &ItemCollection, item: Option<BoxedValue>| items.add(item)],
89});
90
91ferro_markup_type!(class TrayIcons {
93 namespace: "FerroUI.Controls",
94 handles: [Rc<TrayIcons>, Option<Rc<TrayIcons>>],
95 this: Rc<TrayIcons>,
96 base: FerroList<Ref<TrayIcon>>,
97 constructors: [() => TrayIcons::new],
98 methods: [fn Add(Ref<TrayIcon>) => |icons: &Rc<TrayIcons>, item: Ref<TrayIcon>| icons.add(item)],
99});
100
101ferro_markup_type!(class WindowIcon {
102 namespace: "FerroUI.Controls",
103 handles: [Rc<WindowIcon>, Option<Rc<WindowIcon>>],
104});
105
106fn items_source_view_count(view: &Rc<ItemsSourceView>) -> Result<i32, &'static str> {
108 i32::try_from(view.count()).map_err(|_| "The number of items exceeds the range of Int32.")
109}
110
111fn items_source_view_get_at(view: &Rc<ItemsSourceView>, index: i32) -> Result<Option<BoxedValue>, &'static str> {
113 match usize::try_from(index) {
114 Ok(index) if index < view.count() => Ok(view.get_at(index)),
115 _ => Err("Index was out of range. Must be non-negative and less than the size of the collection."),
116 }
117}
118
119fn items_source_view_key_from_index(view: &Rc<ItemsSourceView>, index: i32) -> Result<String, &'static str> {
122 if !view.has_key_index_mapping() {
123 return Err("The items source does not implement IKeyIndexMapping.");
124 }
125 match usize::try_from(index) {
126 Ok(item) if item < view.count() => Ok(view.key_from_index(index)),
127 _ => Err("Argument index is invalid."),
128 }
129}
130
131fn items_source_view_index_from_key(view: &Rc<ItemsSourceView>, key: String) -> Result<i32, &'static str> {
133 if !view.has_key_index_mapping() {
134 return Err("The items source does not implement IKeyIndexMapping.");
135 }
136 Ok(view.index_from_key(&key))
137}
138
139ferro_markup_type!(class ItemsSourceView {
143 namespace: "FerroUI.Controls",
144 handles: [Rc<ItemsSourceView>, Option<Rc<ItemsSourceView>>],
145 this: Rc<ItemsSourceView>,
146 interfaces: [crate::ItemsSource],
147 constructors: [(crate::ItemsSource) => ItemsSourceView::new],
148 properties: [
149 Count: i32 { try_get: items_source_view_count },
150 HasKeyIndexMapping: bool { get: |view: &Rc<ItemsSourceView>| view.has_key_index_mapping() },
151 ],
152 methods: [
153 try fn GetAt(i32) -> Option<BoxedValue> => items_source_view_get_at,
154 fn IndexOf(Option<BoxedValue>) -> i32 => |view: &Rc<ItemsSourceView>, item: Option<BoxedValue>| view.index_of(&item),
155 try fn KeyFromIndex(i32) -> String => items_source_view_key_from_index,
156 try fn IndexFromKey(String) -> i32 => items_source_view_index_from_key,
157 ],
158});
159
160fn set_notification_expiration(
165 notification: &Rc<crate::notifications::Notification>,
166 value: TimeSpan,
167) -> Result<(), &'static str> {
168 match value.to_duration() {
169 Some(expiration) => Ok(notification.set_expiration(expiration)),
170 None => Err("The expiration of a notification cannot be negative."),
171 }
172}
173
174ferro_markup_type!(class crate::notifications::Notification as "Notification" {
178 namespace: "FerroUI.Controls.Notifications",
179 handles: [
180 crate::notifications::Notification,
181 Rc<crate::notifications::Notification>,
182 Option<Rc<crate::notifications::Notification>>
183 ],
184 this: Rc<crate::notifications::Notification>,
185 interfaces: [Rc<dyn crate::notifications::INotification>],
186 constructors: [() => crate::notifications::Notification::empty],
187 properties: [
188 Title: Option<String> {
189 get: |n: &Rc<crate::notifications::Notification>| n.title(),
190 set: |n: &Rc<crate::notifications::Notification>, value: Option<String>| n.set_title(value)
191 },
192 Message: Option<String> {
193 get: |n: &Rc<crate::notifications::Notification>| n.message(),
194 set: |n: &Rc<crate::notifications::Notification>, value: Option<String>| n.set_message(value)
195 },
196 Type: crate::notifications::NotificationType {
197 get: |n: &Rc<crate::notifications::Notification>| n.type_(),
198 set: |n: &Rc<crate::notifications::Notification>, value: crate::notifications::NotificationType| n.set_type(value)
199 },
200 Expiration: TimeSpan {
201 get: |n: &Rc<crate::notifications::Notification>| TimeSpan::from(n.expiration()),
202 try_set: set_notification_expiration
203 },
204 ],
205 notify_property_changed: crate::notifications::Notification,
206});
207
208ferro_markup_type!(class InlineCollection {
211 namespace: "FerroUI.Controls.Documents",
212 handles: [InlineCollection, Option<InlineCollection>],
213 base: FerroList<Ref<Inline>>,
214 constructors: [() => InlineCollection::new],
215 methods: [
216 fn Add(Ref<Inline>) => |inlines: &InlineCollection, inline: Ref<Inline>| inlines.add(inline),
217 fn Add(String) => |inlines: &InlineCollection, text: String| inlines.add_text(&text),
218 fn Add(Ref<Control>) => |inlines: &InlineCollection, control: Ref<Control>| inlines.add_control(control),
219 ],
220 attributes: [WhitespaceSignificantCollection],
221});
222
223ferro_markup_type!(class DataTemplates {
226 namespace: "FerroUI.Controls.Templates",
227 handles: [DataTemplates, Option<DataTemplates>],
228 base: FerroList<Rc<dyn IDataTemplate>>,
229 constructors: [() => DataTemplates::new],
230 methods: [
231 try fn Add(Rc<dyn IDataTemplate>) => |templates: &DataTemplates, item: Rc<dyn IDataTemplate>| {
233 if item.as_typed_data_template().is_some_and(|typed| typed.data_type().is_none()) {
234 return Err(
235 "DataTemplate inside of DataTemplates must have a DataType set. Set DataType property or use \
236 ItemTemplate with single template instead.",
237 );
238 }
239 Ok(templates.add(item))
240 },
241 ],
242});
243
244ferro_markup_type!(class CustomPopupPlacement {
249 namespace: "FerroUI.Controls.Primitives.PopupPositioning",
250 handles: [Rc<RefCell<CustomPopupPlacement>>, Option<Rc<RefCell<CustomPopupPlacement>>>],
251 this: Rc<RefCell<CustomPopupPlacement>>,
252 properties: [
253 PopupSize: Size { get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().popup_size() },
254 Deflate: Thickness { get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().deflate() },
255 Target: Ref<Visual> { get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().target() },
256 AnchorRectangle: Rect {
257 get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().anchor_rectangle,
258 set: |placement: &Rc<RefCell<CustomPopupPlacement>>, value: Rect| placement.borrow_mut().anchor_rectangle = value
259 },
260 Anchor: PopupAnchor {
261 get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().anchor(),
262 set: |placement: &Rc<RefCell<CustomPopupPlacement>>, value: PopupAnchor| placement.borrow_mut().set_anchor(value)
263 },
264 Gravity: PopupGravity {
265 get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().gravity(),
266 set: |placement: &Rc<RefCell<CustomPopupPlacement>>, value: PopupGravity| placement.borrow_mut().set_gravity(value)
267 },
268 ConstraintAdjustment: PopupPositionerConstraintAdjustment {
269 get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().constraint_adjustment,
270 set: |placement: &Rc<RefCell<CustomPopupPlacement>>, value: PopupPositionerConstraintAdjustment| {
271 placement.borrow_mut().constraint_adjustment = value
272 }
273 },
274 Offset: Point {
275 get: |placement: &Rc<RefCell<CustomPopupPlacement>>| placement.borrow().offset,
276 set: |placement: &Rc<RefCell<CustomPopupPlacement>>, value: Point| placement.borrow_mut().offset = value
277 },
278 ],
279});
280
281ferro_markup_type!(class CustomPopupPlacementCallbackValue as "CustomPopupPlacementCallback" {
285 namespace: "FerroUI.Controls.Primitives.PopupPositioning",
286 handles: [CustomPopupPlacementCallbackValue, Option<CustomPopupPlacementCallbackValue>],
287 base: MarkupDelegate,
288 methods: [
289 fn Invoke(Rc<RefCell<CustomPopupPlacement>>) =>
290 |callback: &CustomPopupPlacementCallbackValue, placement: Rc<RefCell<CustomPopupPlacement>>| {
291 (callback.0)(&mut placement.borrow_mut())
292 },
293 ],
294});
295
296fn custom_popup_placement_callback(method: &MarkupDelegate) -> CustomPopupPlacementCallbackValue {
299 let method = method.clone();
300 CustomPopupPlacementCallbackValue(Rc::new(move |placement: &mut CustomPopupPlacement| {
301 let shared = Rc::new(RefCell::new(placement.clone()));
302 method.invoke(&[Some(Rc::new(shared.clone()) as BoxedValue)]);
303 *placement = shared.borrow().clone();
304 }))
305}
306
307#[doc(hidden)]
312pub struct FerroListOf<T>(std::marker::PhantomData<T>);
313
314ferro_markup_type!(class FerroListOf<Ref<Control>> as "FerroList`1" {
317 namespace: "FerroUI.Collections",
318 handles: [FerroList<Ref<Control>>, Option<FerroList<Ref<Control>>>],
319 this: FerroList<Ref<Control>>,
320 generic: "FerroList`1" [Ref<Control>],
321 constructors: [() => FerroList::<Ref<Control>>::new],
322 properties: [
323 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
324 Count: i32 { get: |list: &FerroList<Ref<Control>>| list.count() as i32 },
325 ],
326 methods: [fn Add(Ref<Control>) => |list: &FerroList<Ref<Control>>, item: Ref<Control>| list.add(item)],
327});
328
329ferro_markup_type!(class FerroListOf<Ref<Inline>> as "FerroList`1" {
330 namespace: "FerroUI.Collections",
331 handles: [FerroList<Ref<Inline>>, Option<FerroList<Ref<Inline>>>],
332 this: FerroList<Ref<Inline>>,
333 generic: "FerroList`1" [Ref<Inline>],
334 constructors: [() => FerroList::<Ref<Inline>>::new],
335 properties: [
336 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
337 Count: i32 { get: |list: &FerroList<Ref<Inline>>| list.count() as i32 },
338 ],
339 methods: [fn Add(Ref<Inline>) => |list: &FerroList<Ref<Inline>>, item: Ref<Inline>| list.add(item)],
340});
341
342ferro_markup_type!(class FerroListOf<Rc<dyn IDataTemplate>> as "FerroList`1" {
343 namespace: "FerroUI.Collections",
344 handles: [FerroList<Rc<dyn IDataTemplate>>, Option<FerroList<Rc<dyn IDataTemplate>>>],
345 this: FerroList<Rc<dyn IDataTemplate>>,
346 generic: "FerroList`1" [Rc<dyn IDataTemplate>],
347 constructors: [() => FerroList::<Rc<dyn IDataTemplate>>::new],
348 properties: [
349 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
350 Count: i32 { get: |list: &FerroList<Rc<dyn IDataTemplate>>| list.count() as i32 },
351 ],
352 methods: [fn Add(Rc<dyn IDataTemplate>) => |list: &FerroList<Rc<dyn IDataTemplate>>, item: Rc<dyn IDataTemplate>| list.add(item)],
353});
354
355ferro_markup_type!(class FerroListOf<Ref<RowDefinition>> as "FerroList`1" {
356 namespace: "FerroUI.Collections",
357 handles: [FerroList<Ref<RowDefinition>>, Option<FerroList<Ref<RowDefinition>>>],
358 this: FerroList<Ref<RowDefinition>>,
359 generic: "FerroList`1" [Ref<RowDefinition>],
360 constructors: [() => FerroList::<Ref<RowDefinition>>::new],
361 properties: [
362 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
363 Count: i32 { get: |list: &FerroList<Ref<RowDefinition>>| list.count() as i32 },
364 ],
365 methods: [fn Add(Ref<RowDefinition>) => |list: &FerroList<Ref<RowDefinition>>, item: Ref<RowDefinition>| list.add(item)],
366});
367
368ferro_markup_type!(class FerroListOf<Ref<ColumnDefinition>> as "FerroList`1" {
369 namespace: "FerroUI.Collections",
370 handles: [FerroList<Ref<ColumnDefinition>>, Option<FerroList<Ref<ColumnDefinition>>>],
371 this: FerroList<Ref<ColumnDefinition>>,
372 generic: "FerroList`1" [Ref<ColumnDefinition>],
373 constructors: [() => FerroList::<Ref<ColumnDefinition>>::new],
374 properties: [
375 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
376 Count: i32 { get: |list: &FerroList<Ref<ColumnDefinition>>| list.count() as i32 },
377 ],
378 methods: [fn Add(Ref<ColumnDefinition>) => |list: &FerroList<Ref<ColumnDefinition>>, item: Ref<ColumnDefinition>| list.add(item)],
379});
380
381ferro_markup_type!(class FerroListOf<Ref<TrayIcon>> as "FerroList`1" {
382 namespace: "FerroUI.Collections",
383 handles: [FerroList<Ref<TrayIcon>>, Option<FerroList<Ref<TrayIcon>>>],
384 this: FerroList<Ref<TrayIcon>>,
385 generic: "FerroList`1" [Ref<TrayIcon>],
386 constructors: [() => FerroList::<Ref<TrayIcon>>::new],
387 properties: [
388 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
389 Count: i32 { get: |list: &FerroList<Ref<TrayIcon>>| list.count() as i32 },
390 ],
391 methods: [fn Add(Ref<TrayIcon>) => |list: &FerroList<Ref<TrayIcon>>, item: Ref<TrayIcon>| list.add(item)],
392});
393
394ferro_markup_type!(interface dyn crate::ICommandBarElement as "ICommandBarElement" {
396 namespace: "FerroUI.Controls",
397 handles: [Rc<dyn crate::ICommandBarElement>, Option<Rc<dyn crate::ICommandBarElement>>],
398});
399
400ferro_markup_type!(class FerroListOf<Rc<dyn crate::ICommandBarElement>> as "FerroList`1" {
401 namespace: "FerroUI.Collections",
402 handles: [FerroList<Rc<dyn crate::ICommandBarElement>>, Option<FerroList<Rc<dyn crate::ICommandBarElement>>>],
403 this: FerroList<Rc<dyn crate::ICommandBarElement>>,
404 generic: "FerroList`1" [Rc<dyn crate::ICommandBarElement>],
405 constructors: [() => FerroList::<Rc<dyn crate::ICommandBarElement>>::new],
406 properties: [
407 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
408 Count: i32 { get: |list: &FerroList<Rc<dyn crate::ICommandBarElement>>| list.count() as i32 },
409 ],
410 methods: [
411 fn Add(Rc<dyn crate::ICommandBarElement>) =>
412 |list: &FerroList<Rc<dyn crate::ICommandBarElement>>, item: Rc<dyn crate::ICommandBarElement>| list.add(item),
413 ],
414});
415
416ferro_markup_type!(class FerroListOf<Ref<NativeMenuItemBase>> as "FerroList`1" {
418 namespace: "FerroUI.Collections",
419 handles: [FerroList<Ref<NativeMenuItemBase>>, Option<FerroList<Ref<NativeMenuItemBase>>>],
420 this: FerroList<Ref<NativeMenuItemBase>>,
421 generic: "FerroList`1" [Ref<NativeMenuItemBase>],
422 constructors: [() => FerroList::<Ref<NativeMenuItemBase>>::new],
423 properties: [
424 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
425 Count: i32 { get: |list: &FerroList<Ref<NativeMenuItemBase>>| list.count() as i32 },
426 ],
427 methods: [
428 fn Add(Ref<NativeMenuItemBase>) =>
429 |list: &FerroList<Ref<NativeMenuItemBase>>, item: Ref<NativeMenuItemBase>| list.add(item),
430 ],
431});
432
433ferro_markup_type!(class FerroListOf<Ref<Page>> as "FerroList`1" {
435 namespace: "FerroUI.Collections",
436 handles: [FerroList<Ref<Page>>, Option<FerroList<Ref<Page>>>],
437 this: FerroList<Ref<Page>>,
438 generic: "FerroList`1" [Ref<Page>],
439 constructors: [() => FerroList::<Ref<Page>>::new],
440 properties: [
441 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
442 Count: i32 { get: |list: &FerroList<Ref<Page>>| list.count() as i32 },
443 ],
444 methods: [fn Add(Ref<Page>) => |list: &FerroList<Ref<Page>>, item: Ref<Page>| list.add(item)],
445});
446
447ferro_markup_type!(class FerroListOf<Ref<TableViewColumn>> as "FerroList`1" {
449 namespace: "FerroUI.Collections",
450 handles: [FerroList<Ref<TableViewColumn>>, Option<FerroList<Ref<TableViewColumn>>>],
451 this: FerroList<Ref<TableViewColumn>>,
452 generic: "FerroList`1" [Ref<TableViewColumn>],
453 constructors: [() => FerroList::<Ref<TableViewColumn>>::new],
454 properties: [
455 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
456 Count: i32 { get: |list: &FerroList<Ref<TableViewColumn>>| list.count() as i32 },
457 ],
458 methods: [fn Add(Ref<TableViewColumn>) => |list: &FerroList<Ref<TableViewColumn>>, item: Ref<TableViewColumn>| list.add(item)],
459});
460
461ferro_markup_type!(class FerroListOf<Ref<VisualStateGroup>> as "FerroList`1" {
463 namespace: "FerroUI.Collections",
464 handles: [FerroList<Ref<VisualStateGroup>>, Option<FerroList<Ref<VisualStateGroup>>>],
465 this: FerroList<Ref<VisualStateGroup>>,
466 generic: "FerroList`1" [Ref<VisualStateGroup>],
467 constructors: [() => FerroList::<Ref<VisualStateGroup>>::new],
468 properties: [
469 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
470 Count: i32 { get: |list: &FerroList<Ref<VisualStateGroup>>| list.count() as i32 },
471 ],
472 methods: [fn Add(Ref<VisualStateGroup>) => |list: &FerroList<Ref<VisualStateGroup>>, item: Ref<VisualStateGroup>| list.add(item)],
473});
474
475ferro_markup_type!(class FerroListOf<Ref<VisualState>> as "FerroList`1" {
477 namespace: "FerroUI.Collections",
478 handles: [FerroList<Ref<VisualState>>, Option<FerroList<Ref<VisualState>>>],
479 this: FerroList<Ref<VisualState>>,
480 generic: "FerroList`1" [Ref<VisualState>],
481 constructors: [() => FerroList::<Ref<VisualState>>::new],
482 properties: [
483 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
484 Count: i32 { get: |list: &FerroList<Ref<VisualState>>| list.count() as i32 },
485 ],
486 methods: [fn Add(Ref<VisualState>) => |list: &FerroList<Ref<VisualState>>, item: Ref<VisualState>| list.add(item)],
487});
488
489ferro_markup_type!(class FerroListOf<Ref<StateTriggerBase>> as "FerroList`1" {
491 namespace: "FerroUI.Collections",
492 handles: [FerroList<Ref<StateTriggerBase>>, Option<FerroList<Ref<StateTriggerBase>>>],
493 this: FerroList<Ref<StateTriggerBase>>,
494 generic: "FerroList`1" [Ref<StateTriggerBase>],
495 constructors: [() => FerroList::<Ref<StateTriggerBase>>::new],
496 properties: [
497 Capacity: i32 { get: list_capacity, try_set: set_list_capacity },
498 Count: i32 { get: |list: &FerroList<Ref<StateTriggerBase>>| list.count() as i32 },
499 ],
500 methods: [fn Add(Ref<StateTriggerBase>) => |list: &FerroList<Ref<StateTriggerBase>>, item: Ref<StateTriggerBase>| list.add(item)],
501});
502
503ferro_markup_type!(class RoutedEventOf<ScrollChangedEventArgs> as "RoutedEvent`1" {
509 namespace: "FerroUI.Interactivity",
510 handles: [RoutedEvent<ScrollChangedEventArgs>, Option<RoutedEvent<ScrollChangedEventArgs>>],
511 base: RoutedEvent,
512 generic: "RoutedEvent`1" [ScrollChangedEventArgs],
513});
514
515fn scroll_changed_event_args<R>(
517 e: &Rc<dyn IRoutedEventArgs>,
518 f: impl FnOnce(&ScrollChangedEventArgs) -> R,
519) -> Result<R, String> {
520 match e
521 .query_args(std::any::TypeId::of::<ScrollChangedEventArgs>())
522 .and_then(|args| args.downcast_ref::<ScrollChangedEventArgs>())
523 {
524 Some(args) => Ok(f(args)),
525 None => Err(format!("The arguments are not {}.", std::any::type_name::<ScrollChangedEventArgs>())),
526 }
527}
528
529ferro_markup_type!(class ScrollChangedEventArgs {
530 namespace: "FerroUI.Controls",
531 handles: [ScrollChangedEventArgs],
532 this: Rc<dyn IRoutedEventArgs>,
533 base: Rc<dyn IRoutedEventArgs>,
534 properties: [
535 ExtentDelta: Vector {
536 try_get: |e: &Rc<dyn IRoutedEventArgs>| scroll_changed_event_args(e, |e| e.extent_delta())
537 },
538 OffsetDelta: Vector {
539 try_get: |e: &Rc<dyn IRoutedEventArgs>| scroll_changed_event_args(e, |e| e.offset_delta())
540 },
541 ViewportDelta: Vector {
542 try_get: |e: &Rc<dyn IRoutedEventArgs>| scroll_changed_event_args(e, |e| e.viewport_delta())
543 },
544 ],
545});
546
547pub(super) const TYPES: &[&MarkupType] = &[
549 <crate::notifications::Notification as MarkupTyped>::MARKUP,
550 <RoutedEventOf<ScrollChangedEventArgs> as MarkupTyped>::MARKUP,
551 <ScrollChangedEventArgs as MarkupTyped>::MARKUP,
552 <dyn crate::ICommandBarElement as MarkupTyped>::MARKUP,
553 <FerroListOf<Rc<dyn crate::ICommandBarElement>> as MarkupTyped>::MARKUP,
554 <Controls as MarkupTyped>::MARKUP,
555 <RowDefinitions as MarkupTyped>::MARKUP,
556 <ColumnDefinitions as MarkupTyped>::MARKUP,
557 <ItemCollection as MarkupTyped>::MARKUP,
558 <TrayIcons as MarkupTyped>::MARKUP,
559 <FerroListOf<Ref<TrayIcon>> as MarkupTyped>::MARKUP,
560 <WindowIcon as MarkupTyped>::MARKUP,
561 <ItemsSourceView as MarkupTyped>::MARKUP,
562 <InlineCollection as MarkupTyped>::MARKUP,
563 <DataTemplates as MarkupTyped>::MARKUP,
564 <CustomPopupPlacement as MarkupTyped>::MARKUP,
565 <CustomPopupPlacementCallbackValue as MarkupTyped>::MARKUP,
566 <FerroListOf<Ref<Control>> as MarkupTyped>::MARKUP,
567 <FerroListOf<Ref<Inline>> as MarkupTyped>::MARKUP,
568 <FerroListOf<Rc<dyn IDataTemplate>> as MarkupTyped>::MARKUP,
569 <FerroListOf<Ref<RowDefinition>> as MarkupTyped>::MARKUP,
570 <FerroListOf<Ref<ColumnDefinition>> as MarkupTyped>::MARKUP,
571 <FerroListOf<Ref<NativeMenuItemBase>> as MarkupTyped>::MARKUP,
572 <FerroListOf<Ref<Page>> as MarkupTyped>::MARKUP,
573 <FerroListOf<Ref<TableViewColumn>> as MarkupTyped>::MARKUP,
574 <FerroListOf<Ref<VisualStateGroup>> as MarkupTyped>::MARKUP,
575 <FerroListOf<Ref<VisualState>> as MarkupTyped>::MARKUP,
576 <FerroListOf<Ref<StateTriggerBase>> as MarkupTyped>::MARKUP,
577];
578
579pub(super) fn register_value_types() {
582 ValueTypes::register_cast::<RoutedEvent<ScrollChangedEventArgs>, RoutedEvent>(|event| event.as_routed_event());
583 ValueTypes::register_nullable::<Rc<dyn crate::ICommandBarElement>>();
584 ValueTypes::register_nullable::<FerroList<Rc<dyn crate::ICommandBarElement>>>();
585 ValueTypes::register_nullable::<Controls>();
586 ValueTypes::register_nullable::<RowDefinitions>();
587 ValueTypes::register_nullable::<ColumnDefinitions>();
588 ValueTypes::register_nullable::<ItemCollection>();
589 ValueTypes::register_nullable::<InlineCollection>();
590 ValueTypes::register_nullable::<DataTemplates>();
591 ValueTypes::register_nullable::<FerroList<Ref<Control>>>();
592 ValueTypes::register_nullable::<FerroList<Ref<Inline>>>();
593 ValueTypes::register_nullable::<FerroList<Rc<dyn IDataTemplate>>>();
594 ValueTypes::register_nullable::<FerroList<Ref<RowDefinition>>>();
595 ValueTypes::register_nullable::<FerroList<Ref<ColumnDefinition>>>();
596 ValueTypes::register_nullable::<FerroList<Ref<NativeMenuItemBase>>>();
597 ValueTypes::register_nullable::<FerroList<Ref<Page>>>();
598 ValueTypes::register_nullable::<FerroList<Ref<TableViewColumn>>>();
599 ValueTypes::register_nullable::<FerroList<Ref<VisualStateGroup>>>();
600 ValueTypes::register_nullable::<FerroList<Ref<VisualState>>>();
601 ValueTypes::register_nullable::<FerroList<Ref<StateTriggerBase>>>();
602 ValueTypes::register_nullable::<Rc<WindowIcon>>();
603 ValueTypes::register_nullable::<Rc<RefCell<CustomPopupPlacement>>>();
604 ValueTypes::register_nullable::<CustomPopupPlacementCallbackValue>();
605 ValueTypes::register_cast::<MarkupDelegate, CustomPopupPlacementCallbackValue>(custom_popup_placement_callback);
608 ValueTypes::register_nullable::<crate::ItemsSource>();
613 ValueTypes::register_nullable::<crate::primitives::SelectedItemsList>();
614 crate::notifications::Notification::ensure_registered();
616 crate::ItemsSource::register_binding_conversion::<crate::ItemsSource>();
617 ValueTypes::register_cast::<crate::primitives::SelectedItemsList, crate::ItemsSource>(|list| {
621 crate::ItemsSource::from(list.0.clone())
622 });
623 ValueTypes::register_conversion::<crate::primitives::SelectedItemsList, Option<crate::ItemsSource>>(|list| {
624 Some(Some(crate::ItemsSource::from(list.0.clone())))
625 });
626 crate::ItemsSource::register_binding_conversion_with::<Rc<dyn ferroui_base::media::fonts::IFontCollection>>(|fonts| {
631 crate::ItemsSource::from_values(fonts.font_families())
632 });
633 ValueTypes::register_cast::<Rc<FerroList<Option<BoxedValue>>>, crate::ItemsSource>(|list| {
636 crate::ItemsSource::from(list.clone())
637 });
638 ValueTypes::register_cast::<Vec<BoxedValue>, crate::ItemsSource>(|items| crate::ItemsSource::from(items.clone()));
644 ValueTypes::register_conversion::<Vec<BoxedValue>, Option<crate::ItemsSource>>(|items| {
645 Some(Some(crate::ItemsSource::from(items.clone())))
646 });
647 ValueTypes::register_cast::<Vec<Option<BoxedValue>>, crate::ItemsSource>(|items| {
648 crate::ItemsSource::from(items.clone())
649 });
650 ValueTypes::register_conversion::<Vec<Option<BoxedValue>>, Option<crate::ItemsSource>>(|items| {
651 Some(Some(crate::ItemsSource::from(items.clone())))
652 });
653 ValueTypes::register_nullable::<Rc<ItemsSourceView>>();
657 ValueTypes::register_cast::<Rc<ItemsSourceView>, crate::ItemsSource>(|view| crate::ItemsSource::from(view.clone()));
658 ValueTypes::register_conversion::<Rc<ItemsSourceView>, Option<crate::ItemsSource>>(|view| {
659 Some(Some(crate::ItemsSource::from(view.clone())))
660 });
661 ValueTypes::register_nullable::<Rc<TrayIcons>>();
662 ValueTypes::register_nullable::<FerroList<Ref<TrayIcon>>>();
663 ValueTypes::register_cast::<Rc<TrayIcons>, FerroList<Ref<TrayIcon>>>(|c| (***c).clone());
664 ValueTypes::register_cast::<Controls, FerroList<Ref<Control>>>(|c| (**c).clone());
665 ValueTypes::register_cast::<InlineCollection, FerroList<Ref<Inline>>>(|c| (**c).clone());
666 ValueTypes::register_cast::<DataTemplates, FerroList<Rc<dyn IDataTemplate>>>(|c| (**c).clone());
667 ValueTypes::register_cast::<RowDefinitions, FerroList<Ref<RowDefinition>>>(|c| (***c).clone());
668 ValueTypes::register_cast::<ColumnDefinitions, FerroList<Ref<ColumnDefinition>>>(|c| (***c).clone());
669 ValueTypes::register_deref::<Controls, FerroList<Ref<Control>>>(|c| c);
672 ValueTypes::register_deref::<InlineCollection, FerroList<Ref<Inline>>>(|c| c);
673 ValueTypes::register_deref::<DataTemplates, FerroList<Rc<dyn IDataTemplate>>>(|c| c);
674 ValueTypes::register_deref::<RowDefinitions, FerroList<Ref<RowDefinition>>>(|c| c);
675 ValueTypes::register_deref::<ColumnDefinitions, FerroList<Ref<ColumnDefinition>>>(|c| c);
676}