Skip to main content

iced_runtime/
lib.rs

1//! A renderer-agnostic native GUI runtime.
2//!
3//! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/master/docs/graphs/native.png?raw=true)
4//!
5//! `iced_runtime` takes [`iced_core`] and builds a native runtime on top of it.
6//!
7//! [`iced_core`]: https://github.com/iced-rs/iced/tree/master/core
8#![doc(
9    html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
10)]
11#![cfg_attr(docsrs, feature(doc_cfg))]
12pub mod clipboard;
13pub mod font;
14pub mod image;
15pub mod keyboard;
16pub mod system;
17pub mod task;
18pub mod user_interface;
19pub mod widget;
20pub mod window;
21
22pub use iced_core as core;
23pub use iced_futures as futures;
24
25pub use task::Task;
26pub use user_interface::UserInterface;
27pub use window::Window;
28
29use crate::core::Event;
30
31use std::fmt;
32
33/// An action that the iced runtime can perform.
34pub enum Action<T> {
35    /// Output some value.
36    Output(T),
37
38    /// Run a widget operation.
39    Widget(Box<dyn core::widget::Operation>),
40
41    /// Run a clipboard action.
42    Clipboard(clipboard::Action),
43
44    /// Run a window action.
45    Window(window::Action),
46
47    /// Run a system action.
48    System(system::Action),
49
50    /// Run a font action.
51    Font(font::Action),
52
53    /// Run an image action.
54    Image(image::Action),
55
56    /// Produce an event.
57    Event {
58        /// The [`window::Id`](core::window::Id) of the event.
59        window: core::window::Id,
60        /// The [`Event`] to be produced.
61        event: Event,
62    },
63
64    /// Poll any resources that may have pending computations.
65    Tick,
66
67    /// Recreate all user interfaces and redraw all windows.
68    Reload,
69
70    /// Announce a message to assistive technology via a live region.
71    ///
72    /// The text will be spoken by screen readers on the next
73    /// accessibility tree update. The boolean flag selects politeness:
74    /// `true` for assertive (interrupts current announcement),
75    /// `false` for polite (waits for a gap).
76    Announce(String, bool),
77
78    /// Exits the runtime.
79    ///
80    /// This will normally close any application windows and
81    /// terminate the runtime loop.
82    Exit,
83}
84
85impl<T> Action<T> {
86    /// Creates a new [`Action::Widget`] with the given [`widget::Operation`](core::widget::Operation).
87    pub fn widget(operation: impl core::widget::Operation + 'static) -> Self {
88        Self::Widget(Box::new(operation))
89    }
90
91    fn output<O>(self) -> Result<T, Action<O>> {
92        match self {
93            Action::Output(output) => Ok(output),
94            Action::Widget(operation) => Err(Action::Widget(operation)),
95            Action::Clipboard(action) => Err(Action::Clipboard(action)),
96            Action::Window(action) => Err(Action::Window(action)),
97            Action::System(action) => Err(Action::System(action)),
98            Action::Font(action) => Err(Action::Font(action)),
99            Action::Image(action) => Err(Action::Image(action)),
100            Action::Event { window, event } => Err(Action::Event { window, event }),
101            Action::Tick => Err(Action::Tick),
102            Action::Reload => Err(Action::Reload),
103            Action::Exit => Err(Action::Exit),
104            Action::Announce(text, assertive) => Err(Action::Announce(text, assertive)),
105        }
106    }
107}
108
109impl<T> fmt::Debug for Action<T>
110where
111    T: fmt::Debug,
112{
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        match self {
115            Action::Output(output) => write!(f, "Action::Output({output:?})"),
116            Action::Widget { .. } => {
117                write!(f, "Action::Widget")
118            }
119            Action::Clipboard(action) => {
120                write!(f, "Action::Clipboard({action:?})")
121            }
122            Action::Window(_) => write!(f, "Action::Window"),
123            Action::System(action) => write!(f, "Action::System({action:?})"),
124            Action::Font(action) => {
125                write!(f, "Action::Font({action:?})")
126            }
127            Action::Image(_) => write!(f, "Action::Image"),
128            Action::Event { window, event } => write!(
129                f,
130                "Action::Event {{ window: {window:?}, event: {event:?} }}"
131            ),
132            Action::Tick => write!(f, "Action::Tick"),
133            Action::Reload => write!(f, "Action::Reload"),
134            Action::Exit => write!(f, "Action::Exit"),
135            Action::Announce(text, assertive) => {
136                write!(f, "Action::Announce({text:?}, assertive: {assertive})")
137            }
138        }
139    }
140}
141
142/// Creates a [`Task`] that announces the given text to assistive
143/// technology via a live region.
144///
145/// Screen readers will speak the text using an assertive announcement
146/// (interrupting any announcement currently in progress). For less
147/// urgent text, use [`announce_polite`] instead.
148#[cfg(feature = "a11y")]
149#[cfg_attr(docsrs, doc(cfg(feature = "a11y")))]
150pub fn announce<T>(text: impl Into<String>) -> Task<T> {
151    task::effect(Action::Announce(text.into(), true))
152}
153
154/// Creates a [`Task`] that announces the given text to assistive
155/// technology via a polite live region.
156///
157/// Screen readers will speak the text after a gap in the user's
158/// current announcement. This is the correct choice for most
159/// toast-style feedback (saves, confirmations, counts).
160#[cfg(feature = "a11y")]
161#[cfg_attr(docsrs, doc(cfg(feature = "a11y")))]
162pub fn announce_polite<T>(text: impl Into<String>) -> Task<T> {
163    task::effect(Action::Announce(text.into(), false))
164}
165
166/// Creates a [`Task`] that exits the iced runtime.
167///
168/// This will normally close any application windows and
169/// terminate the runtime loop.
170pub fn exit<T>() -> Task<T> {
171    task::effect(Action::Exit)
172}