mod driver;
mod focus;
mod ime;
mod keyboard;
mod pointer;
use crate::util::Point;
use blitz_traits::events::{DomEvent, DomEventData, PointerCoords, UiEvent};
pub use driver::{EventDriver, EventHandler, NoopEventHandler};
use focus::generate_focus_events;
pub(crate) use ime::handle_ime_event;
use keyboard::{KeyboardOrTextInputEvent, handle_key_or_input_event};
pub(crate) use pointer::{DragMode, ScrollAnimationState};
use pointer::{handle_click, handle_pointerdown, handle_pointermove, handle_pointerup};
use crate::{BaseDocument, events::pointer::handle_wheel};
fn adjust_coords_for_subdocument(
coords: &mut PointerCoords,
offset: Point<f32>,
viewport_scroll: Point<f64>,
) {
coords.page_x -= offset.x - viewport_scroll.x as f32;
coords.page_y -= offset.y - viewport_scroll.y as f32;
coords.client_x -= offset.x;
coords.client_y -= offset.y;
}
pub(crate) fn handle_dom_event<F: FnMut(DomEvent)>(
doc: &mut BaseDocument,
event: &mut DomEvent,
mut dispatch_event: F,
) {
let target_node_id = event.target;
let node = &mut doc.nodes[target_node_id];
let pos = node.absolute_position(0.0, 0.0);
let mut set_focus = false;
if let Some(sub_doc) = node.subdoc_mut() {
let viewport_scroll = sub_doc.inner().viewport_scroll();
let ui_event = match event.data.clone() {
DomEventData::PointerMove(mut event) => {
adjust_coords_for_subdocument(&mut event.coords, pos, viewport_scroll);
Some(UiEvent::PointerMove(event))
}
DomEventData::PointerDown(mut event) => {
adjust_coords_for_subdocument(&mut event.coords, pos, viewport_scroll);
set_focus = true;
Some(UiEvent::PointerDown(event))
}
DomEventData::PointerUp(mut event) => {
adjust_coords_for_subdocument(&mut event.coords, pos, viewport_scroll);
set_focus = true;
Some(UiEvent::PointerUp(event))
}
DomEventData::PointerEnter(_) => None,
DomEventData::PointerLeave(_) => None,
DomEventData::PointerOver(_) => None,
DomEventData::PointerOut(_) => None,
DomEventData::MouseMove(_) => None,
DomEventData::MouseDown(_) => None,
DomEventData::MouseUp(_) => None,
DomEventData::MouseEnter(_) => None,
DomEventData::MouseLeave(_) => None,
DomEventData::MouseOver(_) => None,
DomEventData::MouseOut(_) => None,
DomEventData::KeyDown(data) => Some(UiEvent::KeyDown(data)),
DomEventData::KeyUp(data) => Some(UiEvent::KeyUp(data)),
DomEventData::Ime(data) => Some(UiEvent::Ime(data)),
DomEventData::AppleStandardKeybinding(data) => {
Some(UiEvent::AppleStandardKeybinding(data))
}
DomEventData::KeyPress(_) => None,
DomEventData::Click(_) => None,
DomEventData::ContextMenu(_) => None,
DomEventData::DoubleClick(_) => None,
DomEventData::Input(_) => None,
DomEventData::Wheel(data) => Some(UiEvent::Wheel(data)),
DomEventData::Scroll(_) => None,
DomEventData::Focus(_) => None,
DomEventData::Blur(_) => None,
DomEventData::FocusIn(_) => None,
DomEventData::FocusOut(_) => None,
};
if let Some(ui_event) = ui_event {
sub_doc.handle_ui_event(ui_event);
}
if set_focus {
generate_focus_events(
doc,
&mut |doc| {
doc.set_focus_to(target_node_id);
},
&mut dispatch_event,
);
}
return;
}
match &event.data {
DomEventData::PointerMove(event) => {
let changed = handle_pointermove(doc, target_node_id, event, dispatch_event);
if changed {
doc.shell_provider.request_redraw();
}
}
DomEventData::MouseMove(_) => {
}
DomEventData::PointerDown(event) => {
handle_pointerdown(
doc,
target_node_id,
event.page_x(),
event.page_y(),
event.mods,
&mut dispatch_event,
);
}
DomEventData::MouseDown(_) => {
}
DomEventData::PointerUp(event) => {
handle_pointerup(doc, target_node_id, event, dispatch_event);
}
DomEventData::MouseUp(_) => {
}
DomEventData::Click(event) => {
handle_click(doc, target_node_id, event, &mut dispatch_event);
}
DomEventData::KeyDown(event) => {
handle_key_or_input_event(
doc,
target_node_id,
KeyboardOrTextInputEvent::KeyPress(event.clone()),
dispatch_event,
);
}
DomEventData::KeyPress(_) => {
}
DomEventData::KeyUp(_) => {
}
DomEventData::AppleStandardKeybinding(event) => {
handle_key_or_input_event(
doc,
target_node_id,
KeyboardOrTextInputEvent::AppleStandardKeyBinding(event.clone()),
dispatch_event,
);
}
DomEventData::Ime(event) => {
handle_ime_event(doc, event.clone(), dispatch_event);
}
DomEventData::Input(_) => {
}
DomEventData::ContextMenu(_) => {
}
DomEventData::DoubleClick(_) => {
}
DomEventData::PointerEnter(_) => {
}
DomEventData::PointerLeave(_) => {
}
DomEventData::PointerOver(_) => {
}
DomEventData::PointerOut(_) => {
}
DomEventData::MouseEnter(_) => {
}
DomEventData::MouseLeave(_) => {
}
DomEventData::MouseOver(_) => {
}
DomEventData::MouseOut(_) => {
}
DomEventData::Scroll(_) => {
}
DomEventData::Wheel(event) => {
handle_wheel(doc, target_node_id, event.clone(), dispatch_event);
}
DomEventData::Focus(_) => {
}
DomEventData::Blur(_) => {
}
DomEventData::FocusIn(_) => {
}
DomEventData::FocusOut(_) => {
}
}
}