use super::Event;
#[derive(Default)]
pub struct EventContext {
propagation_stopped: bool,
default_prevented: bool,
handled: bool,
}
impl EventContext {
pub fn new() -> Self {
Self::default()
}
pub fn stop_propagation(&mut self) {
self.propagation_stopped = true;
}
pub fn is_propagation_stopped(&self) -> bool {
self.propagation_stopped
}
pub fn prevent_default(&mut self) {
self.default_prevented = true;
}
pub fn is_default_prevented(&self) -> bool {
self.default_prevented
}
pub fn set_handled(&mut self) {
self.handled = true;
}
pub fn is_handled(&self) -> bool {
self.handled
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EventPhase {
Capture,
Target,
Bubble,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct HandlerId(u64);
type HandlerFn = Box<dyn Fn(&Event, &mut EventContext) -> bool>;
type SimpleHandlerFn = Box<dyn Fn(&Event) -> bool>;
pub struct EventHandler {
capture_handlers: Vec<(HandlerId, HandlerFn)>,
bubble_handlers: Vec<(HandlerId, HandlerFn)>,
simple_handlers: Vec<(HandlerId, SimpleHandlerFn)>,
next_id: u64,
}
impl EventHandler {
pub fn new() -> Self {
Self {
capture_handlers: Vec::new(),
bubble_handlers: Vec::new(),
simple_handlers: Vec::new(),
next_id: 1,
}
}
fn next_handler_id(&mut self) -> HandlerId {
let id = HandlerId(self.next_id);
self.next_id += 1;
id
}
pub fn on<F>(&mut self, handler: F) -> HandlerId
where
F: Fn(&Event) -> bool + 'static,
{
let id = self.next_handler_id();
self.simple_handlers.push((id, Box::new(handler)));
id
}
pub fn on_bubble<F>(&mut self, handler: F) -> HandlerId
where
F: Fn(&Event, &mut EventContext) -> bool + 'static,
{
let id = self.next_handler_id();
self.bubble_handlers.push((id, Box::new(handler)));
id
}
pub fn on_capture<F>(&mut self, handler: F) -> HandlerId
where
F: Fn(&Event, &mut EventContext) -> bool + 'static,
{
let id = self.next_handler_id();
self.capture_handlers.push((id, Box::new(handler)));
id
}
pub fn remove(&mut self, id: HandlerId) -> bool {
let len_before =
self.capture_handlers.len() + self.bubble_handlers.len() + self.simple_handlers.len();
self.capture_handlers.retain(|(hid, _)| *hid != id);
self.bubble_handlers.retain(|(hid, _)| *hid != id);
self.simple_handlers.retain(|(hid, _)| *hid != id);
let len_after =
self.capture_handlers.len() + self.bubble_handlers.len() + self.simple_handlers.len();
len_after < len_before
}
pub fn dispatch_with_context(&self, event: &Event) -> EventContext {
let mut ctx = EventContext::new();
for (_, handler) in &self.capture_handlers {
if ctx.is_propagation_stopped() {
break;
}
if handler(event, &mut ctx) {
ctx.set_handled();
}
}
for (_, handler) in self.bubble_handlers.iter().rev() {
if ctx.is_propagation_stopped() {
break;
}
if handler(event, &mut ctx) {
ctx.set_handled();
}
}
ctx
}
pub fn dispatch(&self, event: &Event) -> bool {
for (_, handler) in &self.simple_handlers {
if handler(event) {
return true;
}
}
let ctx = self.dispatch_with_context(event);
ctx.is_handled()
}
pub fn clear(&mut self) {
self.capture_handlers.clear();
self.bubble_handlers.clear();
self.simple_handlers.clear();
}
pub fn is_empty(&self) -> bool {
self.capture_handlers.is_empty()
&& self.bubble_handlers.is_empty()
&& self.simple_handlers.is_empty()
}
pub fn handler_count(&self) -> usize {
self.capture_handlers.len() + self.bubble_handlers.len() + self.simple_handlers.len()
}
}
impl Default for EventHandler {
fn default() -> Self {
Self::new()
}
}