diff options
Diffstat (limited to 'futures/src')
| -rw-r--r-- | futures/src/event.rs | 59 | ||||
| -rw-r--r-- | futures/src/keyboard.rs | 61 | ||||
| -rw-r--r-- | futures/src/lib.rs | 2 | ||||
| -rw-r--r-- | futures/src/subscription.rs | 91 | 
4 files changed, 141 insertions, 72 deletions
| diff --git a/futures/src/event.rs b/futures/src/event.rs new file mode 100644 index 00000000..214d2d40 --- /dev/null +++ b/futures/src/event.rs @@ -0,0 +1,59 @@ +//! Listen to runtime events. +use crate::core::event::{self, Event}; +use crate::core::window; +use crate::subscription::{self, Subscription}; +use crate::MaybeSend; + +/// Returns a [`Subscription`] to all the ignored runtime events. +/// +/// This subscription will notify your application of any [`Event`] that was +/// not captured by any widget. +pub fn listen() -> Subscription<Event> { +    listen_with(|event, status| match status { +        event::Status::Ignored => Some(event), +        event::Status::Captured => None, +    }) +} + +/// Creates a [`Subscription`] that listens and filters all the runtime events +/// with the provided function, producing messages accordingly. +/// +/// This subscription will call the provided function for every [`Event`] +/// handled by the runtime. If the function: +/// +/// - Returns `None`, the [`Event`] will be discarded. +/// - Returns `Some` message, the `Message` will be produced. +pub fn listen_with<Message>( +    f: fn(Event, event::Status) -> Option<Message>, +) -> Subscription<Message> +where +    Message: 'static + MaybeSend, +{ +    #[derive(Hash)] +    struct EventsWith; + +    subscription::filter_map( +        (EventsWith, f), +        move |event, status| match event { +            Event::Window(window::Event::RedrawRequested(_)) => None, +            _ => f(event, status), +        }, +    ) +} + +/// Creates a [`Subscription`] that produces a message for every runtime event, +/// including the redraw request events. +/// +/// **Warning:** This [`Subscription`], if unfiltered, may produce messages in +/// an infinite loop. +pub fn listen_raw<Message>( +    f: fn(Event, event::Status) -> Option<Message>, +) -> Subscription<Message> +where +    Message: 'static + MaybeSend, +{ +    #[derive(Hash)] +    struct RawEvents; + +    subscription::filter_map((RawEvents, f), f) +} diff --git a/futures/src/keyboard.rs b/futures/src/keyboard.rs new file mode 100644 index 00000000..af68e1f2 --- /dev/null +++ b/futures/src/keyboard.rs @@ -0,0 +1,61 @@ +//! Listen to keyboard events. +use crate::core; +use crate::core::keyboard::{Event, KeyCode, Modifiers}; +use crate::subscription::{self, Subscription}; +use crate::MaybeSend; + +/// Listens to keyboard key presses and calls the given function +/// map them into actual messages. +/// +/// If the function returns `None`, the key press will be simply +/// ignored. +pub fn on_key_press<Message>( +    f: fn(KeyCode, Modifiers) -> Option<Message>, +) -> Subscription<Message> +where +    Message: MaybeSend + 'static, +{ +    #[derive(Hash)] +    struct OnKeyPress; + +    subscription::filter_map((OnKeyPress, f), move |event, status| { +        match (event, status) { +            ( +                core::Event::Keyboard(Event::KeyPressed { +                    key_code, +                    modifiers, +                }), +                core::event::Status::Ignored, +            ) => f(key_code, modifiers), +            _ => None, +        } +    }) +} + +/// Listens to keyboard key releases and calls the given function +/// map them into actual messages. +/// +/// If the function returns `None`, the key release will be simply +/// ignored. +pub fn on_key_release<Message>( +    f: fn(KeyCode, Modifiers) -> Option<Message>, +) -> Subscription<Message> +where +    Message: MaybeSend + 'static, +{ +    #[derive(Hash)] +    struct OnKeyRelease; + +    subscription::filter_map((OnKeyRelease, f), move |event, status| { +        match (event, status) { +            ( +                core::Event::Keyboard(Event::KeyReleased { +                    key_code, +                    modifiers, +                }), +                core::event::Status::Ignored, +            ) => f(key_code, modifiers), +            _ => None, +        } +    }) +} diff --git a/futures/src/lib.rs b/futures/src/lib.rs index 34d81e1e..8e75331f 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -24,7 +24,9 @@ mod maybe_send;  mod runtime;  pub mod backend; +pub mod event;  pub mod executor; +pub mod keyboard;  pub mod subscription;  pub use executor::Executor; diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index 8f78ce3a..759dd223 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -4,7 +4,6 @@ mod tracker;  pub use tracker::Tracker;  use crate::core::event::{self, Event}; -use crate::core::window;  use crate::core::Hasher;  use crate::futures::{Future, Stream};  use crate::{BoxStream, MaybeSend}; @@ -215,77 +214,6 @@ where      }  } -/// Returns a [`Subscription`] to all the ignored runtime events. -/// -/// This subscription will notify your application of any [`Event`] that was -/// not captured by any widget. -pub fn events() -> Subscription<Event> { -    events_with(|event, status| match status { -        event::Status::Ignored => Some(event), -        event::Status::Captured => None, -    }) -} - -/// Returns a [`Subscription`] that filters all the runtime events with the -/// provided function, producing messages accordingly. -/// -/// This subscription will call the provided function for every [`Event`] -/// handled by the runtime. If the function: -/// -/// - Returns `None`, the [`Event`] will be discarded. -/// - Returns `Some` message, the `Message` will be produced. -pub fn events_with<Message>( -    f: fn(Event, event::Status) -> Option<Message>, -) -> Subscription<Message> -where -    Message: 'static + MaybeSend, -{ -    #[derive(Hash)] -    struct EventsWith; - -    Subscription::from_recipe(Runner { -        id: (EventsWith, f), -        spawn: move |events| { -            use futures::future; -            use futures::stream::StreamExt; - -            events.filter_map(move |(event, status)| { -                future::ready(match event { -                    Event::Window(window::Event::RedrawRequested(_)) => None, -                    _ => f(event, status), -                }) -            }) -        }, -    }) -} - -/// Returns a [`Subscription`] that produces a message for every runtime event, -/// including the redraw request events. -/// -/// **Warning:** This [`Subscription`], if unfiltered, may produce messages in -/// an infinite loop. -pub fn raw_events<Message>( -    f: fn(Event, event::Status) -> Option<Message>, -) -> Subscription<Message> -where -    Message: 'static + MaybeSend, -{ -    #[derive(Hash)] -    struct RawEvents; - -    Subscription::from_recipe(Runner { -        id: (RawEvents, f), -        spawn: move |events| { -            use futures::future; -            use futures::stream::StreamExt; - -            events.filter_map(move |(event, status)| { -                future::ready(f(event, status)) -            }) -        }, -    }) -} -  /// Returns a [`Subscription`] that will call the given function to create and  /// asynchronously run the given [`Stream`].  pub fn run<S, Message>(builder: fn() -> S) -> Subscription<Message> @@ -338,6 +266,25 @@ where      )  } +pub(crate) fn filter_map<I, F, Message>(id: I, f: F) -> Subscription<Message> +where +    I: Hash + 'static, +    F: Fn(Event, event::Status) -> Option<Message> + MaybeSend + 'static, +    Message: 'static + MaybeSend, +{ +    Subscription::from_recipe(Runner { +        id, +        spawn: |events| { +            use futures::future; +            use futures::stream::StreamExt; + +            events.filter_map(move |(event, status)| { +                future::ready(f(event, status)) +            }) +        }, +    }) +} +  /// Creates a [`Subscription`] that publishes the events sent from a [`Future`]  /// to an [`mpsc::Sender`] with the given bounds.  /// | 
