1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! Extension methods for [`Interactive`].
use super::{IRoutedEventArgs, Interactive, RoutedEvent, RoutingStrategies};
use crate::reactive::{Disposable, IDisposable, IObservable, Observable};
use crate::Ref;
use std::rc::Rc;
impl Interactive {
/// Adds a handler for a routed event (direct and bubble routes,
/// unhandled events) and returns a disposable that removes the handler
/// when disposed.
pub fn add_disposable_handler<TEventArgs: IRoutedEventArgs>(
&self,
routed_event: &RoutedEvent<TEventArgs>,
handler: impl Fn(&Interactive, &TEventArgs) + 'static,
) -> Rc<dyn IDisposable> {
self.add_disposable_handler_with(routed_event, handler, Self::DEFAULT_ROUTES, false)
}
/// Adds a handler for a routed event and returns a disposable that
/// removes the handler when disposed.
pub fn add_disposable_handler_with<TEventArgs: IRoutedEventArgs>(
&self,
routed_event: &RoutedEvent<TEventArgs>,
handler: impl Fn(&Interactive, &TEventArgs) + 'static,
routes: RoutingStrategies,
handled_events_too: bool,
) -> Rc<dyn IDisposable> {
let token = self.add_handler_with(routed_event, handler, routes, handled_events_too);
// Deviation (DEVIATIONS.md, Routed events): the managed original
// captures the object. An element that keeps the
// disposable of a handler it added to itself (a templated control and
// the handler of its own pointer events) would keep itself alive that
// way; the handlers of an object that is gone are gone with it.
let instance = self.to_ref().downgrade();
let routed_event = routed_event.as_routed_event();
Disposable::create(move || {
if let Some(instance) = instance.upgrade() {
instance.remove_handler(&routed_event, token);
}
})
}
/// The interactive parent of the object for bubbling and tunneling
/// events.
pub fn get_interactive_parent(&self) -> Option<Ref<Interactive>> {
self.interactive_parent()
}
/// Gets an observable for a routed event (direct and bubble routes,
/// unhandled events).
///
/// See [`get_observable_with`](Self::get_observable_with).
pub fn get_observable<TEventArgs: IRoutedEventArgs + Clone>(
&self,
routed_event: &RoutedEvent<TEventArgs>,
) -> Rc<dyn IObservable<TEventArgs>> {
self.get_observable_with(routed_event, Self::DEFAULT_ROUTES, false)
}
/// Gets an observable for a routed event.
///
/// Observers receive a copy of the args of every raise. The copy
/// reflects the routing state at the time of the notification; marking
/// the copy as handled does not affect the event being routed. Use a
/// handler for that.
pub fn get_observable_with<TEventArgs: IRoutedEventArgs + Clone>(
&self,
routed_event: &RoutedEvent<TEventArgs>,
routes: RoutingStrategies,
handled_events_too: bool,
) -> Rc<dyn IObservable<TEventArgs>> {
let o = self.to_ref();
let routed_event = *routed_event;
Observable::create(move |observer| {
o.add_disposable_handler_with(
&routed_event,
move |_, e: &TEventArgs| observer.on_next(e.clone()),
routes,
handled_events_too,
)
})
}
}