ferroui_diagnostics/diagnostics/controls/
top_level_group.rs1use crate::diagnostics::IDevToolsTopLevelGroup;
4use ferroui_base::collections::NotifyCollectionChangedEventArgs;
5use ferroui_base::reactive::{Disposable, IDisposable};
6use ferroui_base::utilities::HandlerList;
7use ferroui_base::{ferro_class, ferro_class_info, instantiate, FerroObject, FerroObjectImpl, FerroObjectImplExt, Ref};
8use ferroui_controls::TopLevel;
9use std::rc::Rc;
10
11#[repr(C)]
14pub struct TopLevelGroup {
15 base: FerroObject,
16 group: Rc<dyn IDevToolsTopLevelGroup>,
17 added: HandlerList<dyn Fn(&Ref<TopLevel>)>,
18 removed: HandlerList<dyn Fn(&Ref<TopLevel>)>,
19}
20
21ferro_class!(TopLevelGroup: FerroObject);
22ferro_class_info!(TopLevelGroup {});
23
24impl FerroObjectImpl for TopLevelGroup {
25 fn constructed(this: &Self) {
26 Self::parent_constructed(this);
27
28 if let Some(incc) = this.group.observable_items() {
29 let weak = this.to_ref().downgrade();
30 incc.add_collection_changed(Rc::new(move |args: &NotifyCollectionChangedEventArgs<'_, Ref<TopLevel>>| {
31 let Some(this) = weak.upgrade() else {
32 return;
33 };
34
35 for old_item in args.old_items {
36 for (_, handler) in this.removed.snapshot().iter() {
37 handler(old_item);
38 }
39 }
40
41 for new_item in args.new_items {
42 for (_, handler) in this.added.snapshot().iter() {
43 handler(new_item);
44 }
45 }
46 }));
47 }
48 }
49}
50
51impl TopLevelGroup {
52 pub fn construct(group: Rc<dyn IDevToolsTopLevelGroup>) -> Self {
53 Self { base: FerroObject::construct(), group, added: HandlerList::new(), removed: HandlerList::new() }
54 }
55
56 pub fn new(group: Rc<dyn IDevToolsTopLevelGroup>) -> Ref<Self> {
58 instantiate(Self::construct(group))
59 }
60
61 pub fn group(&self) -> Rc<dyn IDevToolsTopLevelGroup> {
62 self.group.clone()
63 }
64
65 pub fn items(&self) -> Vec<Ref<TopLevel>> {
66 self.group.items()
67 }
68
69 pub fn added(&self, handler: impl Fn(&Ref<TopLevel>) + 'static) -> Rc<dyn IDisposable> {
71 let token = self.added.add(Rc::new(handler));
72 let weak = self.to_ref().downgrade();
73 Disposable::create(move || {
74 if let Some(this) = weak.upgrade() {
75 this.added.remove(token);
76 }
77 })
78 }
79
80 pub fn removed(&self, handler: impl Fn(&Ref<TopLevel>) + 'static) -> Rc<dyn IDisposable> {
82 let token = self.removed.add(Rc::new(handler));
83 let weak = self.to_ref().downgrade();
84 Disposable::create(move || {
85 if let Some(this) = weak.upgrade() {
86 this.removed.remove(token);
87 }
88 })
89 }
90}