ferroui_xaml_interactivity/collections/
action_collection.rs1use crate::IAction;
4use ferroui_base::collections::{FerroList, NotifyCollectionChangedAction, NotifyCollectionChangedEventArgs, WeakFerroList};
5use ferroui_base::utilities::WeakEventSender;
6use ferroui_base::{FerroObject, Ref};
7use std::ops::Deref;
8use std::rc::Rc;
9
10#[derive(Clone, PartialEq)]
16pub struct ActionCollection(FerroList<Ref<FerroObject>>);
17
18impl ActionCollection {
19 pub fn new() -> Self {
21 let list: FerroList<Ref<FerroObject>> = FerroList::new();
22 let weak = list.downgrade_sender();
23 list.add_collection_changed(Rc::new(move |e: &NotifyCollectionChangedEventArgs<'_, Ref<FerroObject>>| {
24 Self::action_collection_collection_changed(&weak, e);
25 }));
26 Self(list)
27 }
28
29 pub fn list(&self) -> &FerroList<Ref<FerroObject>> {
31 &self.0
32 }
33
34 fn action_collection_collection_changed(
35 this: &WeakFerroList<Ref<FerroObject>>,
36 event_args: &NotifyCollectionChangedEventArgs<'_, Ref<FerroObject>>,
37 ) {
38 match event_args.action {
39 NotifyCollectionChangedAction::Reset => {
40 if let Some(this) = <FerroList<Ref<FerroObject>> as WeakEventSender>::upgrade_sender(this) {
41 for item in this.snapshot().iter() {
42 Self::verify_type(Some(item));
43 }
44 }
45 }
46 NotifyCollectionChangedAction::Add | NotifyCollectionChangedAction::Replace => {
47 let changed_item = event_args.new_items.first();
48 Self::verify_type(changed_item);
49 }
50 _ => {}
51 }
52 }
53
54 fn verify_type(item: Option<&Ref<FerroObject>>) {
55 let Some(item) = item else {
56 return;
57 };
58
59 if <dyn IAction>::of(item).is_none() {
60 panic!("Only IAction types are supported in an ActionCollection.");
61 }
62 }
63}
64
65impl Default for ActionCollection {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71impl Deref for ActionCollection {
72 type Target = FerroList<Ref<FerroObject>>;
73
74 fn deref(&self) -> &FerroList<Ref<FerroObject>> {
75 &self.0
76 }
77}
78
79impl std::fmt::Debug for ActionCollection {
80 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 write!(f, "ActionCollection({})", self.0.count())
82 }
83}