Add Event::Key::repeat that is set to true if the event is a repeat (#2435)

* Add `Event::Key::repeat` that is set to `true` if the event is a repeat

* Update changelog

* Improve docstring
This commit is contained in:
Emil Ernerfeldt 2022-12-12 15:37:42 +01:00 committed by GitHub
parent cb77458f70
commit 7a658e3ddb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 29 additions and 10 deletions

View file

@ -5,6 +5,8 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG
## Unreleased
### Added ⭐
* `Event::Key` now has a `repeat` field that is set to `true` if the event was the result of a key-repeat ([#2435](https://github.com/emilk/egui/pull/2435)).
## 0.20.1 - 2022-12-11 - Fix key-repeat

View file

@ -69,6 +69,7 @@ pub fn install_document_events(runner_container: &mut AppRunnerContainer) -> Res
runner_lock.input.raw.events.push(egui::Event::Key {
key,
pressed: true,
repeat: false, // egui will fill this in for us!
modifiers,
});
}
@ -125,6 +126,7 @@ pub fn install_document_events(runner_container: &mut AppRunnerContainer) -> Res
runner_lock.input.raw.events.push(egui::Event::Key {
key,
pressed: false,
repeat: false,
modifiers,
});
}

View file

@ -594,6 +594,7 @@ impl State {
self.egui_input.events.push(egui::Event::Key {
key,
pressed,
repeat: false, // egui will fill this in for us!
modifiers: self.egui_input.modifiers,
});
}

View file

@ -1,7 +1,5 @@
//! The input needed by egui.
#![allow(deprecated)] // TODO(emilk): remove
use crate::emath::*;
/// What the integrations provides to egui at the start of each frame.
@ -189,14 +187,19 @@ pub enum Event {
/// Was it pressed or released?
pressed: bool,
/// If this is a `pressed` event, is it a key-repeat?
///
/// On many platforms, holding down a key produces many repeated "pressed" events for it, so called key-repeats.
/// Sometimes you will want to ignore such events, and this lets you do that.
///
/// egui will automatically detect such repeat events and mark them as such here.
/// Therefore, if you are writing an egui integration, you do not need to set this (just set it to `false`).
repeat: bool,
/// The state of the modifier keys at the time of the event.
modifiers: Modifiers,
},
/// DEPRECATED - DO NOT USE
#[deprecated = "Do not use"]
KeyRepeat { key: Key, modifiers: Modifiers },
/// The mouse or touch moved to a new place.
PointerMoved(Pos2),

View file

@ -166,10 +166,15 @@ impl InputState {
let mut zoom_factor_delta = 1.0;
for event in &mut new.events {
match event {
Event::Key { key, pressed, .. } => {
Event::Key {
key,
pressed,
repeat,
..
} => {
if *pressed {
keys_down.insert(*key);
// TODO(emilk): detect key repeats and mark the event accordingly!
let first_press = keys_down.insert(*key);
*repeat = !first_press;
} else {
keys_down.remove(key);
}
@ -263,7 +268,8 @@ impl InputState {
Event::Key {
key: ev_key,
modifiers: ev_mods,
pressed: true
pressed: true,
..
} if *ev_key == key && ev_mods.matches(modifiers)
);

View file

@ -248,6 +248,7 @@ impl Focus {
key: crate::Key::Escape,
pressed: true,
modifiers: _,
..
}
) {
self.id = None;
@ -259,6 +260,7 @@ impl Focus {
key: crate::Key::Tab,
pressed: true,
modifiers,
..
} = event
{
if !self.is_focus_locked {

View file

@ -866,6 +866,7 @@ fn events(
key: Key::Tab,
pressed: true,
modifiers,
..
} => {
if multiline && ui.memory().has_lock_focus(id) {
let mut ccursor = delete_selected(text, &cursor_range);
@ -899,6 +900,7 @@ fn events(
key: Key::Z,
pressed: true,
modifiers,
..
} if modifiers.command && !modifiers.shift => {
// TODO(emilk): redo
if let Some((undo_ccursor_range, undo_txt)) = state
@ -917,6 +919,7 @@ fn events(
key,
pressed: true,
modifiers,
..
} => on_key_press(&mut cursor_range, text, galley, *key, modifiers),
Event::CompositionStart => {