mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-26 03:21:03 +00:00
navigation: Add support for event creation and simplify the API
And also allow implement serialization with serde (behind a feature) to allow sending navigation event through the network (for example from a browser with a WebRTC data channel).
This commit is contained in:
parent
56dfe0fe59
commit
fc452036d2
4 changed files with 278 additions and 194 deletions
|
@ -24,9 +24,11 @@ gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
||||||
once_cell = "1.0"
|
once_cell = "1.0"
|
||||||
futures-channel = "0.3"
|
futures-channel = "0.3"
|
||||||
fragile = "1"
|
fragile = "1"
|
||||||
|
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
|
serde_json = "1.0"
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -38,6 +40,7 @@ v1_16 = ["gst/v1_16", "gst-base/v1_16", "ffi/v1_16", "v1_14"]
|
||||||
v1_18 = ["gst/v1_18", "gst-base/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-base/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-base/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-base/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
dox = ["v1_20", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox"]
|
dox = ["v1_20", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox"]
|
||||||
|
ser_de = ["serde"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
|
@ -81,6 +81,7 @@ impl ToValue for ColorBalanceType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[doc(alias = "GstNavigationCommand")]
|
#[doc(alias = "GstNavigationCommand")]
|
||||||
|
|
|
@ -58,12 +58,9 @@ mod video_overlay;
|
||||||
pub use crate::video_overlay::is_video_overlay_prepare_window_handle_message;
|
pub use crate::video_overlay::is_video_overlay_prepare_window_handle_message;
|
||||||
|
|
||||||
pub mod video_event;
|
pub mod video_event;
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
|
||||||
pub use crate::video_event::MouseScrollEvent;
|
|
||||||
pub use crate::video_event::{
|
pub use crate::video_event::{
|
||||||
CommandEvent, DownstreamForceKeyUnitEvent, ForceKeyUnitEvent, KeyEvent, MouseButtonEvent,
|
DownstreamForceKeyUnitEvent, ForceKeyUnitEvent, NavigationEvent, StillFrameEvent,
|
||||||
MouseMoveEvent, NavigationEvent, StillFrameEvent, UpstreamForceKeyUnitEvent,
|
UpstreamForceKeyUnitEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod video_message;
|
pub mod video_message;
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
// Take a look at the license at the top of the repository in the LICENSE file.
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
use crate::{NavigationCommand, NavigationEventType};
|
use crate::{NavigationCommand, NavigationEventType};
|
||||||
use glib::translate::{from_glib, from_glib_none, from_glib_full, IntoGlib};
|
use glib::translate::{from_glib, from_glib_full, IntoGlib};
|
||||||
use glib::ToSendValue;
|
use glib::ToSendValue;
|
||||||
use std::{mem, ptr};
|
use std::mem;
|
||||||
|
|
||||||
// FIXME: Copy from gstreamer/src/event.rs
|
// FIXME: Copy from gstreamer/src/event.rs
|
||||||
macro_rules! event_builder_generic_impl {
|
macro_rules! event_builder_generic_impl {
|
||||||
|
@ -351,212 +350,296 @@ impl StillFrameEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NAVIGATION_EVENT_NAME: &str = "application/x-gst-navigation";
|
||||||
|
#[cfg_attr(feature = "ser_de", derive(serde::Serialize, serde::Deserialize))]
|
||||||
|
#[cfg_attr(feature = "ser_de", serde(tag = "event"))]
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct KeyEvent {
|
pub enum NavigationEvent {
|
||||||
pub key: String,
|
KeyPress {
|
||||||
|
key: String,
|
||||||
|
},
|
||||||
|
KeyRelease {
|
||||||
|
key: String,
|
||||||
|
},
|
||||||
|
MouseMove {
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
},
|
||||||
|
MouseButtonPress {
|
||||||
|
button: i32,
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
},
|
||||||
|
MouseButtonRelease {
|
||||||
|
button: i32,
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
},
|
||||||
|
Command {
|
||||||
|
command: NavigationCommand,
|
||||||
|
},
|
||||||
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||||
|
MouseScroll {
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
delta_x: f64,
|
||||||
|
delta_y: f64,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyEvent {
|
impl NavigationEvent {
|
||||||
#[doc(alias = "gst_navigation_event_parse_key_event")]
|
pub fn new_key_press(key: &str) -> NavigationEvent {
|
||||||
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
Self::KeyPress {
|
||||||
let mut key = ptr::null();
|
key: key.to_string(),
|
||||||
let ret = from_glib(ffi::gst_navigation_event_parse_key_event(
|
|
||||||
event.as_mut_ptr(),
|
|
||||||
&mut key,
|
|
||||||
));
|
|
||||||
|
|
||||||
if ret {
|
|
||||||
Ok(Self {
|
|
||||||
key: from_glib_none(key),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(glib::bool_error!("Invalid key event"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
pub fn new_key_release(key: &str) -> NavigationEvent {
|
||||||
pub struct MouseButtonEvent {
|
|
||||||
pub button: i32,
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MouseButtonEvent {
|
|
||||||
#[doc(alias = "gst_navigation_event_parse_mouse_button_event")]
|
|
||||||
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
Self::KeyRelease {
|
||||||
let mut button = mem::MaybeUninit::uninit();
|
key: key.to_string(),
|
||||||
let mut x = mem::MaybeUninit::uninit();
|
|
||||||
let mut y = mem::MaybeUninit::uninit();
|
|
||||||
let ret = from_glib(ffi::gst_navigation_event_parse_mouse_button_event(
|
|
||||||
event.as_mut_ptr(),
|
|
||||||
button.as_mut_ptr(),
|
|
||||||
x.as_mut_ptr(),
|
|
||||||
y.as_mut_ptr(),
|
|
||||||
));
|
|
||||||
let button = button.assume_init();
|
|
||||||
let x = x.assume_init();
|
|
||||||
let y = y.assume_init();
|
|
||||||
if ret {
|
|
||||||
Ok(Self { button, x, y })
|
|
||||||
} else {
|
|
||||||
Err(glib::bool_error!("Invalid mouse button event"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
pub fn new_mouse_move(x: f64, y: f64) -> NavigationEvent {
|
||||||
pub struct MouseMoveEvent {
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MouseMoveEvent {
|
|
||||||
#[doc(alias = "gst_navigation_event_parse_mouse_move_event")]
|
|
||||||
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
Self::MouseMove { x, y }
|
||||||
let mut x = mem::MaybeUninit::uninit();
|
|
||||||
let mut y = mem::MaybeUninit::uninit();
|
|
||||||
let ret = from_glib(ffi::gst_navigation_event_parse_mouse_move_event(
|
|
||||||
event.as_mut_ptr(),
|
|
||||||
x.as_mut_ptr(),
|
|
||||||
y.as_mut_ptr(),
|
|
||||||
));
|
|
||||||
let x = x.assume_init();
|
|
||||||
let y = y.assume_init();
|
|
||||||
if ret {
|
|
||||||
Ok(Self { x, y })
|
|
||||||
} else {
|
|
||||||
Err(glib::bool_error!("Invalid mouse move event"))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
pub fn new_mouse_button_press(button: i32, x: f64, y: f64) -> NavigationEvent {
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub struct MouseScrollEvent {
|
|
||||||
pub x: f64,
|
|
||||||
pub y: f64,
|
|
||||||
pub delta_x: f64,
|
|
||||||
pub delta_y: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
|
||||||
impl MouseScrollEvent {
|
|
||||||
#[doc(alias = "gst_navigation_event_parse_mouse_scroll_event")]
|
|
||||||
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
Self::MouseButtonPress { button, x, y }
|
||||||
let mut x = mem::MaybeUninit::uninit();
|
}
|
||||||
let mut y = mem::MaybeUninit::uninit();
|
|
||||||
let mut delta_x = mem::MaybeUninit::uninit();
|
pub fn new_mouse_button_release(button: i32, x: f64, y: f64) -> NavigationEvent {
|
||||||
let mut delta_y = mem::MaybeUninit::uninit();
|
assert_initialized_main_thread!();
|
||||||
let ret = from_glib(ffi::gst_navigation_event_parse_mouse_scroll_event(
|
Self::MouseButtonRelease { button, x, y }
|
||||||
event.as_mut_ptr(),
|
}
|
||||||
x.as_mut_ptr(),
|
|
||||||
y.as_mut_ptr(),
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||||
delta_x.as_mut_ptr(),
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||||
delta_y.as_mut_ptr(),
|
pub fn new_mouse_scroll(x: f64, y: f64, delta_x: f64, delta_y: f64) -> NavigationEvent {
|
||||||
));
|
assert_initialized_main_thread!();
|
||||||
let x = x.assume_init();
|
Self::MouseScroll {
|
||||||
let y = y.assume_init();
|
|
||||||
let delta_x = delta_x.assume_init();
|
|
||||||
let delta_y = delta_y.assume_init();
|
|
||||||
if ret {
|
|
||||||
Ok(Self {
|
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
delta_x,
|
delta_x,
|
||||||
delta_y,
|
delta_y,
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(glib::bool_error!("Invalid mouse button event"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
pub fn new_command(command: NavigationCommand) -> NavigationEvent {
|
||||||
pub struct CommandEvent {
|
|
||||||
cmd: NavigationCommand,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommandEvent {
|
|
||||||
#[doc(alias = "gst_navigation_event_parse_command")]
|
|
||||||
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe {
|
Self::Command { command }
|
||||||
let mut command = mem::MaybeUninit::uninit();
|
|
||||||
let ret = from_glib(ffi::gst_navigation_event_parse_command(
|
|
||||||
event.as_mut_ptr(),
|
|
||||||
command.as_mut_ptr(),
|
|
||||||
));
|
|
||||||
let command = command.assume_init();
|
|
||||||
if ret {
|
|
||||||
Ok(Self {
|
|
||||||
cmd: from_glib(command),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(glib::bool_error!("Invalid navigation command event"))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub enum NavigationEvent {
|
|
||||||
KeyPress(KeyEvent),
|
|
||||||
KeyRelease(KeyEvent),
|
|
||||||
MouseMove(MouseMoveEvent),
|
|
||||||
MouseButtonPress(MouseButtonEvent),
|
|
||||||
MouseButtonRelease(MouseButtonEvent),
|
|
||||||
Command(CommandEvent),
|
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
|
||||||
MouseScroll(MouseScrollEvent),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NavigationEvent {
|
|
||||||
#[doc(alias = "gst_navigation_event_get_type")]
|
#[doc(alias = "gst_navigation_event_get_type")]
|
||||||
pub fn type_(event: &gst::EventRef) -> NavigationEventType {
|
pub fn type_(event: &gst::EventRef) -> NavigationEventType {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
unsafe { from_glib(ffi::gst_navigation_event_get_type(event.as_mut_ptr())) }
|
unsafe { from_glib(ffi::gst_navigation_event_get_type(event.as_mut_ptr())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(alias = "gst_navigation_event_parse_mouse_button_event")]
|
||||||
|
#[doc(alias = "gst_navigation_event_parse_mouse_command")]
|
||||||
|
#[doc(alias = "gst_navigation_event_parse_mouse_scroll_event")]
|
||||||
|
#[doc(alias = "gst_navigation_event_parse_mouse_move_event")]
|
||||||
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
|
||||||
let event_type: NavigationEventType = Self::type_(event);
|
let structure = event
|
||||||
|
.structure()
|
||||||
match event_type {
|
.ok_or_else(|| glib::bool_error!("Invalid mouse event"))?;
|
||||||
NavigationEventType::MouseMove => MouseMoveEvent::parse(event).map(Self::MouseMove),
|
Ok(match Self::type_(event) {
|
||||||
NavigationEventType::KeyPress => KeyEvent::parse(event).map(Self::KeyPress),
|
NavigationEventType::MouseMove => Self::new_mouse_move(
|
||||||
NavigationEventType::KeyRelease => KeyEvent::parse(event).map(Self::KeyRelease),
|
structure
|
||||||
|
.get("pointer_x")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
structure
|
||||||
|
.get("pointer_y")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
),
|
||||||
|
NavigationEventType::MouseButtonPress => Self::new_mouse_button_press(
|
||||||
|
structure
|
||||||
|
.get("button")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
structure
|
||||||
|
.get("pointer_x")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
structure
|
||||||
|
.get("pointer_y")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
),
|
||||||
|
NavigationEventType::MouseButtonRelease => Self::new_mouse_button_press(
|
||||||
|
structure
|
||||||
|
.get("button")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
structure
|
||||||
|
.get("pointer_x")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
structure
|
||||||
|
.get("pointer_y")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
),
|
||||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||||
NavigationEventType::MouseScroll => {
|
NavigationEventType::MouseScroll => Self::new_mouse_scroll(
|
||||||
MouseScrollEvent::parse(event).map(Self::MouseScroll)
|
structure
|
||||||
}
|
.get("pointer_x")
|
||||||
NavigationEventType::MouseButtonPress => {
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
MouseButtonEvent::parse(event).map(Self::MouseButtonPress)
|
structure
|
||||||
}
|
.get("pointer_y")
|
||||||
NavigationEventType::MouseButtonRelease => {
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
MouseButtonEvent::parse(event).map(Self::MouseButtonRelease)
|
structure
|
||||||
}
|
.get("delta_pointer_x")
|
||||||
NavigationEventType::Command => CommandEvent::parse(event).map(Self::Command),
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
structure
|
||||||
|
.get("delta_pointer_y")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid mouse event"))?,
|
||||||
|
),
|
||||||
|
NavigationEventType::KeyPress => Self::new_key_press(
|
||||||
|
structure
|
||||||
|
.get("key")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid key press event"))?,
|
||||||
|
),
|
||||||
|
NavigationEventType::KeyRelease => Self::new_key_release(
|
||||||
|
structure
|
||||||
|
.get("key")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid key press event"))?,
|
||||||
|
),
|
||||||
|
NavigationEventType::Command => Self::new_command(
|
||||||
|
structure
|
||||||
|
.get("command-code")
|
||||||
|
.map_err(|_| glib::bool_error!("Invalid key press event"))?,
|
||||||
|
),
|
||||||
NavigationEventType::Invalid | NavigationEventType::__Unknown(_) => {
|
NavigationEventType::Invalid | NavigationEventType::__Unknown(_) => {
|
||||||
return Err(glib::bool_error!("Invalid navigation event"))
|
return Err(glib::bool_error!("Invalid navigation event"))
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build(&self) -> gst::Event {
|
||||||
|
skip_assert_initialized!();
|
||||||
|
|
||||||
|
gst::event::Navigation::new(match self {
|
||||||
|
Self::MouseMove { x, y } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "mouse-move")
|
||||||
|
.field("pointer_x", x)
|
||||||
|
.field("pointer_y", y)
|
||||||
|
.build(),
|
||||||
|
Self::MouseButtonPress { button, x, y } => {
|
||||||
|
gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "mouse-button-press")
|
||||||
|
.field("button", button)
|
||||||
|
.field("pointer_x", x)
|
||||||
|
.field("pointer_y", y)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
Self::MouseButtonRelease { button, x, y } => {
|
||||||
|
gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "mouse-button-release")
|
||||||
|
.field("button", button)
|
||||||
|
.field("pointer_x", x)
|
||||||
|
.field("pointer_y", y)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
|
||||||
|
Self::MouseScroll {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
delta_x,
|
||||||
|
delta_y,
|
||||||
|
} => gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "mouse-scroll")
|
||||||
|
.field("pointer_x", x)
|
||||||
|
.field("pointer_y", y)
|
||||||
|
.field("delta_pointer_x", delta_x)
|
||||||
|
.field("delta_pointer_y", delta_y)
|
||||||
|
.build(),
|
||||||
|
Self::KeyPress { key } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "key-press")
|
||||||
|
.field("key", key)
|
||||||
|
.build(),
|
||||||
|
Self::KeyRelease { key } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "key-release")
|
||||||
|
.field("key", key)
|
||||||
|
.build(),
|
||||||
|
Self::Command { command } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
|
||||||
|
.field("event", "command")
|
||||||
|
.field("command-code", command)
|
||||||
|
.build(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
fn serialize_navigation_events() {
|
||||||
|
use crate::NavigationEvent;
|
||||||
|
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
let ev = NavigationEvent::new_mouse_scroll(1.0, 2.0, 3.0, 4.0).build();
|
||||||
|
let navigation_event = NavigationEvent::parse(&ev).unwrap();
|
||||||
|
match &navigation_event {
|
||||||
|
NavigationEvent::MouseScroll {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
delta_x,
|
||||||
|
delta_y,
|
||||||
|
} => {
|
||||||
|
assert!(*x == 1.0 && *y == 2.0 && *delta_x == 3.0 && *delta_y == 4.0);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let json_event = serde_json::to_string(&navigation_event).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
json_event,
|
||||||
|
r#"{"event":"MouseScroll","x":1.0,"y":2.0,"delta_x":3.0,"delta_y":4.0}"#
|
||||||
|
);
|
||||||
|
let navigation_event: NavigationEvent = serde_json::from_str(&json_event).unwrap();
|
||||||
|
match &navigation_event {
|
||||||
|
NavigationEvent::MouseScroll {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
delta_x,
|
||||||
|
delta_y,
|
||||||
|
} => {
|
||||||
|
assert!(*x == 1.0 && *y == 2.0 && *delta_x == 3.0 && *delta_y == 4.0);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let ev = NavigationEvent::new_mouse_button_press(1, 1.0, 2.0).build();
|
||||||
|
let navigation_event = NavigationEvent::parse(&ev).unwrap();
|
||||||
|
match &navigation_event {
|
||||||
|
NavigationEvent::MouseButtonPress { button, x, y } => {
|
||||||
|
assert!(*button == 1 && *x == 1.0 && *y == 2.0);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let json_event = serde_json::to_string(&navigation_event).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
json_event,
|
||||||
|
r#"{"event":"MouseButtonPress","button":1,"x":1.0,"y":2.0}"#
|
||||||
|
);
|
||||||
|
|
||||||
|
let ev = NavigationEvent::new_key_release("a").build();
|
||||||
|
let navigation_event = NavigationEvent::parse(&ev).unwrap();
|
||||||
|
match &navigation_event {
|
||||||
|
NavigationEvent::KeyRelease { key } => {
|
||||||
|
assert_eq!(key, "a");
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let json_event = serde_json::to_string(&navigation_event).unwrap();
|
||||||
|
assert_eq!(json_event, r#"{"event":"KeyRelease","key":"a"}"#);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue