mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Support Cmd+A ^W ^U ^K and shift-click
This commit is contained in:
@@ -92,16 +92,18 @@ impl egui::app::TextureAllocator for webgl::Painter {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO: Just use RawInput?
|
||||
/// Data gathered between frames.
|
||||
/// Is translated to `egui::RawInput` at the start of each frame.
|
||||
#[derive(Default)]
|
||||
pub struct WebInput {
|
||||
/// In native points (not same as Egui points)
|
||||
pub mouse_pos: Option<egui::Pos2>,
|
||||
pub mouse_down: bool, // TODO: which button
|
||||
/// Is this a touch screen? If so, we ignore mouse events.
|
||||
pub is_touch: bool,
|
||||
/// In native points (not same as Egui points)
|
||||
pub scroll_delta: egui::Vec2,
|
||||
pub events: Vec<egui::Event>,
|
||||
|
||||
pub raw: egui::RawInput,
|
||||
}
|
||||
|
||||
impl WebInput {
|
||||
@@ -111,13 +113,12 @@ impl WebInput {
|
||||
let scroll_delta = std::mem::take(&mut self.scroll_delta) * scale;
|
||||
let mouse_pos = self.mouse_pos.map(|mp| pos2(mp.x * scale, mp.y * scale));
|
||||
egui::RawInput {
|
||||
mouse_down: self.mouse_down,
|
||||
mouse_pos,
|
||||
scroll_delta,
|
||||
screen_size: screen_size_in_native_points().unwrap() * scale,
|
||||
pixels_per_point: Some(pixels_per_point),
|
||||
time: now_sec(),
|
||||
events: std::mem::take(&mut self.events),
|
||||
..self.raw.take()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +128,7 @@ impl WebInput {
|
||||
pub struct AppRunner {
|
||||
pixels_per_point: f32,
|
||||
pub web_backend: WebBackend,
|
||||
pub web_input: WebInput,
|
||||
pub input: WebInput,
|
||||
pub app: Box<dyn App>,
|
||||
pub needs_repaint: bool, // TODO: move
|
||||
}
|
||||
@@ -138,7 +139,7 @@ impl AppRunner {
|
||||
Ok(Self {
|
||||
pixels_per_point: native_pixels_per_point(),
|
||||
web_backend,
|
||||
web_input: Default::default(),
|
||||
input: Default::default(),
|
||||
app,
|
||||
needs_repaint: true, // TODO: move
|
||||
})
|
||||
@@ -151,7 +152,7 @@ impl AppRunner {
|
||||
pub fn logic(&mut self) -> Result<(egui::Output, egui::PaintJobs), JsValue> {
|
||||
resize_canvas_to_screen_size(self.web_backend.canvas_id());
|
||||
|
||||
let raw_input = self.web_input.new_frame(self.pixels_per_point);
|
||||
let raw_input = self.input.new_frame(self.pixels_per_point);
|
||||
self.web_backend.begin_frame(raw_input);
|
||||
|
||||
let mut integration_context = egui::app::IntegrationContext {
|
||||
|
||||
@@ -195,14 +195,30 @@ fn should_ignore_key(key: &str) -> bool {
|
||||
|| matches!(
|
||||
key,
|
||||
"Alt"
|
||||
| "ArrowDown"
|
||||
| "ArrowLeft"
|
||||
| "ArrowRight"
|
||||
| "ArrowUp"
|
||||
| "Backspace"
|
||||
| "CapsLock"
|
||||
| "ContextMenu"
|
||||
| "Control"
|
||||
| "Delete"
|
||||
| "End"
|
||||
| "Enter"
|
||||
| "Esc"
|
||||
| "Escape"
|
||||
| "Help"
|
||||
| "Home"
|
||||
| "Insert"
|
||||
| "Meta"
|
||||
| "NumLock"
|
||||
| "PageDown"
|
||||
| "PageUp"
|
||||
| "Pause"
|
||||
| "ScrollLock"
|
||||
| "Shift"
|
||||
| "Tab"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -224,6 +240,11 @@ pub fn translate_key(key: &str) -> Option<egui::Key> {
|
||||
"PageDown" => Some(egui::Key::PageDown),
|
||||
"PageUp" => Some(egui::Key::PageUp),
|
||||
"Tab" => Some(egui::Key::Tab),
|
||||
"a" | "A" => Some(egui::Key::A),
|
||||
"k" | "K" => Some(egui::Key::K),
|
||||
"u" | "U" => Some(egui::Key::U),
|
||||
"w" | "W" => Some(egui::Key::W),
|
||||
"z" | "Z" => Some(egui::Key::Z),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -271,20 +292,24 @@ fn install_document_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
// https://www.fxsitecompat.dev/en-CA/docs/2018/keydown-and-keyup-events-are-now-fired-during-ime-composition/
|
||||
return;
|
||||
}
|
||||
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
let modifiers = modifiers_from_event(&event);
|
||||
runner_lock.input.raw.modifiers = modifiers;
|
||||
|
||||
let key = event.key();
|
||||
|
||||
if let Some(key) = translate_key(&key) {
|
||||
runner_lock.web_input.events.push(egui::Event::Key {
|
||||
runner_lock.input.raw.events.push(egui::Event::Key {
|
||||
key,
|
||||
pressed: true,
|
||||
modifiers: modifiers_from_event(&event),
|
||||
modifiers,
|
||||
});
|
||||
runner_lock.needs_repaint = true;
|
||||
} else if !should_ignore_key(&key) {
|
||||
runner_lock.web_input.events.push(egui::Event::Text(key));
|
||||
runner_lock.needs_repaint = true;
|
||||
}
|
||||
if !modifiers.ctrl && !modifiers.command && !should_ignore_key(&key) {
|
||||
runner_lock.input.raw.events.push(egui::Event::Text(key));
|
||||
}
|
||||
runner_lock.needs_repaint = true;
|
||||
}) as Box<dyn FnMut(_)>);
|
||||
document.add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref())?;
|
||||
closure.forget();
|
||||
@@ -295,15 +320,16 @@ fn install_document_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
let key = event.key();
|
||||
if let Some(key) = translate_key(&key) {
|
||||
runner_lock.web_input.events.push(egui::Event::Key {
|
||||
let modifiers = modifiers_from_event(&event);
|
||||
runner_lock.input.raw.modifiers = modifiers;
|
||||
if let Some(key) = translate_key(&event.key()) {
|
||||
runner_lock.input.raw.events.push(egui::Event::Key {
|
||||
key,
|
||||
pressed: false,
|
||||
modifiers: modifiers_from_event(&event),
|
||||
modifiers,
|
||||
});
|
||||
runner_lock.needs_repaint = true;
|
||||
}
|
||||
runner_lock.needs_repaint = true;
|
||||
}) as Box<dyn FnMut(_)>);
|
||||
document.add_event_listener_with_callback("keyup", closure.as_ref().unchecked_ref())?;
|
||||
closure.forget();
|
||||
@@ -346,10 +372,10 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::MouseEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
if !runner_lock.web_input.is_touch {
|
||||
runner_lock.web_input.mouse_pos =
|
||||
if !runner_lock.input.is_touch {
|
||||
runner_lock.input.mouse_pos =
|
||||
Some(pos_from_mouse_event(runner_lock.canvas_id(), &event));
|
||||
runner_lock.web_input.mouse_down = true;
|
||||
runner_lock.input.raw.mouse_down = true;
|
||||
runner_lock.logic().unwrap(); // in case we get "mouseup" the same frame. TODO: handle via events instead
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
@@ -365,8 +391,8 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::MouseEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
if !runner_lock.web_input.is_touch {
|
||||
runner_lock.web_input.mouse_pos =
|
||||
if !runner_lock.input.is_touch {
|
||||
runner_lock.input.mouse_pos =
|
||||
Some(pos_from_mouse_event(runner_lock.canvas_id(), &event));
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
@@ -382,10 +408,10 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::MouseEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
if !runner_lock.web_input.is_touch {
|
||||
runner_lock.web_input.mouse_pos =
|
||||
if !runner_lock.input.is_touch {
|
||||
runner_lock.input.mouse_pos =
|
||||
Some(pos_from_mouse_event(runner_lock.canvas_id(), &event));
|
||||
runner_lock.web_input.mouse_down = false;
|
||||
runner_lock.input.raw.mouse_down = false;
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
@@ -400,8 +426,8 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::MouseEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
if !runner_lock.web_input.is_touch {
|
||||
runner_lock.web_input.mouse_pos = None;
|
||||
if !runner_lock.input.is_touch {
|
||||
runner_lock.input.mouse_pos = None;
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
@@ -416,9 +442,9 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::TouchEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
runner_lock.web_input.is_touch = true;
|
||||
runner_lock.web_input.mouse_pos = Some(pos_from_touch_event(&event));
|
||||
runner_lock.web_input.mouse_down = true;
|
||||
runner_lock.input.is_touch = true;
|
||||
runner_lock.input.mouse_pos = Some(pos_from_touch_event(&event));
|
||||
runner_lock.input.raw.mouse_down = true;
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
@@ -432,8 +458,8 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::TouchEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
runner_lock.web_input.is_touch = true;
|
||||
runner_lock.web_input.mouse_pos = Some(pos_from_touch_event(&event));
|
||||
runner_lock.input.is_touch = true;
|
||||
runner_lock.input.mouse_pos = Some(pos_from_touch_event(&event));
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
@@ -447,10 +473,10 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::TouchEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
runner_lock.web_input.is_touch = true;
|
||||
runner_lock.web_input.mouse_down = false; // First release mouse to click...
|
||||
runner_lock.input.is_touch = true;
|
||||
runner_lock.input.raw.mouse_down = false; // First release mouse to click...
|
||||
runner_lock.logic().unwrap(); // ...do the clicking... (TODO: handle via events instead)
|
||||
runner_lock.web_input.mouse_pos = None; // ...remove hover effect
|
||||
runner_lock.input.mouse_pos = None; // ...remove hover effect
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
@@ -464,8 +490,8 @@ fn install_canvas_events(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||
let runner_ref = runner_ref.clone();
|
||||
let closure = Closure::wrap(Box::new(move |event: web_sys::WheelEvent| {
|
||||
let mut runner_lock = runner_ref.0.lock();
|
||||
runner_lock.web_input.scroll_delta.x -= event.delta_x() as f32;
|
||||
runner_lock.web_input.scroll_delta.y -= event.delta_y() as f32;
|
||||
runner_lock.input.scroll_delta.x -= event.delta_x() as f32;
|
||||
runner_lock.input.scroll_delta.y -= event.delta_y() as f32;
|
||||
runner_lock.needs_repaint = true;
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
|
||||
Reference in New Issue
Block a user