summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/application.rs77
-rw-r--r--src/element.rs9
-rw-r--r--src/executor.rs68
-rw-r--r--src/lib.rs29
-rw-r--r--src/native.rs113
-rw-r--r--src/sandbox.rs9
-rw-r--r--src/settings.rs37
-rw-r--r--src/web.rs1
-rw-r--r--src/widget.rs60
-rw-r--r--src/window.rs6
-rw-r--r--src/window/mode.rs9
-rw-r--r--src/window/settings.rs22
12 files changed, 292 insertions, 148 deletions
diff --git a/src/application.rs b/src/application.rs
index a4d20e68..2ee3337f 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -1,4 +1,4 @@
-use crate::{Command, Element, Settings};
+use crate::{window, Command, Element, Executor, Settings, Subscription};
/// An interactive cross-platform application.
///
@@ -19,7 +19,7 @@ use crate::{Command, Element, Settings};
/// before](index.html#overview). We just need to fill in the gaps:
///
/// ```no_run
-/// use iced::{button, Application, Button, Column, Command, Element, Settings, Text};
+/// use iced::{button, executor, Application, Button, Column, Command, Element, Settings, Text};
///
/// pub fn main() {
/// Counter::run(Settings::default())
@@ -39,6 +39,7 @@ use crate::{Command, Element, Settings};
/// }
///
/// impl Application for Counter {
+/// type Executor = executor::Null;
/// type Message = Message;
///
/// fn new() -> (Self, Command<Message>) {
@@ -80,10 +81,18 @@ use crate::{Command, Element, Settings};
/// }
/// ```
pub trait Application: Sized {
+ /// The [`Executor`] that will run commands and subscriptions.
+ ///
+ /// The [`executor::Default`] can be a good starting point!
+ ///
+ /// [`Executor`]: trait.Executor.html
+ /// [`executor::Default`]: executor/struct.Default.html
+ type Executor: Executor;
+
/// The type of __messages__ your [`Application`] will produce.
///
/// [`Application`]: trait.Application.html
- type Message: std::fmt::Debug + Send + Clone;
+ type Message: std::fmt::Debug + Send;
/// Initializes the [`Application`].
///
@@ -117,6 +126,20 @@ pub trait Application: Sized {
/// [`Command`]: struct.Command.html
fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
+ /// Returns the event [`Subscription`] for the current state of the
+ /// application.
+ ///
+ /// A [`Subscription`] will be kept alive as long as you keep returning it,
+ /// and the __messages__ produced will be handled by
+ /// [`update`](#tymethod.update).
+ ///
+ /// By default, this method returns an empty [`Subscription`].
+ ///
+ /// [`Subscription`]: struct.Subscription.html
+ fn subscription(&self) -> Subscription<Self::Message> {
+ Subscription::none()
+ }
+
/// Returns the widgets to display in the [`Application`].
///
/// These widgets can produce __messages__ based on user interaction.
@@ -124,6 +147,20 @@ pub trait Application: Sized {
/// [`Application`]: trait.Application.html
fn view(&mut self) -> Element<'_, Self::Message>;
+ /// Returns the current [`Application`] mode.
+ ///
+ /// The runtime will automatically transition your application if a new mode
+ /// is returned.
+ ///
+ /// Currently, the mode only has an effect in native platforms.
+ ///
+ /// By default, an application will run in windowed mode.
+ ///
+ /// [`Application`]: trait.Application.html
+ fn mode(&self) -> window::Mode {
+ window::Mode::Windowed
+ }
+
/// Runs the [`Application`].
///
/// This method will take control of the current thread and __will NOT
@@ -132,12 +169,23 @@ pub trait Application: Sized {
/// It should probably be that last thing you call in your `main` function.
///
/// [`Application`]: trait.Application.html
- fn run(settings: Settings)
+ fn run(_settings: Settings)
where
Self: 'static,
{
#[cfg(not(target_arch = "wasm32"))]
- <Instance<Self> as iced_winit::Application>::run(settings.into());
+ <Instance<Self> as iced_winit::Application>::run(
+ _settings.into(),
+ iced_wgpu::Settings {
+ default_font: _settings.default_font,
+ antialiasing: if _settings.antialiasing {
+ Some(iced_wgpu::settings::Antialiasing::MSAAx4)
+ } else {
+ None
+ },
+ ..iced_wgpu::Settings::default()
+ },
+ );
#[cfg(target_arch = "wasm32")]
<Instance<Self> as iced_web::Application>::run();
@@ -151,7 +199,8 @@ impl<A> iced_winit::Application for Instance<A>
where
A: Application,
{
- type Renderer = iced_wgpu::Renderer;
+ type Backend = iced_wgpu::window::Backend;
+ type Executor = A::Executor;
type Message = A::Message;
fn new() -> (Self, Command<A::Message>) {
@@ -164,10 +213,21 @@ where
self.0.title()
}
+ fn mode(&self) -> iced_winit::Mode {
+ match self.0.mode() {
+ window::Mode::Windowed => iced_winit::Mode::Windowed,
+ window::Mode::Fullscreen => iced_winit::Mode::Fullscreen,
+ }
+ }
+
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
self.0.update(message)
}
+ fn subscription(&self) -> Subscription<Self::Message> {
+ self.0.subscription()
+ }
+
fn view(&mut self) -> Element<'_, Self::Message> {
self.0.view()
}
@@ -179,6 +239,7 @@ where
A: Application,
{
type Message = A::Message;
+ type Executor = A::Executor;
fn new() -> (Self, Command<A::Message>) {
let (app, command) = A::new();
@@ -194,6 +255,10 @@ where
self.0.update(message)
}
+ fn subscription(&self) -> Subscription<Self::Message> {
+ self.0.subscription()
+ }
+
fn view(&mut self) -> Element<'_, Self::Message> {
self.0.view()
}
diff --git a/src/element.rs b/src/element.rs
new file mode 100644
index 00000000..e5356fb6
--- /dev/null
+++ b/src/element.rs
@@ -0,0 +1,9 @@
+/// A generic widget.
+///
+/// This is an alias of an `iced_native` element with a default `Renderer`.
+#[cfg(not(target_arch = "wasm32"))]
+pub type Element<'a, Message> =
+ iced_winit::Element<'a, Message, iced_wgpu::Renderer>;
+
+#[cfg(target_arch = "wasm32")]
+pub use iced_web::Element;
diff --git a/src/executor.rs b/src/executor.rs
new file mode 100644
index 00000000..b4be5264
--- /dev/null
+++ b/src/executor.rs
@@ -0,0 +1,68 @@
+//! Choose your preferred executor to power your application.
+pub use crate::common::{executor::Null, Executor};
+
+pub use platform::Default;
+
+#[cfg(not(target_arch = "wasm32"))]
+mod platform {
+ use iced_futures::{executor, futures};
+
+ #[cfg(feature = "tokio")]
+ type Executor = executor::Tokio;
+
+ #[cfg(all(not(feature = "tokio"), feature = "async-std"))]
+ type Executor = executor::AsyncStd;
+
+ #[cfg(not(any(feature = "tokio", feature = "async-std")))]
+ type Executor = executor::ThreadPool;
+
+ /// A default cross-platform executor.
+ ///
+ /// - On native platforms, it will use:
+ /// - `iced_futures::executor::Tokio` when the `tokio` feature is enabled.
+ /// - `iced_futures::executor::AsyncStd` when the `async-std` feature is
+ /// enabled.
+ /// - `iced_futures::executor::ThreadPool` otherwise.
+ /// - On the Web, it will use `iced_futures::executor::WasmBindgen`.
+ #[derive(Debug)]
+ pub struct Default(Executor);
+
+ impl super::Executor for Default {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Default(Executor::new()?))
+ }
+
+ fn spawn(
+ &self,
+ future: impl futures::Future<Output = ()> + Send + 'static,
+ ) {
+ let _ = self.0.spawn(future);
+ }
+
+ fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
+ self.0.enter(f)
+ }
+ }
+}
+
+#[cfg(target_arch = "wasm32")]
+mod platform {
+ use iced_futures::{executor::WasmBindgen, futures, Executor};
+
+ /// A default cross-platform executor.
+ ///
+ /// - On native platforms, it will use `iced_futures::executor::ThreadPool`.
+ /// - On the Web, it will use `iced_futures::executor::WasmBindgen`.
+ #[derive(Debug)]
+ pub struct Default(WasmBindgen);
+
+ impl Executor for Default {
+ fn new() -> Result<Self, futures::io::Error> {
+ Ok(Default(WasmBindgen::new()?))
+ }
+
+ fn spawn(&self, future: impl futures::Future<Output = ()> + 'static) {
+ self.0.spawn(future);
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index dd828afd..d492db02 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -171,23 +171,38 @@
//!
//! [Elm]: https://elm-lang.org/
//! [The Elm Architecture]: https://guide.elm-lang.org/architecture/
-//! [documentation]: https://docs.rs/iced
//! [examples]: https://github.com/hecrj/iced/tree/master/examples
//! [`Application`]: trait.Application.html
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
-#![deny(unsafe_code)]
-#![deny(rust_2018_idioms)]
+#![forbid(unsafe_code)]
+#![forbid(rust_2018_idioms)]
mod application;
-#[cfg_attr(target_arch = "wasm32", path = "web.rs")]
-#[cfg_attr(not(target_arch = "wasm32"), path = "native.rs")]
-mod platform;
+mod element;
mod sandbox;
+pub mod executor;
pub mod settings;
+pub mod widget;
+pub mod window;
+
+#[doc(no_inline)]
+pub use widget::*;
pub use application::Application;
-pub use platform::*;
+pub use element::Element;
+pub use executor::Executor;
pub use sandbox::Sandbox;
pub use settings::Settings;
+
+#[cfg(not(target_arch = "wasm32"))]
+use iced_winit as common;
+
+#[cfg(target_arch = "wasm32")]
+use iced_web as common;
+
+pub use common::{
+ futures, Align, Background, Color, Command, Font, HorizontalAlignment,
+ Length, Point, Size, Space, Subscription, Vector, VerticalAlignment,
+};
diff --git a/src/native.rs b/src/native.rs
deleted file mode 100644
index 926b2d11..00000000
--- a/src/native.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-pub use iced_winit::{
- Align, Background, Color, Command, Font, HorizontalAlignment, Length,
- VerticalAlignment,
-};
-
-pub mod widget {
- //! Display information and interactive controls in your application.
- //!
- //! # Re-exports
- //! For convenience, the contents of this module are available at the root
- //! module. Therefore, you can directly type:
- //!
- //! ```
- //! use iced::{button, Button};
- //! ```
- //!
- //! # Stateful widgets
- //! Some widgets need to keep track of __local state__.
- //!
- //! These widgets have their own module with a `State` type. For instance, a
- //! [`TextInput`] has some [`text_input::State`].
- //!
- //! [`TextInput`]: text_input/struct.TextInput.html
- //! [`text_input::State`]: text_input/struct.State.html
- pub mod button {
- //! Allow your users to perform actions by pressing a button.
- //!
- //! A [`Button`] has some local [`State`].
- //!
- //! [`Button`]: type.Button.html
- //! [`State`]: struct.State.html
-
- /// A widget that produces a message when clicked.
- ///
- /// This is an alias of an `iced_native` button with a default
- /// `Renderer`.
- pub type Button<'a, Message> =
- iced_winit::Button<'a, Message, iced_wgpu::Renderer>;
-
- pub use iced_winit::button::State;
- }
-
- pub mod scrollable {
- //! Navigate an endless amount of content with a scrollbar.
-
- /// A widget that can vertically display an infinite amount of content
- /// with a scrollbar.
- ///
- /// This is an alias of an `iced_native` scrollable with a default
- /// `Renderer`.
- pub type Scrollable<'a, Message> =
- iced_winit::Scrollable<'a, Message, iced_wgpu::Renderer>;
-
- pub use iced_winit::scrollable::State;
- }
-
- pub mod text_input {
- //! Ask for information using text fields.
- //!
- //! A [`TextInput`] has some local [`State`].
- //!
- //! [`TextInput`]: struct.TextInput.html
- //! [`State`]: struct.State.html
- pub use iced_winit::text_input::{State, TextInput};
- }
-
- pub mod slider {
- //! Display an interactive selector of a single value from a range of
- //! values.
- //!
- //! A [`Slider`] has some local [`State`].
- //!
- //! [`Slider`]: struct.Slider.html
- //! [`State`]: struct.State.html
- pub use iced_winit::slider::{Slider, State};
- }
-
- pub use iced_winit::{Checkbox, Image, Radio, Text};
-
- #[doc(no_inline)]
- pub use {
- button::Button, scrollable::Scrollable, slider::Slider,
- text_input::TextInput,
- };
-
- /// A container that distributes its contents vertically.
- ///
- /// This is an alias of an `iced_native` column with a default `Renderer`.
- pub type Column<'a, Message> =
- iced_winit::Column<'a, Message, iced_wgpu::Renderer>;
-
- /// A container that distributes its contents horizontally.
- ///
- /// This is an alias of an `iced_native` row with a default `Renderer`.
- pub type Row<'a, Message> =
- iced_winit::Row<'a, Message, iced_wgpu::Renderer>;
-
- /// An element decorating some content.
- ///
- /// This is an alias of an `iced_native` container with a default
- /// `Renderer`.
- pub type Container<'a, Message> =
- iced_winit::Container<'a, Message, iced_wgpu::Renderer>;
-}
-
-#[doc(no_inline)]
-pub use widget::*;
-
-/// A generic widget.
-///
-/// This is an alias of an `iced_native` element with a default `Renderer`.
-pub type Element<'a, Message> =
- iced_winit::Element<'a, Message, iced_wgpu::Renderer>;
diff --git a/src/sandbox.rs b/src/sandbox.rs
index acf7f5e0..2c0332ff 100644
--- a/src/sandbox.rs
+++ b/src/sandbox.rs
@@ -1,4 +1,4 @@
-use crate::{Application, Command, Element, Settings};
+use crate::{executor, Application, Command, Element, Settings, Subscription};
/// A sandboxed [`Application`].
///
@@ -81,7 +81,7 @@ pub trait Sandbox {
/// The type of __messages__ your [`Sandbox`] will produce.
///
/// [`Sandbox`]: trait.Sandbox.html
- type Message: std::fmt::Debug + Send + Clone;
+ type Message: std::fmt::Debug + Send;
/// Initializes the [`Sandbox`].
///
@@ -133,6 +133,7 @@ impl<T> Application for T
where
T: Sandbox,
{
+ type Executor = executor::Null;
type Message = T::Message;
fn new() -> (Self, Command<T::Message>) {
@@ -149,6 +150,10 @@ where
Command::none()
}
+ fn subscription(&self) -> Subscription<T::Message> {
+ Subscription::none()
+ }
+
fn view(&mut self) -> Element<'_, T::Message> {
T::view(self)
}
diff --git a/src/settings.rs b/src/settings.rs
index 2556c51b..32ec583c 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -1,33 +1,30 @@
//! Configure your application.
+use crate::window;
/// The settings of an application.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Settings {
- /// The [`Window`] settings.
+ /// The window settings.
///
/// They will be ignored on the Web.
///
/// [`Window`]: struct.Window.html
- pub window: Window,
-}
-
-/// The window settings of an application.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct Window {
- /// The size of the window.
- pub size: (u32, u32),
+ pub window: window::Settings,
- /// Whether the window should be resizable or not.
- pub resizable: bool,
-}
+ /// The bytes of the font that will be used by default.
+ ///
+ /// If `None` is provided, a default system font will be chosen.
+ // TODO: Add `name` for web compatibility
+ pub default_font: Option<&'static [u8]>,
-impl Default for Window {
- fn default() -> Window {
- Window {
- size: (1024, 768),
- resizable: true,
- }
- }
+ /// If set to true, the renderer will try to perform antialiasing for some
+ /// primitives.
+ ///
+ /// Enabling it can produce a smoother result in some widgets, like the
+ /// `Canvas`, at a performance cost.
+ ///
+ /// By default, it is disabled.
+ pub antialiasing: bool,
}
#[cfg(not(target_arch = "wasm32"))]
@@ -37,6 +34,8 @@ impl From<Settings> for iced_winit::Settings {
window: iced_winit::settings::Window {
size: settings.window.size,
resizable: settings.window.resizable,
+ decorations: settings.window.decorations,
+ platform_specific: Default::default(),
},
}
}
diff --git a/src/web.rs b/src/web.rs
deleted file mode 100644
index 31f1a6fc..00000000
--- a/src/web.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub use iced_web::*;
diff --git a/src/widget.rs b/src/widget.rs
new file mode 100644
index 00000000..7d3a1cef
--- /dev/null
+++ b/src/widget.rs
@@ -0,0 +1,60 @@
+//! Display information and interactive controls in your application.
+//!
+//! # Re-exports
+//! For convenience, the contents of this module are available at the root
+//! module. Therefore, you can directly type:
+//!
+//! ```
+//! use iced::{button, Button};
+//! ```
+//!
+//! # Stateful widgets
+//! Some widgets need to keep track of __local state__.
+//!
+//! These widgets have their own module with a `State` type. For instance, a
+//! [`TextInput`] has some [`text_input::State`].
+//!
+//! [`TextInput`]: text_input/struct.TextInput.html
+//! [`text_input::State`]: text_input/struct.State.html
+#[cfg(not(target_arch = "wasm32"))]
+mod platform {
+ pub use iced_wgpu::widget::*;
+
+ pub mod image {
+ //! Display images in your user interface.
+ pub use iced_winit::image::{Handle, Image};
+ }
+
+ pub mod svg {
+ //! Display vector graphics in your user interface.
+ pub use iced_winit::svg::{Handle, Svg};
+ }
+
+ pub use iced_winit::Text;
+
+ #[doc(no_inline)]
+ pub use {
+ button::Button, checkbox::Checkbox, container::Container, image::Image,
+ progress_bar::ProgressBar, radio::Radio, scrollable::Scrollable,
+ slider::Slider, svg::Svg, text_input::TextInput,
+ };
+
+ /// A container that distributes its contents vertically.
+ ///
+ /// This is an alias of an `iced_native` column with a default `Renderer`.
+ pub type Column<'a, Message> =
+ iced_winit::Column<'a, Message, iced_wgpu::Renderer>;
+
+ /// A container that distributes its contents horizontally.
+ ///
+ /// This is an alias of an `iced_native` row with a default `Renderer`.
+ pub type Row<'a, Message> =
+ iced_winit::Row<'a, Message, iced_wgpu::Renderer>;
+}
+
+#[cfg(target_arch = "wasm32")]
+mod platform {
+ pub use iced_web::widget::*;
+}
+
+pub use platform::*;
diff --git a/src/window.rs b/src/window.rs
new file mode 100644
index 00000000..54ea2a02
--- /dev/null
+++ b/src/window.rs
@@ -0,0 +1,6 @@
+//! Configure the window of your application in native platforms.
+mod mode;
+mod settings;
+
+pub use mode::Mode;
+pub use settings::Settings;
diff --git a/src/window/mode.rs b/src/window/mode.rs
new file mode 100644
index 00000000..37464711
--- /dev/null
+++ b/src/window/mode.rs
@@ -0,0 +1,9 @@
+/// The mode of a window-based application.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Mode {
+ /// The application appears in its own window.
+ Windowed,
+
+ /// The application takes the whole screen of its current monitor.
+ Fullscreen,
+}
diff --git a/src/window/settings.rs b/src/window/settings.rs
new file mode 100644
index 00000000..a31d2af2
--- /dev/null
+++ b/src/window/settings.rs
@@ -0,0 +1,22 @@
+/// The window settings of an application.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct Settings {
+ /// The size of the window.
+ pub size: (u32, u32),
+
+ /// Whether the window should be resizable or not.
+ pub resizable: bool,
+
+ /// Whether the window should have a border, a title bar, etc. or not.
+ pub decorations: bool,
+}
+
+impl Default for Settings {
+ fn default() -> Settings {
+ Settings {
+ size: (1024, 768),
+ resizable: true,
+ decorations: true,
+ }
+ }
+}