Skip to content

Commit

Permalink
Merge pull request #2073 from iced-rs/event-helpers
Browse files Browse the repository at this point in the history
Add `keyboard` subscriptions and rename `subscription::events` to `event::listen`
  • Loading branch information
hecrj authored Sep 7, 2023
2 parents a56b25b + d21f069 commit c8fed14
Show file tree
Hide file tree
Showing 15 changed files with 208 additions and 139 deletions.
5 changes: 2 additions & 3 deletions examples/events/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use iced::alignment;
use iced::event::{self, Event};
use iced::executor;
use iced::subscription;
use iced::widget::{button, checkbox, container, text, Column};
use iced::window;
use iced::Event;
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
Theme,
Expand Down Expand Up @@ -71,7 +70,7 @@ impl Application for Events {
}

fn subscription(&self) -> Subscription<Message> {
subscription::events().map(Message::EventOccurred)
event::listen().map(Message::EventOccurred)
}

fn view(&self) -> Element<Message> {
Expand Down
8 changes: 5 additions & 3 deletions examples/modal/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
use iced::subscription::{self, Subscription};
use iced::theme;
use iced::widget::{
self, button, column, container, horizontal_space, pick_list, row, text,
text_input,
};
use iced::{Alignment, Application, Command, Element, Event, Length, Settings};
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
};

use modal::Modal;
use std::fmt;
Expand Down Expand Up @@ -49,7 +51,7 @@ impl Application for App {
}

fn subscription(&self) -> Subscription<Self::Message> {
subscription::events().map(Message::Event)
event::listen().map(Message::Event)
}

fn update(&mut self, message: Message) -> Command<Message> {
Expand Down
14 changes: 3 additions & 11 deletions examples/pane_grid/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use iced::alignment::{self, Alignment};
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
use iced::subscription;
use iced::theme::{self, Theme};
use iced::widget::pane_grid::{self, PaneGrid};
use iced::widget::{
Expand Down Expand Up @@ -146,18 +144,12 @@ impl Application for Example {
}

fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, status| {
if let event::Status::Captured = status {
keyboard::on_key_press(|key_code, modifiers| {
if !modifiers.command() {
return None;
}

match event {
Event::Keyboard(keyboard::Event::KeyPressed {
modifiers,
key_code,
}) if modifiers.command() => handle_hotkey(key_code),
_ => None,
}
handle_hotkey(key_code)
})
}

Expand Down
7 changes: 3 additions & 4 deletions examples/screenshot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use iced::theme::{Button, Container};
use iced::widget::{button, column, container, image, row, text, text_input};
use iced::window::screenshot::{self, Screenshot};
use iced::{
event, executor, keyboard, subscription, Alignment, Application, Command,
ContentFit, Element, Event, Length, Rectangle, Renderer, Subscription,
Theme,
event, executor, keyboard, Alignment, Application, Command, ContentFit,
Element, Event, Length, Rectangle, Renderer, Subscription, Theme,
};

use ::image as img;
Expand Down Expand Up @@ -254,7 +253,7 @@ impl Application for Example {
}

fn subscription(&self) -> Subscription<Self::Message> {
subscription::events_with(|event, status| {
event::listen_with(|event, status| {
if let event::Status::Captured = status {
return None;
}
Expand Down
16 changes: 15 additions & 1 deletion examples/stopwatch/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use iced::alignment;
use iced::executor;
use iced::keyboard;
use iced::theme::{self, Theme};
use iced::time;
use iced::widget::{button, column, container, row, text};
Expand Down Expand Up @@ -77,12 +78,25 @@ impl Application for Stopwatch {
}

fn subscription(&self) -> Subscription<Message> {
match self.state {
let tick = match self.state {
State::Idle => Subscription::none(),
State::Ticking { .. } => {
time::every(Duration::from_millis(10)).map(Message::Tick)
}
};

fn handle_hotkey(
key_code: keyboard::KeyCode,
_modifiers: keyboard::Modifiers,
) -> Option<Message> {
match key_code {
keyboard::KeyCode::Space => Some(Message::Toggle),
keyboard::KeyCode::R => Some(Message::Reset),
_ => None,
}
}

Subscription::batch(vec![tick, keyboard::on_key_press(handle_hotkey)])
}

fn view(&self) -> Element<Message> {
Expand Down
8 changes: 5 additions & 3 deletions examples/toast/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use iced::event::{self, Event};
use iced::executor;
use iced::keyboard;
use iced::subscription::{self, Subscription};
use iced::widget::{
self, button, column, container, pick_list, row, slider, text, text_input,
};
use iced::{Alignment, Application, Command, Element, Event, Length, Settings};
use iced::{
Alignment, Application, Command, Element, Length, Settings, Subscription,
};

use toast::{Status, Toast};

Expand Down Expand Up @@ -57,7 +59,7 @@ impl Application for App {
}

fn subscription(&self) -> Subscription<Self::Message> {
subscription::events().map(Message::Event)
event::listen().map(Message::Event)
}

fn update(&mut self, message: Message) -> Command<Message> {
Expand Down
40 changes: 12 additions & 28 deletions examples/todos/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use iced::alignment::{self, Alignment};
use iced::event::{self, Event};
use iced::font::{self, Font};
use iced::keyboard::{self, KeyCode, Modifiers};
use iced::subscription;
use iced::keyboard;
use iced::theme::{self, Theme};
use iced::widget::{
self, button, checkbox, column, container, row, scrollable, text,
Expand Down Expand Up @@ -52,7 +50,7 @@ enum Message {
FilterChanged(Filter),
TaskMessage(usize, TaskMessage),
TabPressed { shift: bool },
ToggleFullscreen(window::Mode),
ChangeWindowMode(window::Mode),
}

impl Application for Todos {
Expand Down Expand Up @@ -163,7 +161,7 @@ impl Application for Todos {
widget::focus_next()
}
}
Message::ToggleFullscreen(mode) => {
Message::ChangeWindowMode(mode) => {
window::change_mode(mode)
}
_ => Command::none(),
Expand Down Expand Up @@ -262,33 +260,19 @@ impl Application for Todos {
}

fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, status| match (event, status) {
(
Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,
modifiers,
..
keyboard::on_key_press(|key_code, modifiers| {
match (key_code, modifiers) {
(keyboard::KeyCode::Tab, _) => Some(Message::TabPressed {
shift: modifiers.shift(),
}),
event::Status::Ignored,
) => Some(Message::TabPressed {
shift: modifiers.shift(),
}),
(
Event::Keyboard(keyboard::Event::KeyPressed {
key_code,
modifiers: Modifiers::SHIFT,
}),
event::Status::Ignored,
) => match key_code {
KeyCode::Up => {
Some(Message::ToggleFullscreen(window::Mode::Fullscreen))
(keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => {
Some(Message::ChangeWindowMode(window::Mode::Fullscreen))
}
KeyCode::Down => {
Some(Message::ToggleFullscreen(window::Mode::Windowed))
(keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => {
Some(Message::ChangeWindowMode(window::Mode::Windowed))
}
_ => None,
},
_ => None,
}
})
}
}
Expand Down
13 changes: 7 additions & 6 deletions examples/url_handler/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use iced::event::{Event, MacOS, PlatformSpecific};
use iced::event::{self, Event};
use iced::executor;
use iced::subscription;
use iced::widget::{container, text};
use iced::{
Application, Command, Element, Length, Settings, Subscription, Theme,
Expand Down Expand Up @@ -37,9 +36,11 @@ impl Application for App {
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::EventOccurred(event) => {
if let Event::PlatformSpecific(PlatformSpecific::MacOS(
MacOS::ReceivedUrl(url),
)) = event
if let Event::PlatformSpecific(
event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl(
url,
)),
) = event
{
self.url = Some(url);
}
Expand All @@ -50,7 +51,7 @@ impl Application for App {
}

fn subscription(&self) -> Subscription<Message> {
subscription::events().map(Message::EventOccurred)
event::listen().map(Message::EventOccurred)
}

fn view(&self) -> Element<Message> {
Expand Down
8 changes: 4 additions & 4 deletions examples/visible_bounds/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use iced::event::{self, Event};
use iced::executor;
use iced::mouse;
use iced::subscription::{self, Subscription};
use iced::theme::{self, Theme};
use iced::widget::{
column, container, horizontal_space, row, scrollable, text, vertical_space,
};
use iced::window;
use iced::{
Alignment, Application, Color, Command, Element, Event, Font, Length,
Point, Rectangle, Settings,
Alignment, Application, Color, Command, Element, Font, Length, Point,
Rectangle, Settings, Subscription,
};

pub fn main() -> iced::Result {
Expand Down Expand Up @@ -163,7 +163,7 @@ impl Application for Example {
}

fn subscription(&self) -> Subscription<Message> {
subscription::events_with(|event, _| match event {
event::listen_with(|event, _| match event {
Event::Mouse(mouse::Event::CursorMoved { position }) => {
Some(Message::MouseMoved(position))
}
Expand Down
59 changes: 59 additions & 0 deletions futures/src/event.rs
Original file line number Diff line number Diff line change
@@ -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)
}
Loading

0 comments on commit c8fed14

Please sign in to comment.