Implement InputState::key_down (#107)

This commit is contained in:
Michael Tang 2021-01-12 04:46:27 -08:00 committed by GitHub
parent 449192e5fb
commit 90797f04f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,7 @@
//! The input needed by Egui. //! The input needed by Egui.
use std::collections::HashSet;
use crate::{math::*, util::History}; use crate::{math::*, util::History};
/// If mouse moves more than this, it is no longer a click (but maybe a drag) /// If mouse moves more than this, it is no longer a click (but maybe a drag)
@ -125,6 +127,9 @@ pub struct InputState {
/// Which modifier keys are down at the start of the frame? /// Which modifier keys are down at the start of the frame?
pub modifiers: Modifiers, pub modifiers: Modifiers,
// The keys that are currently being held down.
pub keys_down: HashSet<Key>,
/// In-order events received this frame /// In-order events received this frame
pub events: Vec<Event>, pub events: Vec<Event>,
} }
@ -141,6 +146,7 @@ impl Default for InputState {
unstable_dt: 1.0 / 6.0, unstable_dt: 1.0 / 6.0,
predicted_dt: 1.0 / 6.0, predicted_dt: 1.0 / 6.0,
modifiers: Default::default(), modifiers: Default::default(),
keys_down: Default::default(),
events: Default::default(), events: Default::default(),
} }
} }
@ -258,7 +264,7 @@ pub struct Modifiers {
/// ///
/// Many keys are omitted because they are not always physical keys (depending on keyboard language), e.g. `;` and `§`, /// Many keys are omitted because they are not always physical keys (depending on keyboard language), e.g. `;` and `§`,
/// and are therefor unsuitable as keyboard shortcuts if you want your app to be portable. /// and are therefor unsuitable as keyboard shortcuts if you want your app to be portable.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub enum Key { pub enum Key {
ArrowDown, ArrowDown,
ArrowLeft, ArrowLeft,
@ -344,6 +350,16 @@ impl InputState {
} }
}); });
let mouse = self.mouse.begin_frame(time, &new); let mouse = self.mouse.begin_frame(time, &new);
let mut keys_down = self.keys_down;
for event in &new.events {
if let Event::Key { key, pressed, .. } = event {
if *pressed {
keys_down.insert(*key);
} else {
keys_down.remove(key);
}
}
}
InputState { InputState {
mouse, mouse,
scroll_delta: new.scroll_delta, scroll_delta: new.scroll_delta,
@ -353,6 +369,7 @@ impl InputState {
unstable_dt, unstable_dt,
predicted_dt: new.predicted_dt, predicted_dt: new.predicted_dt,
modifiers: new.modifiers, modifiers: new.modifiers,
keys_down,
events: new.events.clone(), // TODO: remove clone() and use raw.events events: new.events.clone(), // TODO: remove clone() and use raw.events
raw: new, raw: new,
} }
@ -384,6 +401,11 @@ impl InputState {
}) })
} }
/// Is the given key currently held down?
pub fn key_down(&self, desired_key: Key) -> bool {
self.keys_down.contains(&desired_key)
}
/// Was the given key released this frame? /// Was the given key released this frame?
pub fn key_released(&self, desired_key: Key) -> bool { pub fn key_released(&self, desired_key: Key) -> bool {
self.events.iter().any(|event| { self.events.iter().any(|event| {
@ -536,6 +558,7 @@ impl InputState {
unstable_dt, unstable_dt,
predicted_dt, predicted_dt,
modifiers, modifiers,
keys_down,
events, events,
} = self; } = self;
@ -561,6 +584,7 @@ impl InputState {
)); ));
ui.label(format!("predicted_dt: {:.1} ms", 1e3 * predicted_dt)); ui.label(format!("predicted_dt: {:.1} ms", 1e3 * predicted_dt));
ui.label(format!("modifiers: {:#?}", modifiers)); ui.label(format!("modifiers: {:#?}", modifiers));
ui.label(format!("keys_down: {:?}", keys_down));
ui.label(format!("events: {:?}", events)) ui.label(format!("events: {:?}", events))
.on_hover_text("key presses etc"); .on_hover_text("key presses etc");
} }