Refactor web event handling: break up into smaller functions (#4717)
No change in functionality, just making the code easier to read and change. * Part of fixing https://github.com/rerun-io/rerun/issues/6638
This commit is contained in:
parent
ce0e200503
commit
a0f4fafb88
|
|
@ -1,3 +1,5 @@
|
||||||
|
use web_sys::EventTarget;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
@ -47,9 +49,51 @@ fn paint_if_needed(runner: &mut AppRunner) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
pub(crate) fn install_document_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
pub(crate) fn install_event_handlers(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||||
let document = web_sys::window().unwrap().document().unwrap();
|
let window = web_sys::window().unwrap();
|
||||||
|
let document = window.document().unwrap();
|
||||||
|
let canvas = runner_ref.try_lock().unwrap().canvas().clone();
|
||||||
|
|
||||||
|
install_blur_focus(runner_ref, &document)?;
|
||||||
|
install_blur_focus(runner_ref, &window)?;
|
||||||
|
|
||||||
|
prevent_default(
|
||||||
|
runner_ref,
|
||||||
|
&canvas,
|
||||||
|
&[
|
||||||
|
// Allow users to use ctrl-p for e.g. a command palette:
|
||||||
|
"afterprint",
|
||||||
|
// By default, right-clicks open a browser context menu.
|
||||||
|
// We don't want to do that (right clicks are handled by egui):
|
||||||
|
"contextmenu",
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
install_keydown(runner_ref, &document)?;
|
||||||
|
install_keyup(runner_ref, &document)?;
|
||||||
|
install_copy_cut_paste(runner_ref, &document)?;
|
||||||
|
|
||||||
|
install_mousedown(runner_ref, &canvas)?;
|
||||||
|
// Use `document` here to notice if the user releases a drag outside of the canvas:
|
||||||
|
// See https://github.com/emilk/egui/issues/3157
|
||||||
|
install_mousemove(runner_ref, &document)?;
|
||||||
|
install_mouseup(runner_ref, &document)?;
|
||||||
|
install_mouseleave(runner_ref, &canvas)?;
|
||||||
|
|
||||||
|
install_touchstart(runner_ref, &canvas)?;
|
||||||
|
// Use `document` here to notice if the user drag outside of the canvas:
|
||||||
|
// See https://github.com/emilk/egui/issues/3157
|
||||||
|
install_touchmove(runner_ref, &document)?;
|
||||||
|
install_touchend(runner_ref, &document)?;
|
||||||
|
install_touchcancel(runner_ref, &canvas)?;
|
||||||
|
|
||||||
|
install_wheel(runner_ref, &canvas)?;
|
||||||
|
install_drag_and_drop(runner_ref, &canvas)?;
|
||||||
|
install_window_events(runner_ref, &window)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_blur_focus(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
for event_name in ["blur", "focus"] {
|
for event_name in ["blur", "focus"] {
|
||||||
let closure = move |_event: web_sys::MouseEvent, runner: &mut AppRunner| {
|
let closure = move |_event: web_sys::MouseEvent, runner: &mut AppRunner| {
|
||||||
// log::debug!("{event_name:?}");
|
// log::debug!("{event_name:?}");
|
||||||
|
|
@ -64,11 +108,14 @@ pub(crate) fn install_document_events(runner_ref: &WebRunner) -> Result<(), JsVa
|
||||||
runner.egui_ctx().request_repaint();
|
runner.egui_ctx().request_repaint();
|
||||||
};
|
};
|
||||||
|
|
||||||
runner_ref.add_event_listener(&document, event_name, closure)?;
|
runner_ref.add_event_listener(target, event_name, closure)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_keydown(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(
|
||||||
&document,
|
target,
|
||||||
"keydown",
|
"keydown",
|
||||||
|event: web_sys::KeyboardEvent, runner| {
|
|event: web_sys::KeyboardEvent, runner| {
|
||||||
if event.is_composing() || event.key_code() == 229 {
|
if event.is_composing() || event.key_code() == 229 {
|
||||||
|
|
@ -141,121 +188,90 @@ pub(crate) fn install_document_events(runner_ref: &WebRunner) -> Result<(), JsVa
|
||||||
// event.stop_propagation();
|
// event.stop_propagation();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
}
|
||||||
|
|
||||||
runner_ref.add_event_listener(
|
fn install_keyup(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
&document,
|
runner_ref.add_event_listener(target, "keyup", |event: web_sys::KeyboardEvent, runner| {
|
||||||
"keyup",
|
let modifiers = modifiers_from_kb_event(&event);
|
||||||
|event: web_sys::KeyboardEvent, runner| {
|
runner.input.raw.modifiers = modifiers;
|
||||||
let modifiers = modifiers_from_kb_event(&event);
|
if let Some(key) = translate_key(&event.key()) {
|
||||||
runner.input.raw.modifiers = modifiers;
|
runner.input.raw.events.push(egui::Event::Key {
|
||||||
if let Some(key) = translate_key(&event.key()) {
|
key,
|
||||||
runner.input.raw.events.push(egui::Event::Key {
|
physical_key: None, // TODO(fornwall)
|
||||||
key,
|
pressed: false,
|
||||||
physical_key: None, // TODO(fornwall)
|
repeat: false,
|
||||||
pressed: false,
|
modifiers,
|
||||||
repeat: false,
|
});
|
||||||
modifiers,
|
}
|
||||||
});
|
runner.needs_repaint.repaint_asap();
|
||||||
}
|
})
|
||||||
runner.needs_repaint.repaint_asap();
|
}
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
|
fn install_copy_cut_paste(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
#[cfg(web_sys_unstable_apis)]
|
#[cfg(web_sys_unstable_apis)]
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(target, "paste", |event: web_sys::ClipboardEvent, runner| {
|
||||||
&document,
|
if let Some(data) = event.clipboard_data() {
|
||||||
"paste",
|
if let Ok(text) = data.get_data("text") {
|
||||||
|event: web_sys::ClipboardEvent, runner| {
|
let text = text.replace("\r\n", "\n");
|
||||||
if let Some(data) = event.clipboard_data() {
|
if !text.is_empty() {
|
||||||
if let Ok(text) = data.get_data("text") {
|
runner.input.raw.events.push(egui::Event::Paste(text));
|
||||||
let text = text.replace("\r\n", "\n");
|
runner.needs_repaint.repaint_asap();
|
||||||
if !text.is_empty() {
|
|
||||||
runner.input.raw.events.push(egui::Event::Paste(text));
|
|
||||||
runner.needs_repaint.repaint_asap();
|
|
||||||
}
|
|
||||||
event.stop_propagation();
|
|
||||||
event.prevent_default();
|
|
||||||
}
|
}
|
||||||
|
event.stop_propagation();
|
||||||
|
event.prevent_default();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)?;
|
})?;
|
||||||
|
|
||||||
#[cfg(web_sys_unstable_apis)]
|
#[cfg(web_sys_unstable_apis)]
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(target, "cut", |event: web_sys::ClipboardEvent, runner| {
|
||||||
&document,
|
runner.input.raw.events.push(egui::Event::Cut);
|
||||||
"cut",
|
|
||||||
|event: web_sys::ClipboardEvent, runner| {
|
|
||||||
runner.input.raw.events.push(egui::Event::Cut);
|
|
||||||
|
|
||||||
// In Safari we are only allowed to write to the clipboard during the
|
// In Safari we are only allowed to write to the clipboard during the
|
||||||
// event callback, which is why we run the app logic here and now:
|
// event callback, which is why we run the app logic here and now:
|
||||||
runner.logic();
|
runner.logic();
|
||||||
|
|
||||||
// Make sure we paint the output of the above logic call asap:
|
// Make sure we paint the output of the above logic call asap:
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.needs_repaint.repaint_asap();
|
||||||
|
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
},
|
})?;
|
||||||
)?;
|
|
||||||
|
|
||||||
#[cfg(web_sys_unstable_apis)]
|
#[cfg(web_sys_unstable_apis)]
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(target, "copy", |event: web_sys::ClipboardEvent, runner| {
|
||||||
&document,
|
runner.input.raw.events.push(egui::Event::Copy);
|
||||||
"copy",
|
|
||||||
|event: web_sys::ClipboardEvent, runner| {
|
|
||||||
runner.input.raw.events.push(egui::Event::Copy);
|
|
||||||
|
|
||||||
// In Safari we are only allowed to write to the clipboard during the
|
// In Safari we are only allowed to write to the clipboard during the
|
||||||
// event callback, which is why we run the app logic here and now:
|
// event callback, which is why we run the app logic here and now:
|
||||||
runner.logic();
|
runner.logic();
|
||||||
|
|
||||||
// Make sure we paint the output of the above logic call asap:
|
// Make sure we paint the output of the above logic call asap:
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.needs_repaint.repaint_asap();
|
||||||
|
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
},
|
})?;
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn install_window_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
fn install_window_events(runner_ref: &WebRunner, window: &EventTarget) -> Result<(), JsValue> {
|
||||||
let window = web_sys::window().unwrap();
|
|
||||||
|
|
||||||
for event_name in ["blur", "focus"] {
|
|
||||||
let closure = move |_event: web_sys::MouseEvent, runner: &mut AppRunner| {
|
|
||||||
// log::debug!("{event_name:?}");
|
|
||||||
let has_focus = event_name == "focus";
|
|
||||||
|
|
||||||
if !has_focus {
|
|
||||||
// We lost focus - good idea to save
|
|
||||||
runner.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
runner.input.on_web_page_focus_change(has_focus);
|
|
||||||
runner.egui_ctx().request_repaint();
|
|
||||||
};
|
|
||||||
|
|
||||||
runner_ref.add_event_listener(&window, event_name, closure)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save-on-close
|
// Save-on-close
|
||||||
runner_ref.add_event_listener(&window, "onbeforeunload", |_: web_sys::Event, runner| {
|
runner_ref.add_event_listener(window, "onbeforeunload", |_: web_sys::Event, runner| {
|
||||||
runner.save();
|
runner.save();
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// NOTE: resize is handled by `ResizeObserver` below
|
// NOTE: resize is handled by `ResizeObserver` below
|
||||||
for event_name in &["load", "pagehide", "pageshow"] {
|
for event_name in &["load", "pagehide", "pageshow"] {
|
||||||
runner_ref.add_event_listener(&window, event_name, move |_: web_sys::Event, runner| {
|
runner_ref.add_event_listener(window, event_name, move |_: web_sys::Event, runner| {
|
||||||
// log::debug!("{event_name:?}");
|
// log::debug!("{event_name:?}");
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.needs_repaint.repaint_asap();
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
runner_ref.add_event_listener(&window, "hashchange", |_: web_sys::Event, runner| {
|
runner_ref.add_event_listener(window, "hashchange", |_: web_sys::Event, runner| {
|
||||||
// `epi::Frame::info(&self)` clones `epi::IntegrationInfo`, but we need to modify the original here
|
// `epi::Frame::info(&self)` clones `epi::IntegrationInfo`, but we need to modify the original here
|
||||||
runner.frame.info.web_info.location.hash = location_hash();
|
runner.frame.info.web_info.location.hash = location_hash();
|
||||||
runner.needs_repaint.repaint_asap(); // tell the user about the new hash
|
runner.needs_repaint.repaint_asap(); // tell the user about the new hash
|
||||||
|
|
@ -283,33 +299,27 @@ pub(crate) fn install_color_scheme_change_event(runner_ref: &WebRunner) -> Resul
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
fn prevent_default(
|
||||||
let canvas = runner_ref.try_lock().unwrap().canvas().clone();
|
runner_ref: &WebRunner,
|
||||||
let window = web_sys::window().unwrap();
|
target: &EventTarget,
|
||||||
let document = window.document().unwrap();
|
event_names: &[&'static str],
|
||||||
|
) -> Result<(), JsValue> {
|
||||||
|
for event_name in event_names {
|
||||||
|
let closure = move |event: web_sys::MouseEvent, _runner: &mut AppRunner| {
|
||||||
|
event.prevent_default();
|
||||||
|
// event.stop_propagation();
|
||||||
|
// log::debug!("Preventing event {event_name:?}");
|
||||||
|
};
|
||||||
|
|
||||||
{
|
runner_ref.add_event_listener(target, event_name, closure)?;
|
||||||
let prevent_default_events = [
|
|
||||||
// By default, right-clicks open a context menu.
|
|
||||||
// We don't want to do that (right clicks is handled by egui):
|
|
||||||
"contextmenu",
|
|
||||||
// Allow users to use ctrl-p for e.g. a command palette:
|
|
||||||
"afterprint",
|
|
||||||
];
|
|
||||||
|
|
||||||
for event_name in prevent_default_events {
|
|
||||||
let closure = move |event: web_sys::MouseEvent, _runner: &mut AppRunner| {
|
|
||||||
event.prevent_default();
|
|
||||||
// event.stop_propagation();
|
|
||||||
// log::debug!("Preventing event {event_name:?}");
|
|
||||||
};
|
|
||||||
|
|
||||||
runner_ref.add_event_listener(&canvas, event_name, closure)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_mousedown(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(
|
||||||
&canvas,
|
target,
|
||||||
"mousedown",
|
"mousedown",
|
||||||
|event: web_sys::MouseEvent, runner: &mut AppRunner| {
|
|event: web_sys::MouseEvent, runner: &mut AppRunner| {
|
||||||
let modifiers = modifiers_from_mouse_event(&event);
|
let modifiers = modifiers_from_mouse_event(&event);
|
||||||
|
|
@ -334,61 +344,59 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
// Note: prevent_default breaks VSCode tab focusing, hence why we don't call it here.
|
// Note: prevent_default breaks VSCode tab focusing, hence why we don't call it here.
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_mousemove(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
// NOTE: we register "mousemove" on `document` instead of just the canvas
|
// NOTE: we register "mousemove" on `document` instead of just the canvas
|
||||||
// in order to track a dragged mouse outside the canvas.
|
// in order to track a dragged mouse outside the canvas.
|
||||||
// See https://github.com/emilk/egui/issues/3157
|
// See https://github.com/emilk/egui/issues/3157
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(target, "mousemove", |event: web_sys::MouseEvent, runner| {
|
||||||
&document,
|
let modifiers = modifiers_from_mouse_event(&event);
|
||||||
"mousemove",
|
runner.input.raw.modifiers = modifiers;
|
||||||
|event: web_sys::MouseEvent, runner| {
|
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
|
||||||
let modifiers = modifiers_from_mouse_event(&event);
|
runner.input.raw.events.push(egui::Event::PointerMoved(pos));
|
||||||
runner.input.raw.modifiers = modifiers;
|
runner.needs_repaint.repaint_asap();
|
||||||
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
|
event.stop_propagation();
|
||||||
runner.input.raw.events.push(egui::Event::PointerMoved(pos));
|
event.prevent_default();
|
||||||
runner.needs_repaint.repaint_asap();
|
})
|
||||||
event.stop_propagation();
|
}
|
||||||
event.prevent_default();
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
|
fn install_mouseup(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
// Use `document` here to notice if the user releases a drag outside of the canvas.
|
// Use `document` here to notice if the user releases a drag outside of the canvas.
|
||||||
// See https://github.com/emilk/egui/issues/3157
|
// See https://github.com/emilk/egui/issues/3157
|
||||||
|
runner_ref.add_event_listener(target, "mouseup", |event: web_sys::MouseEvent, runner| {
|
||||||
|
let modifiers = modifiers_from_mouse_event(&event);
|
||||||
|
runner.input.raw.modifiers = modifiers;
|
||||||
|
if let Some(button) = button_from_mouse_event(&event) {
|
||||||
|
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
|
||||||
|
let modifiers = runner.input.raw.modifiers;
|
||||||
|
runner.input.raw.events.push(egui::Event::PointerButton {
|
||||||
|
pos,
|
||||||
|
button,
|
||||||
|
pressed: false,
|
||||||
|
modifiers,
|
||||||
|
});
|
||||||
|
|
||||||
|
// In Safari we are only allowed to write to the clipboard during the
|
||||||
|
// event callback, which is why we run the app logic here and now:
|
||||||
|
runner.logic();
|
||||||
|
|
||||||
|
runner
|
||||||
|
.text_agent
|
||||||
|
.set_focus(runner.mutable_text_under_cursor);
|
||||||
|
|
||||||
|
// Make sure we paint the output of the above logic call asap:
|
||||||
|
runner.needs_repaint.repaint_asap();
|
||||||
|
}
|
||||||
|
event.stop_propagation();
|
||||||
|
event.prevent_default();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_mouseleave(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(
|
||||||
&document,
|
target,
|
||||||
"mouseup",
|
|
||||||
|event: web_sys::MouseEvent, runner| {
|
|
||||||
let modifiers = modifiers_from_mouse_event(&event);
|
|
||||||
runner.input.raw.modifiers = modifiers;
|
|
||||||
if let Some(button) = button_from_mouse_event(&event) {
|
|
||||||
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
|
|
||||||
let modifiers = runner.input.raw.modifiers;
|
|
||||||
runner.input.raw.events.push(egui::Event::PointerButton {
|
|
||||||
pos,
|
|
||||||
button,
|
|
||||||
pressed: false,
|
|
||||||
modifiers,
|
|
||||||
});
|
|
||||||
|
|
||||||
// In Safari we are only allowed to write to the clipboard during the
|
|
||||||
// event callback, which is why we run the app logic here and now:
|
|
||||||
runner.logic();
|
|
||||||
|
|
||||||
runner
|
|
||||||
.text_agent
|
|
||||||
.set_focus(runner.mutable_text_under_cursor);
|
|
||||||
|
|
||||||
// Make sure we paint the output of the above logic call asap:
|
|
||||||
runner.needs_repaint.repaint_asap();
|
|
||||||
}
|
|
||||||
event.stop_propagation();
|
|
||||||
event.prevent_default();
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
runner_ref.add_event_listener(
|
|
||||||
&canvas,
|
|
||||||
"mouseleave",
|
"mouseleave",
|
||||||
|event: web_sys::MouseEvent, runner| {
|
|event: web_sys::MouseEvent, runner| {
|
||||||
runner.input.raw.events.push(egui::Event::PointerGone);
|
runner.input.raw.events.push(egui::Event::PointerGone);
|
||||||
|
|
@ -396,10 +404,12 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_touchstart(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(
|
||||||
&canvas,
|
target,
|
||||||
"touchstart",
|
"touchstart",
|
||||||
|event: web_sys::TouchEvent, runner| {
|
|event: web_sys::TouchEvent, runner| {
|
||||||
let mut latest_touch_pos_id = runner.input.latest_touch_pos_id;
|
let mut latest_touch_pos_id = runner.input.latest_touch_pos_id;
|
||||||
|
|
@ -424,65 +434,61 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
},
|
},
|
||||||
)?;
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Use `document` here to notice if the user drag outside of the canvas.
|
fn install_touchmove(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
|
runner_ref.add_event_listener(target, "touchmove", |event: web_sys::TouchEvent, runner| {
|
||||||
|
let mut latest_touch_pos_id = runner.input.latest_touch_pos_id;
|
||||||
|
let pos = pos_from_touch_event(
|
||||||
|
runner.canvas(),
|
||||||
|
&event,
|
||||||
|
&mut latest_touch_pos_id,
|
||||||
|
runner.egui_ctx(),
|
||||||
|
);
|
||||||
|
runner.input.latest_touch_pos_id = latest_touch_pos_id;
|
||||||
|
runner.input.latest_touch_pos = Some(pos);
|
||||||
|
runner.input.raw.events.push(egui::Event::PointerMoved(pos));
|
||||||
|
|
||||||
|
push_touches(runner, egui::TouchPhase::Move, &event);
|
||||||
|
runner.needs_repaint.repaint_asap();
|
||||||
|
event.stop_propagation();
|
||||||
|
event.prevent_default();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_touchend(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
|
// Use `document` here to notice if the user releases a drag outside of the canvas.
|
||||||
// See https://github.com/emilk/egui/issues/3157
|
// See https://github.com/emilk/egui/issues/3157
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(target, "touchend", |event: web_sys::TouchEvent, runner| {
|
||||||
&document,
|
if let Some(pos) = runner.input.latest_touch_pos {
|
||||||
"touchmove",
|
let modifiers = runner.input.raw.modifiers;
|
||||||
|event: web_sys::TouchEvent, runner| {
|
// First release mouse to click:
|
||||||
let mut latest_touch_pos_id = runner.input.latest_touch_pos_id;
|
runner.input.raw.events.push(egui::Event::PointerButton {
|
||||||
let pos = pos_from_touch_event(
|
pos,
|
||||||
runner.canvas(),
|
button: egui::PointerButton::Primary,
|
||||||
&event,
|
pressed: false,
|
||||||
&mut latest_touch_pos_id,
|
modifiers,
|
||||||
runner.egui_ctx(),
|
});
|
||||||
);
|
// Then remove hover effect:
|
||||||
runner.input.latest_touch_pos_id = latest_touch_pos_id;
|
runner.input.raw.events.push(egui::Event::PointerGone);
|
||||||
runner.input.latest_touch_pos = Some(pos);
|
|
||||||
runner.input.raw.events.push(egui::Event::PointerMoved(pos));
|
push_touches(runner, egui::TouchPhase::End, &event);
|
||||||
|
|
||||||
|
runner
|
||||||
|
.text_agent
|
||||||
|
.set_focus(runner.mutable_text_under_cursor);
|
||||||
|
|
||||||
push_touches(runner, egui::TouchPhase::Move, &event);
|
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.needs_repaint.repaint_asap();
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
},
|
}
|
||||||
)?;
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Use `document` here to notice if the user releases a drag outside of the canvas.
|
fn install_touchcancel(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
// See https://github.com/emilk/egui/issues/3157
|
|
||||||
runner_ref.add_event_listener(
|
runner_ref.add_event_listener(
|
||||||
&document,
|
target,
|
||||||
"touchend",
|
|
||||||
|event: web_sys::TouchEvent, runner| {
|
|
||||||
if let Some(pos) = runner.input.latest_touch_pos {
|
|
||||||
let modifiers = runner.input.raw.modifiers;
|
|
||||||
// First release mouse to click:
|
|
||||||
runner.input.raw.events.push(egui::Event::PointerButton {
|
|
||||||
pos,
|
|
||||||
button: egui::PointerButton::Primary,
|
|
||||||
pressed: false,
|
|
||||||
modifiers,
|
|
||||||
});
|
|
||||||
// Then remove hover effect:
|
|
||||||
runner.input.raw.events.push(egui::Event::PointerGone);
|
|
||||||
|
|
||||||
push_touches(runner, egui::TouchPhase::End, &event);
|
|
||||||
|
|
||||||
runner
|
|
||||||
.text_agent
|
|
||||||
.set_focus(runner.mutable_text_under_cursor);
|
|
||||||
|
|
||||||
runner.needs_repaint.repaint_asap();
|
|
||||||
event.stop_propagation();
|
|
||||||
event.prevent_default();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
runner_ref.add_event_listener(
|
|
||||||
&canvas,
|
|
||||||
"touchcancel",
|
"touchcancel",
|
||||||
|event: web_sys::TouchEvent, runner| {
|
|event: web_sys::TouchEvent, runner| {
|
||||||
push_touches(runner, egui::TouchPhase::Cancel, &event);
|
push_touches(runner, egui::TouchPhase::Cancel, &event);
|
||||||
|
|
@ -491,7 +497,11 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
runner_ref.add_event_listener(&canvas, "wheel", |event: web_sys::WheelEvent, runner| {
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn install_wheel(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
|
runner_ref.add_event_listener(target, "wheel", |event: web_sys::WheelEvent, runner| {
|
||||||
let unit = match event.delta_mode() {
|
let unit = match event.delta_mode() {
|
||||||
web_sys::WheelEvent::DOM_DELTA_PIXEL => egui::MouseWheelUnit::Point,
|
web_sys::WheelEvent::DOM_DELTA_PIXEL => egui::MouseWheelUnit::Point,
|
||||||
web_sys::WheelEvent::DOM_DELTA_LINE => egui::MouseWheelUnit::Line,
|
web_sys::WheelEvent::DOM_DELTA_LINE => egui::MouseWheelUnit::Line,
|
||||||
|
|
@ -523,9 +533,11 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.needs_repaint.repaint_asap();
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
})?;
|
})
|
||||||
|
}
|
||||||
|
|
||||||
runner_ref.add_event_listener(&canvas, "dragover", |event: web_sys::DragEvent, runner| {
|
fn install_drag_and_drop(runner_ref: &WebRunner, target: &EventTarget) -> Result<(), JsValue> {
|
||||||
|
runner_ref.add_event_listener(target, "dragover", |event: web_sys::DragEvent, runner| {
|
||||||
if let Some(data_transfer) = event.data_transfer() {
|
if let Some(data_transfer) = event.data_transfer() {
|
||||||
runner.input.raw.hovered_files.clear();
|
runner.input.raw.hovered_files.clear();
|
||||||
for i in 0..data_transfer.items().length() {
|
for i in 0..data_transfer.items().length() {
|
||||||
|
|
@ -542,14 +554,14 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
runner_ref.add_event_listener(&canvas, "dragleave", |event: web_sys::DragEvent, runner| {
|
runner_ref.add_event_listener(target, "dragleave", |event: web_sys::DragEvent, runner| {
|
||||||
runner.input.raw.hovered_files.clear();
|
runner.input.raw.hovered_files.clear();
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.needs_repaint.repaint_asap();
|
||||||
event.stop_propagation();
|
event.stop_propagation();
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
runner_ref.add_event_listener(&canvas, "drop", {
|
runner_ref.add_event_listener(target, "drop", {
|
||||||
let runner_ref = runner_ref.clone();
|
let runner_ref = runner_ref.clone();
|
||||||
|
|
||||||
move |event: web_sys::DragEvent, runner| {
|
move |event: web_sys::DragEvent, runner| {
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,7 @@ impl WebRunner {
|
||||||
self.runner.replace(Some(runner));
|
self.runner.replace(Some(runner));
|
||||||
|
|
||||||
{
|
{
|
||||||
events::install_canvas_events(self)?;
|
events::install_event_handlers(self)?;
|
||||||
events::install_document_events(self)?;
|
|
||||||
events::install_window_events(self)?;
|
|
||||||
|
|
||||||
if follow_system_theme {
|
if follow_system_theme {
|
||||||
events::install_color_scheme_change_event(self)?;
|
events::install_color_scheme_change_event(self)?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue