ferroui_xaml_interactivity/events/
add_event_handler_registry.rs1use super::handlers::{FlyoutEventHandler, FuncAddEventHandler};
4use super::{AddEventHandlerCallback, IAddEventHandler};
5use ferroui_base::interactivity::{CancelRoutedEventArgs, RoutedEventArgs, RoutedEventHandlerToken};
6use ferroui_base::reactive::IDisposable;
7use ferroui_base::{BoxedValue, Ref};
8use ferroui_controls::{Button, Control, MenuItem, ToolTip};
9use std::cell::RefCell;
10use std::rc::Rc;
11
12pub struct AddEventHandlerRegistry;
17
18ferroui_base::ferro_thread_local! {
19 static ADD_EVENT_HANDLERS: RefCell<Vec<Rc<dyn IAddEventHandler>>> = RefCell::new(AddEventHandlerRegistry::default_handlers());
20}
21
22impl AddEventHandlerRegistry {
23 fn default_handlers() -> Vec<Rc<dyn IAddEventHandler>> {
25 let mut handlers: Vec<Rc<dyn IAddEventHandler>> = Vec::new();
26
27 handlers.push(Rc::new(FuncAddEventHandler::<Ref<Button>, RoutedEventArgs, RoutedEventHandlerToken>::new(
30 "Click",
31 |o, h| o.click(move |sender, e| h(Some(&(Rc::new(sender.to_ref()) as BoxedValue)), e)),
32 |o, h| {
33 o.remove_handler(Button::click_event(), h);
34 },
35 )));
36
37 handlers.push(Rc::new(FuncAddEventHandler::<Ref<MenuItem>, RoutedEventArgs, RoutedEventHandlerToken>::new(
38 "Click",
39 |o, h| o.click(move |sender, e| h(Some(&(Rc::new(sender.to_ref()) as BoxedValue)), e)),
40 |o, h| {
41 o.remove_handler(MenuItem::click_event(), h);
42 },
43 )));
44
45 handlers.push(Rc::new(FlyoutEventHandler));
46
47 handlers.push(Rc::new(FuncAddEventHandler::<Ref<Control>, CancelRoutedEventArgs, RoutedEventHandlerToken>::new(
48 "ToolTipOpening",
49 |o, h| ToolTip::add_tool_tip_opening_handler(o, move |sender, e| h(Some(&(Rc::new(sender.to_ref()) as BoxedValue)), e)),
50 |o, h| ToolTip::remove_tool_tip_opening_handler(o, h),
51 )));
52
53 handlers.push(Rc::new(FuncAddEventHandler::<Ref<Control>, RoutedEventArgs, RoutedEventHandlerToken>::new(
54 "ToolTipClosing",
55 |o, h| ToolTip::add_tool_tip_closing_handler(o, move |sender, e| h(Some(&(Rc::new(sender.to_ref()) as BoxedValue)), e)),
56 |o, h| ToolTip::remove_tool_tip_closing_handler(o, h),
57 )));
58
59 handlers
60 }
61
62 pub fn register(add_event_handler: Rc<dyn IAddEventHandler>) {
64 ADD_EVENT_HANDLERS.with(|handlers| {
65 let mut handlers = handlers.borrow_mut();
66 if !handlers.iter().any(|handler| Rc::ptr_eq(handler, &add_event_handler)) {
67 handlers.push(add_event_handler);
68 }
69 });
70 }
71
72 pub fn unregister(add_event_handler: &Rc<dyn IAddEventHandler>) {
74 ADD_EVENT_HANDLERS.with(|handlers| {
75 handlers.borrow_mut().retain(|handler| !Rc::ptr_eq(handler, add_event_handler));
76 });
77 }
78
79 pub fn try_register_event_handler(
82 source: &BoxedValue,
83 event_name: &str,
84 handler: AddEventHandlerCallback,
85 ) -> Option<Rc<dyn IDisposable>> {
86 let add_event_handler = ADD_EVENT_HANDLERS.with(|handlers| {
87 handlers.borrow().iter().find(|handler| handler.matches(source, event_name)).cloned()
88 });
89
90 add_event_handler?.add_handler(source, event_name, handler)
91 }
92}