trait based event system
This commit is contained in:
1 parent
a72718134b
commit
299b123446
28 files changed
+2407
-734
No files matched your search
@@ -1,9 +1,7 @@
|
||||
use crate::input_data::{decode_key_location, encode_key_location};
|
||||
use dioxus_core::Event;
|
||||
use keyboard_types::{Code, Key, Location, Modifiers};
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::str::FromStr;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
fn resilient_deserialize_code<'de, D>(deserializer: D) -> Result<Code, D::Error>
|
||||
@@ -16,57 +14,136 @@ where
|
||||
}
|
||||
|
||||
pub type KeyboardEvent = Event<KeyboardData>;
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct KeyboardData {
|
||||
#[deprecated(
|
||||
since = "0.3.0",
|
||||
note = "This may not work in all environments. Use key() instead."
|
||||
)]
|
||||
pub char_code: u32,
|
||||
inner: Box<dyn HasKeyboardData>,
|
||||
}
|
||||
|
||||
/// Identify which "key" was entered.
|
||||
#[deprecated(since = "0.3.0", note = "use key() instead")]
|
||||
pub key: String,
|
||||
impl<E: HasKeyboardData> From<E> for KeyboardData {
|
||||
fn from(e: E) -> Self {
|
||||
Self { inner: Box::new(e) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the key code as an enum Variant.
|
||||
#[deprecated(
|
||||
since = "0.3.0",
|
||||
note = "This may not work in all environments. Use code() instead."
|
||||
)]
|
||||
pub key_code: KeyCode,
|
||||
impl std::fmt::Debug for KeyboardData {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("KeyboardData")
|
||||
.field("key", &self.key())
|
||||
.field("code", &self.code())
|
||||
.field("modifiers", &self.modifiers())
|
||||
.field("location", &self.location())
|
||||
.field("is_auto_repeating", &self.is_auto_repeating())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// the physical key on the keyboard
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
serde(deserialize_with = "resilient_deserialize_code")
|
||||
)]
|
||||
impl PartialEq for KeyboardData {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.key() == other.key()
|
||||
&& self.code() == other.code()
|
||||
&& self.modifiers() == other.modifiers()
|
||||
&& self.location() == other.location()
|
||||
&& self.is_auto_repeating() == other.is_auto_repeating()
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardData {
|
||||
/// The value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
|
||||
pub fn key(&self) -> Key {
|
||||
self.inner.key()
|
||||
}
|
||||
|
||||
/// A physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn't altered by keyboard layout or the state of the modifier keys.
|
||||
pub fn code(&self) -> Code {
|
||||
self.inner.code()
|
||||
}
|
||||
|
||||
/// The set of modifier keys which were pressed when the event occurred
|
||||
pub fn modifiers(&self) -> Modifiers {
|
||||
self.inner.modifiers()
|
||||
}
|
||||
|
||||
/// The location of the key on the keyboard or other input device.
|
||||
pub fn location(&self) -> Location {
|
||||
self.inner.location()
|
||||
}
|
||||
|
||||
/// `true` iff the key is being held down such that it is automatically repeating.
|
||||
pub fn is_auto_repeating(&self) -> bool {
|
||||
self.inner.is_auto_repeating()
|
||||
}
|
||||
|
||||
/// Downcast this KeyboardData to a concrete type.
|
||||
pub fn downcast<T: 'static>(&self) -> Option<&T> {
|
||||
self.inner.as_any().downcast_ref::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
struct SerializedKeyboardData {
|
||||
auto_repeating: bool,
|
||||
#[serde(deserialize_with = "resilient_deserialize_code")]
|
||||
code: Code,
|
||||
key: Key,
|
||||
location: Location,
|
||||
modifiers: Modifiers,
|
||||
}
|
||||
|
||||
/// Indicate if the `alt` modifier key was pressed during this keyboard event
|
||||
#[deprecated(since = "0.3.0", note = "use modifiers() instead")]
|
||||
pub alt_key: bool,
|
||||
#[cfg(feature = "serialize")]
|
||||
impl From<&KeyboardData> for SerializedKeyboardData {
|
||||
fn from(data: &KeyboardData) -> Self {
|
||||
Self {
|
||||
auto_repeating: data.is_auto_repeating(),
|
||||
code: data.code(),
|
||||
key: data.key(),
|
||||
location: data.location(),
|
||||
modifiers: data.modifiers(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicate if the `ctrl` modifier key was pressed during this keyboard event
|
||||
#[deprecated(since = "0.3.0", note = "use modifiers() instead")]
|
||||
pub ctrl_key: bool,
|
||||
#[cfg(feature = "serialize")]
|
||||
impl HasKeyboardData for SerializedKeyboardData {
|
||||
fn key(&self) -> Key {
|
||||
self.key.clone()
|
||||
}
|
||||
|
||||
/// Indicate if the `meta` modifier key was pressed during this keyboard event
|
||||
#[deprecated(since = "0.3.0", note = "use modifiers() instead")]
|
||||
pub meta_key: bool,
|
||||
fn code(&self) -> Code {
|
||||
self.code
|
||||
}
|
||||
|
||||
/// Indicate if the `shift` modifier key was pressed during this keyboard event
|
||||
#[deprecated(since = "0.3.0", note = "use modifiers() instead")]
|
||||
pub shift_key: bool,
|
||||
fn modifiers(&self) -> Modifiers {
|
||||
self.modifiers
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.3.0", note = "use location() instead")]
|
||||
pub location: usize,
|
||||
fn location(&self) -> Location {
|
||||
self.location
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.3.0", note = "use is_auto_repeating() instead")]
|
||||
pub repeat: bool,
|
||||
fn is_auto_repeating(&self) -> bool {
|
||||
self.auto_repeating
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.3.0", note = "use code() or key() instead")]
|
||||
pub which: usize,
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl serde::Serialize for KeyboardData {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
SerializedKeyboardData::from(self).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<'de> serde::Deserialize<'de> for KeyboardData {
|
||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
let data = SerializedKeyboardData::deserialize(deserializer)?;
|
||||
Ok(Self {
|
||||
inner: Box::new(data),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl_event! {
|
||||
@@ -82,94 +159,24 @@ impl_event! {
|
||||
onkeyup
|
||||
}
|
||||
|
||||
impl KeyboardData {
|
||||
pub fn new(
|
||||
key: Key,
|
||||
code: Code,
|
||||
location: Location,
|
||||
is_auto_repeating: bool,
|
||||
modifiers: Modifiers,
|
||||
) -> Self {
|
||||
#[allow(deprecated)]
|
||||
KeyboardData {
|
||||
char_code: key.legacy_charcode(),
|
||||
key: key.to_string(),
|
||||
key_code: KeyCode::from_raw_code(
|
||||
key.legacy_keycode()
|
||||
.try_into()
|
||||
.expect("could not convert keycode to u8"),
|
||||
),
|
||||
code,
|
||||
alt_key: modifiers.contains(Modifiers::ALT),
|
||||
ctrl_key: modifiers.contains(Modifiers::CONTROL),
|
||||
meta_key: modifiers.contains(Modifiers::META),
|
||||
shift_key: modifiers.contains(Modifiers::SHIFT),
|
||||
location: encode_key_location(location),
|
||||
repeat: is_auto_repeating,
|
||||
which: key
|
||||
.legacy_charcode()
|
||||
.try_into()
|
||||
.expect("could not convert charcode to usize"),
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasKeyboardData: std::any::Any {
|
||||
/// The value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
|
||||
pub fn key(&self) -> Key {
|
||||
#[allow(deprecated)]
|
||||
FromStr::from_str(&self.key).unwrap_or(Key::Unidentified)
|
||||
}
|
||||
fn key(&self) -> Key;
|
||||
|
||||
/// A physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn't altered by keyboard layout or the state of the modifier keys.
|
||||
pub fn code(&self) -> Code {
|
||||
self.code
|
||||
}
|
||||
fn code(&self) -> Code;
|
||||
|
||||
/// The set of modifier keys which were pressed when the event occurred
|
||||
pub fn modifiers(&self) -> Modifiers {
|
||||
let mut modifiers = Modifiers::empty();
|
||||
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
if self.alt_key {
|
||||
modifiers.insert(Modifiers::ALT);
|
||||
}
|
||||
if self.ctrl_key {
|
||||
modifiers.insert(Modifiers::CONTROL);
|
||||
}
|
||||
if self.meta_key {
|
||||
modifiers.insert(Modifiers::META);
|
||||
}
|
||||
if self.shift_key {
|
||||
modifiers.insert(Modifiers::SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
modifiers
|
||||
}
|
||||
fn modifiers(&self) -> Modifiers;
|
||||
|
||||
/// The location of the key on the keyboard or other input device.
|
||||
pub fn location(&self) -> Location {
|
||||
#[allow(deprecated)]
|
||||
decode_key_location(self.location)
|
||||
}
|
||||
fn location(&self) -> Location;
|
||||
|
||||
/// `true` iff the key is being held down such that it is automatically repeating.
|
||||
pub fn is_auto_repeating(&self) -> bool {
|
||||
#[allow(deprecated)]
|
||||
self.repeat
|
||||
}
|
||||
}
|
||||
fn is_auto_repeating(&self) -> bool;
|
||||
|
||||
impl Debug for KeyboardData {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("KeyboardData")
|
||||
.field("key", &self.key())
|
||||
.field("code", &self.code())
|
||||
.field("modifiers", &self.modifiers())
|
||||
.field("location", &self.location())
|
||||
.field("is_auto_repeating", &self.is_auto_repeating())
|
||||
.finish()
|
||||
}
|
||||
/// return self as Any
|
||||
fn as_any(&self) -> &dyn std::any::Any;
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
|
||||
Reference in new issue
Block a user