diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/application.rs | 132 | ||||
-rw-r--r-- | src/error.rs | 13 | ||||
-rw-r--r-- | src/executor.rs | 31 | ||||
-rw-r--r-- | src/keyboard.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 26 | ||||
-rw-r--r-- | src/result.rs | 2 | ||||
-rw-r--r-- | src/sandbox.rs | 66 | ||||
-rw-r--r-- | src/settings.rs | 46 | ||||
-rw-r--r-- | src/time.rs | 2 | ||||
-rw-r--r-- | src/widget.rs | 22 | ||||
-rw-r--r-- | src/window.rs | 2 | ||||
-rw-r--r-- | src/window/icon.rs | 18 | ||||
-rw-r--r-- | src/window/mode.rs | 3 | ||||
-rw-r--r-- | src/window/position.rs | 33 | ||||
-rw-r--r-- | src/window/settings.rs | 14 |
15 files changed, 268 insertions, 144 deletions
diff --git a/src/application.rs b/src/application.rs index d46cd2ac..78280e98 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,5 +1,7 @@ use crate::window; -use crate::{Color, Command, Element, Executor, Settings, Subscription}; +use crate::{ + Clipboard, Color, Command, Element, Executor, Menu, Settings, Subscription, +}; /// An interactive cross-platform application. /// @@ -11,15 +13,13 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription}; /// document. /// /// An [`Application`] can execute asynchronous actions by returning a -/// [`Command`](struct.Command.html) in some of its methods. If -/// you do not intend to perform any background work in your program, the -/// [`Sandbox`](trait.Sandbox.html) trait offers a simplified interface. +/// [`Command`] in some of its methods. If you do not intend to perform any +/// background work in your program, the [`Sandbox`] trait offers a simplified +/// interface. /// /// When using an [`Application`] with the `debug` feature enabled, a debug view /// can be toggled by pressing `F12`. /// -/// [`Application`]: trait.Application.html -/// /// # Examples /// [The repository has a bunch of examples] that use the [`Application`] trait: /// @@ -29,6 +29,8 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription}; /// a dummy file of 100 MB and tracks the download progress. /// - [`events`], a log of native events displayed using a conditional /// [`Subscription`]. +/// - [`game_of_life`], an interactive version of the [Game of Life], invented +/// by [John Horton Conway]. /// - [`pokedex`], an application that displays a random Pokédex entry (sprite /// included!) by using the [PokéAPI]. /// - [`solar_system`], an animated solar system drawn using the [`Canvas`] widget @@ -37,17 +39,18 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription}; /// to listen to time. /// - [`todos`], a todos tracker inspired by [TodoMVC]. /// -/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.1/examples -/// [`clock`]: https://github.com/hecrj/iced/tree/0.1/examples/clock -/// [`download_progress`]: https://github.com/hecrj/iced/tree/0.1/examples/download_progress -/// [`events`]: https://github.com/hecrj/iced/tree/0.1/examples/events -/// [`pokedex`]: https://github.com/hecrj/iced/tree/0.1/examples/pokedex -/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.1/examples/solar_system -/// [`stopwatch`]: https://github.com/hecrj/iced/tree/0.1/examples/stopwatch -/// [`todos`]: https://github.com/hecrj/iced/tree/0.1/examples/todos -/// [`Canvas`]: widget/canvas/struct.Canvas.html +/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.3/examples +/// [`clock`]: https://github.com/hecrj/iced/tree/0.3/examples/clock +/// [`download_progress`]: https://github.com/hecrj/iced/tree/0.3/examples/download_progress +/// [`events`]: https://github.com/hecrj/iced/tree/0.3/examples/events +/// [`game_of_life`]: https://github.com/hecrj/iced/tree/0.3/examples/game_of_life +/// [`pokedex`]: https://github.com/hecrj/iced/tree/0.3/examples/pokedex +/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.3/examples/solar_system +/// [`stopwatch`]: https://github.com/hecrj/iced/tree/0.3/examples/stopwatch +/// [`todos`]: https://github.com/hecrj/iced/tree/0.3/examples/todos +/// [`Sandbox`]: crate::Sandbox +/// [`Canvas`]: crate::widget::Canvas /// [PokéAPI]: https://pokeapi.co/ -/// [`Subscription`]: type.Subscription.html /// [TodoMVC]: http://todomvc.com/ /// /// ## A simple "Hello, world!" @@ -56,7 +59,7 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription}; /// says "Hello, world!": /// /// ```no_run -/// use iced::{executor, Application, Command, Element, Settings, Text}; +/// use iced::{executor, Application, Clipboard, Command, Element, Settings, Text}; /// /// pub fn main() -> iced::Result { /// Hello::run(Settings::default()) @@ -65,7 +68,7 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription}; /// struct Hello; /// /// impl Application for Hello { -/// type Executor = executor::Null; +/// type Executor = executor::Default; /// type Message = (); /// type Flags = (); /// @@ -77,7 +80,7 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription}; /// String::from("A cool application") /// } /// -/// fn update(&mut self, _message: Self::Message) -> Command<Self::Message> { +/// fn update(&mut self, _message: Self::Message, _clipboard: &mut Clipboard) -> Command<Self::Message> { /// Command::none() /// } /// @@ -91,18 +94,14 @@ pub trait Application: Sized { /// /// The [default executor] can be a good starting point! /// - /// [`Executor`]: trait.Executor.html - /// [default executor]: executor/struct.Default.html + /// [`Executor`]: Self::Executor + /// [default executor]: crate::executor::Default type Executor: Executor; /// The type of __messages__ your [`Application`] will produce. - /// - /// [`Application`]: trait.Application.html - type Message: std::fmt::Debug + Send; + type Message: std::fmt::Debug + Clone + Send; /// The data needed to initialize your [`Application`]. - /// - /// [`Application`]: trait.Application.html type Flags; /// Initializes the [`Application`] with the flags provided to @@ -110,22 +109,17 @@ pub trait Application: Sized { /// /// Here is where you should return the initial state of your app. /// - /// Additionally, you can return a [`Command`](struct.Command.html) if you - /// need to perform some async action in the background on startup. This is - /// useful if you want to load state from a file, perform an initial HTTP - /// request, etc. + /// Additionally, you can return a [`Command`] if you need to perform some + /// async action in the background on startup. This is useful if you want to + /// load state from a file, perform an initial HTTP request, etc. /// - /// [`Application`]: trait.Application.html - /// [`run`]: #method.run.html - /// [`Settings`]: struct.Settings.html + /// [`run`]: Self::run fn new(flags: Self::Flags) -> (Self, Command<Self::Message>); /// Returns the current title of the [`Application`]. /// /// This title can be dynamic! The runtime will automatically update the /// title of your application when necessary. - /// - /// [`Application`]: trait.Application.html fn title(&self) -> String; /// Handles a __message__ and updates the state of the [`Application`]. @@ -135,10 +129,11 @@ pub trait Application: Sized { /// this method. /// /// Any [`Command`] returned will be executed immediately in the background. - /// - /// [`Application`]: trait.Application.html - /// [`Command`]: struct.Command.html - fn update(&mut self, message: Self::Message) -> Command<Self::Message>; + fn update( + &mut self, + message: Self::Message, + clipboard: &mut Clipboard, + ) -> Command<Self::Message>; /// Returns the event [`Subscription`] for the current state of the /// application. @@ -148,8 +143,6 @@ pub trait Application: Sized { /// [`update`](#tymethod.update). /// /// By default, this method returns an empty [`Subscription`]. - /// - /// [`Subscription`]: struct.Subscription.html fn subscription(&self) -> Subscription<Self::Message> { Subscription::none() } @@ -157,8 +150,6 @@ pub trait Application: Sized { /// Returns the widgets to display in the [`Application`]. /// /// These widgets can produce __messages__ based on user interaction. - /// - /// [`Application`]: trait.Application.html fn view(&mut self) -> Element<'_, Self::Message>; /// Returns the current [`Application`] mode. @@ -169,8 +160,6 @@ pub trait Application: Sized { /// 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 } @@ -178,9 +167,6 @@ pub trait Application: Sized { /// Returns the background color of the [`Application`]. /// /// By default, it returns [`Color::WHITE`]. - /// - /// [`Application`]: trait.Application.html - /// [`Color::WHITE`]: struct.Color.html#const.WHITE fn background_color(&self) -> Color { Color::WHITE } @@ -194,12 +180,24 @@ pub trait Application: Sized { /// while a scale factor of `0.5` will shrink them to half their size. /// /// By default, it returns `1.0`. - /// - /// [`Application`]: trait.Application.html fn scale_factor(&self) -> f64 { 1.0 } + /// Returns whether the [`Application`] should be terminated. + /// + /// By default, it returns `false`. + fn should_exit(&self) -> bool { + false + } + + /// Returns the current system [`Menu`] of the [`Application`]. + /// + /// By default, it returns an empty [`Menu`]. + fn menu(&self) -> Menu<Self::Message> { + Menu::new() + } + /// Runs the [`Application`]. /// /// On native platforms, this method will take control of the current thread @@ -207,8 +205,7 @@ pub trait Application: Sized { /// /// It should probably be that last thing you call in your `main` function. /// - /// [`Application`]: trait.Application.html - /// [`Error`]: enum.Error.html + /// [`Error`]: crate::Error fn run(settings: Settings<Self::Flags>) -> crate::Result where Self: 'static, @@ -218,12 +215,13 @@ pub trait Application: Sized { let renderer_settings = crate::renderer::Settings { default_font: settings.default_font, default_text_size: settings.default_text_size, + text_multithreading: settings.text_multithreading, antialiasing: if settings.antialiasing { Some(crate::renderer::settings::Antialiasing::MSAAx4) } else { None }, - ..crate::renderer::Settings::default() + ..crate::renderer::Settings::from_env() }; Ok(crate::runtime::application::run::< @@ -251,9 +249,14 @@ where { type Renderer = crate::renderer::Renderer; type Message = A::Message; - - fn update(&mut self, message: Self::Message) -> Command<Self::Message> { - self.0.update(message) + type Clipboard = iced_winit::Clipboard; + + fn update( + &mut self, + message: Self::Message, + clipboard: &mut iced_winit::Clipboard, + ) -> Command<Self::Message> { + self.0.update(message, clipboard) } fn view(&mut self) -> Element<'_, Self::Message> { @@ -282,6 +285,7 @@ where match self.0.mode() { window::Mode::Windowed => iced_winit::Mode::Windowed, window::Mode::Fullscreen => iced_winit::Mode::Fullscreen, + window::Mode::Hidden => iced_winit::Mode::Hidden, } } @@ -296,6 +300,14 @@ where fn scale_factor(&self) -> f64 { self.0.scale_factor() } + + fn should_exit(&self) -> bool { + self.0.should_exit() + } + + fn menu(&self) -> Menu<Self::Message> { + self.0.menu() + } } #[cfg(target_arch = "wasm32")] @@ -317,8 +329,12 @@ where self.0.title() } - fn update(&mut self, message: Self::Message) -> Command<Self::Message> { - self.0.update(message) + fn update( + &mut self, + message: Self::Message, + clipboard: &mut Clipboard, + ) -> Command<Self::Message> { + self.0.update(message, clipboard) } fn subscription(&self) -> Subscription<Self::Message> { diff --git a/src/error.rs b/src/error.rs index 31b87d17..c8fa6636 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,7 +9,7 @@ pub enum Error { /// The application window could not be created. #[error("the application window could not be created")] - WindowCreationFailed(Box<dyn std::error::Error>), + WindowCreationFailed(Box<dyn std::error::Error + Send + Sync>), /// A suitable graphics adapter or device could not be found. #[error("a suitable graphics adapter or device could not be found")] @@ -32,3 +32,14 @@ impl From<iced_winit::Error> for Error { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn assert_send_sync() { + fn _assert<T: Send + Sync>() {} + _assert::<Error>(); + } +} diff --git a/src/executor.rs b/src/executor.rs index 59d59a5a..9f3656b1 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -1,5 +1,5 @@ //! Choose your preferred executor to power your application. -pub use crate::runtime::{executor::Null, Executor}; +pub use crate::runtime::Executor; pub use platform::Default; @@ -7,13 +7,34 @@ pub use platform::Default; mod platform { use iced_futures::{executor, futures}; - #[cfg(feature = "tokio")] + #[cfg(feature = "tokio_old")] + type Executor = executor::TokioOld; + + #[cfg(all(feature = "tokio", not(feature = "tokio_old")))] type Executor = executor::Tokio; - #[cfg(all(not(feature = "tokio"), feature = "async-std"))] + #[cfg(all( + feature = "async-std", + not(any(feature = "tokio_old", feature = "tokio")), + ))] type Executor = executor::AsyncStd; - #[cfg(not(any(feature = "tokio", feature = "async-std")))] + #[cfg(all( + feature = "smol", + not(any( + feature = "tokio_old", + feature = "tokio", + feature = "async-std" + )), + ))] + type Executor = executor::Smol; + + #[cfg(not(any( + feature = "tokio_old", + feature = "tokio", + feature = "async-std", + feature = "smol", + )))] type Executor = executor::ThreadPool; /// A default cross-platform executor. @@ -40,7 +61,7 @@ mod platform { } fn enter<R>(&self, f: impl FnOnce() -> R) -> R { - self.0.enter(f) + super::Executor::enter(&self.0, f) } } } diff --git a/src/keyboard.rs b/src/keyboard.rs index 0b3e894d..2134a66b 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -1,2 +1,2 @@ //! Listen and react to keyboard events. -pub use crate::runtime::keyboard::{Event, KeyCode, ModifiersState}; +pub use crate::runtime::keyboard::{Event, KeyCode, Modifiers}; @@ -30,7 +30,7 @@ //! [windowing shell]: https://github.com/hecrj/iced/tree/master/winit //! [`dodrio`]: https://github.com/fitzgen/dodrio //! [web runtime]: https://github.com/hecrj/iced/tree/master/web -//! [examples]: https://github.com/hecrj/iced/tree/0.1/examples +//! [examples]: https://github.com/hecrj/iced/tree/0.3/examples //! [repository]: https://github.com/hecrj/iced //! //! # Overview @@ -171,8 +171,6 @@ //! //! [Elm]: https://elm-lang.org/ //! [The Elm Architecture]: https://guide.elm-lang.org/architecture/ -//! [`Application`]: trait.Application.html -//! [`Sandbox`]: trait.Sandbox.html #![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] @@ -193,10 +191,23 @@ pub mod widget; pub mod window; #[cfg(all( - any(feature = "tokio", feature = "async-std"), + any( + feature = "tokio", + feature = "tokio_old", + feature = "async-std", + feature = "smol" + ), not(target_arch = "wasm32") ))] -#[cfg_attr(docsrs, doc(cfg(any(feature = "tokio", feature = "async-std"))))] +#[cfg_attr( + docsrs, + doc(cfg(any( + feature = "tokio", + feature = "tokio_old", + feature = "async-std" + feature = "smol" + ))) +)] pub mod time; #[cfg(all( @@ -234,6 +245,7 @@ pub use sandbox::Sandbox; pub use settings::Settings; pub use runtime::{ - futures, Align, Background, Color, Command, Font, HorizontalAlignment, - Length, Point, Rectangle, Size, Subscription, Vector, VerticalAlignment, + futures, menu, Align, Background, Clipboard, Color, Command, Font, + HorizontalAlignment, Length, Menu, Point, Rectangle, Size, Subscription, + Vector, VerticalAlignment, }; diff --git a/src/result.rs b/src/result.rs index 2f05a6a9..ef565bd6 100644 --- a/src/result.rs +++ b/src/result.rs @@ -2,5 +2,5 @@ use crate::Error; /// The result of running an [`Application`]. /// -/// [`Application`]: trait.Application.html +/// [`Application`]: crate::Application pub type Result = std::result::Result<(), Error>; diff --git a/src/sandbox.rs b/src/sandbox.rs index c72b58d8..cb3cf624 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -1,6 +1,6 @@ -use crate::executor; use crate::{ - Application, Color, Command, Element, Error, Settings, Subscription, + Application, Clipboard, Color, Command, Element, Error, Settings, + Subscription, }; /// A sandboxed [`Application`]. @@ -15,16 +15,11 @@ use crate::{ /// Therefore, it is recommended to always start by implementing this trait and /// upgrade only once necessary. /// -/// [`Application`]: trait.Application.html -/// [`Sandbox`]: trait.Sandbox.html -/// [`Command`]: struct.Command.html -/// [`Command::none`]: struct.Command.html#method.none -/// /// # Examples /// [The repository has a bunch of examples] that use the [`Sandbox`] trait: /// -/// - [`bezier_tool`], a Paint-like tool for drawing Bézier curves using -/// [`lyon`]. +/// - [`bezier_tool`], a Paint-like tool for drawing Bézier curves using the +/// [`Canvas widget`]. /// - [`counter`], the classic counter example explained in [the overview]. /// - [`custom_widget`], a demonstration of how to build a custom widget that /// draws a circle. @@ -41,20 +36,20 @@ use crate::{ /// - [`tour`], a simple UI tour that can run both on native platforms and the /// web! /// -/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.1/examples -/// [`bezier_tool`]: https://github.com/hecrj/iced/tree/0.1/examples/bezier_tool -/// [`counter`]: https://github.com/hecrj/iced/tree/0.1/examples/counter -/// [`custom_widget`]: https://github.com/hecrj/iced/tree/0.1/examples/custom_widget -/// [`geometry`]: https://github.com/hecrj/iced/tree/0.1/examples/geometry -/// [`pane_grid`]: https://github.com/hecrj/iced/tree/0.1/examples/pane_grid -/// [`progress_bar`]: https://github.com/hecrj/iced/tree/0.1/examples/progress_bar -/// [`styling`]: https://github.com/hecrj/iced/tree/0.1/examples/styling -/// [`svg`]: https://github.com/hecrj/iced/tree/0.1/examples/svg -/// [`tour`]: https://github.com/hecrj/iced/tree/0.1/examples/tour -/// [`lyon`]: https://github.com/nical/lyon +/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.3/examples +/// [`bezier_tool`]: https://github.com/hecrj/iced/tree/0.3/examples/bezier_tool +/// [`counter`]: https://github.com/hecrj/iced/tree/0.3/examples/counter +/// [`custom_widget`]: https://github.com/hecrj/iced/tree/0.3/examples/custom_widget +/// [`geometry`]: https://github.com/hecrj/iced/tree/0.3/examples/geometry +/// [`pane_grid`]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid +/// [`progress_bar`]: https://github.com/hecrj/iced/tree/0.3/examples/progress_bar +/// [`styling`]: https://github.com/hecrj/iced/tree/0.3/examples/styling +/// [`svg`]: https://github.com/hecrj/iced/tree/0.3/examples/svg +/// [`tour`]: https://github.com/hecrj/iced/tree/0.3/examples/tour +/// [`Canvas widget`]: crate::widget::Canvas /// [the overview]: index.html#overview -/// [`iced_wgpu`]: https://github.com/hecrj/iced/tree/0.1/wgpu -/// [`Svg` widget]: widget/svg/struct.Svg.html +/// [`iced_wgpu`]: https://github.com/hecrj/iced/tree/0.3/wgpu +/// [`Svg` widget]: crate::widget::Svg /// [Ghostscript Tiger]: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg /// /// ## A simple "Hello, world!" @@ -93,46 +88,33 @@ use crate::{ /// ``` pub trait Sandbox { /// The type of __messages__ your [`Sandbox`] will produce. - /// - /// [`Sandbox`]: trait.Sandbox.html - type Message: std::fmt::Debug + Send; + type Message: std::fmt::Debug + Clone + Send; /// Initializes the [`Sandbox`]. /// /// Here is where you should return the initial state of your app. - /// - /// [`Sandbox`]: trait.Sandbox.html fn new() -> Self; /// Returns the current title of the [`Sandbox`]. /// /// This title can be dynamic! The runtime will automatically update the /// title of your application when necessary. - /// - /// [`Sandbox`]: trait.Sandbox.html fn title(&self) -> String; /// Handles a __message__ and updates the state of the [`Sandbox`]. /// /// This is where you define your __update logic__. All the __messages__, /// produced by user interactions, will be handled by this method. - /// - /// [`Sandbox`]: trait.Sandbox.html fn update(&mut self, message: Self::Message); /// Returns the widgets to display in the [`Sandbox`]. /// /// These widgets can produce __messages__ based on user interaction. - /// - /// [`Sandbox`]: trait.Sandbox.html fn view(&mut self) -> Element<'_, Self::Message>; /// Returns the background color of the [`Sandbox`]. /// /// By default, it returns [`Color::WHITE`]. - /// - /// [`Sandbox`]: trait.Sandbox.html - /// [`Color::WHITE`]: struct.Color.html#const.WHITE fn background_color(&self) -> Color { Color::WHITE } @@ -146,8 +128,6 @@ pub trait Sandbox { /// while a scale factor of `0.5` will shrink them to half their size. /// /// By default, it returns `1.0`. - /// - /// [`Sandbox`]: trait.Sandbox.html fn scale_factor(&self) -> f64 { 1.0 } @@ -158,8 +138,6 @@ pub trait Sandbox { /// and __will NOT return__. /// /// It should probably be that last thing you call in your `main` function. - /// - /// [`Sandbox`]: trait.Sandbox.html fn run(settings: Settings<()>) -> Result<(), Error> where Self: 'static + Sized, @@ -172,7 +150,7 @@ impl<T> Application for T where T: Sandbox, { - type Executor = executor::Null; + type Executor = crate::runtime::executor::Null; type Flags = (); type Message = T::Message; @@ -184,7 +162,11 @@ where T::title(self) } - fn update(&mut self, message: T::Message) -> Command<T::Message> { + fn update( + &mut self, + message: T::Message, + _clipboard: &mut Clipboard, + ) -> Command<T::Message> { T::update(self, message); Command::none() diff --git a/src/settings.rs b/src/settings.rs index 40b1b1ea..d726dc4f 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -4,16 +4,20 @@ use crate::window; /// The settings of an application. #[derive(Debug, Clone)] pub struct Settings<Flags> { + /// The identifier of the application. + /// + /// If provided, this identifier may be used to identify the application or + /// communicate with it through the windowing system. + pub id: Option<String>, + /// The window settings. /// /// They will be ignored on the Web. - /// - /// [`Window`]: struct.Window.html pub window: window::Settings, - /// The data needed to initialize an [`Application`]. + /// The data needed to initialize the [`Application`]. /// - /// [`Application`]: ../trait.Application.html + /// [`Application`]: crate::Application pub flags: Flags, /// The bytes of the font that will be used by default. @@ -27,6 +31,12 @@ pub struct Settings<Flags> { /// The default value is 20. pub default_text_size: u16, + /// If enabled, spread text workload in multiple threads when multiple cores + /// are available. + /// + /// By default, it is disabled. + pub text_multithreading: bool, + /// If set to true, the renderer will try to perform antialiasing for some /// primitives. /// @@ -35,23 +45,32 @@ pub struct Settings<Flags> { /// /// By default, it is disabled. /// - /// [`Canvas`]: ../widget/canvas/struct.Canvas.html + /// [`Canvas`]: crate::widget::Canvas pub antialiasing: bool, + + /// Whether the [`Application`] should exit when the user requests the + /// window to close (e.g. the user presses the close button). + /// + /// By default, it is enabled. + pub exit_on_close_request: bool, } impl<Flags> Settings<Flags> { - /// Initialize application settings using the given data. + /// Initialize [`Application`] settings using the given data. /// - /// [`Application`]: ../trait.Application.html + /// [`Application`]: crate::Application pub fn with_flags(flags: Flags) -> Self { let default_settings = Settings::<()>::default(); Self { flags, - antialiasing: default_settings.antialiasing, + id: default_settings.id, + window: default_settings.window, default_font: default_settings.default_font, default_text_size: default_settings.default_text_size, - window: default_settings.window, + text_multithreading: default_settings.text_multithreading, + antialiasing: default_settings.antialiasing, + exit_on_close_request: default_settings.exit_on_close_request, } } } @@ -62,11 +81,14 @@ where { fn default() -> Self { Self { + id: None, + window: Default::default(), flags: Default::default(), - antialiasing: Default::default(), default_font: Default::default(), default_text_size: 20, - window: Default::default(), + text_multithreading: false, + antialiasing: false, + exit_on_close_request: true, } } } @@ -75,8 +97,10 @@ where impl<Flags> From<Settings<Flags>> for iced_winit::Settings<Flags> { fn from(settings: Settings<Flags>) -> iced_winit::Settings<Flags> { iced_winit::Settings { + id: settings.id, window: settings.window.into(), flags: settings.flags, + exit_on_close_request: settings.exit_on_close_request, } } } diff --git a/src/time.rs b/src/time.rs index cd442461..b8432895 100644 --- a/src/time.rs +++ b/src/time.rs @@ -5,8 +5,6 @@ use crate::Subscription; /// /// The first message is produced after a `duration`, and then continues to /// produce more messages every `duration` after that. -/// -/// [`Subscription`]: ../subscription/struct.Subscription.html pub fn every( duration: std::time::Duration, ) -> Subscription<std::time::Instant> { diff --git a/src/widget.rs b/src/widget.rs index e8fff9cc..db052106 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -13,14 +13,12 @@ //! //! 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 crate::renderer::widget::{ button, checkbox, container, pane_grid, pick_list, progress_bar, radio, - rule, scrollable, slider, text_input, Column, Row, Space, Text, + rule, scrollable, slider, text_input, toggler, tooltip, Column, Row, + Space, Text, }; #[cfg(any(feature = "canvas", feature = "glow_canvas"))] @@ -30,10 +28,18 @@ mod platform { )] pub use crate::renderer::widget::canvas; + #[cfg(any(feature = "qr_code", feature = "glow_qr_code"))] + #[cfg_attr( + docsrs, + doc(cfg(any(feature = "qr_code", feature = "glow_qr_code"))) + )] + pub use crate::renderer::widget::qr_code; + #[cfg_attr(docsrs, doc(cfg(feature = "image")))] pub mod image { //! Display images in your user interface. - pub use crate::runtime::image::{Handle, Image}; + pub use crate::runtime::image::viewer; + pub use crate::runtime::image::{Handle, Image, Viewer}; } #[cfg_attr(docsrs, doc(cfg(feature = "svg")))] @@ -47,12 +53,16 @@ mod platform { button::Button, checkbox::Checkbox, container::Container, image::Image, pane_grid::PaneGrid, pick_list::PickList, progress_bar::ProgressBar, radio::Radio, rule::Rule, scrollable::Scrollable, slider::Slider, - svg::Svg, text_input::TextInput, + svg::Svg, text_input::TextInput, toggler::Toggler, tooltip::Tooltip, }; #[cfg(any(feature = "canvas", feature = "glow_canvas"))] #[doc(no_inline)] pub use canvas::Canvas; + + #[cfg(any(feature = "qr_code", feature = "glow_qr_code"))] + #[doc(no_inline)] + pub use qr_code::QRCode; } #[cfg(target_arch = "wasm32")] diff --git a/src/window.rs b/src/window.rs index a2883b62..7d441062 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,9 +1,11 @@ //! Configure the window of your application in native platforms. mod mode; +mod position; mod settings; pub mod icon; pub use icon::Icon; pub use mode::Mode; +pub use position::Position; pub use settings::Settings; diff --git a/src/window/icon.rs b/src/window/icon.rs index 15e0312d..287538b1 100644 --- a/src/window/icon.rs +++ b/src/window/icon.rs @@ -97,23 +97,25 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::InvalidData { byte_count } => { - write!(f, - "The provided RGBA data (with length {:?}) isn't divisble by \ + write!( + f, + "The provided RGBA data (with length {:?}) isn't divisble by \ 4. Therefore, it cannot be safely interpreted as 32bpp RGBA \ pixels.", - byte_count, - ) + byte_count, + ) } Error::DimensionsMismatch { width, height, pixel_count, } => { - write!(f, - "The number of RGBA pixels ({:?}) does not match the provided \ + write!( + f, + "The number of RGBA pixels ({:?}) does not match the provided \ dimensions ({:?}x{:?}).", - width, height, pixel_count, - ) + pixel_count, width, height, + ) } Error::OsError(e) => write!( f, diff --git a/src/window/mode.rs b/src/window/mode.rs index 37464711..fdce8e23 100644 --- a/src/window/mode.rs +++ b/src/window/mode.rs @@ -6,4 +6,7 @@ pub enum Mode { /// The application takes the whole screen of its current monitor. Fullscreen, + + /// The application is hidden + Hidden, } diff --git a/src/window/position.rs b/src/window/position.rs new file mode 100644 index 00000000..8535ef6a --- /dev/null +++ b/src/window/position.rs @@ -0,0 +1,33 @@ +/// The position of a window in a given screen. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Position { + /// The platform-specific default position for a new window. + Default, + /// The window is completely centered on the screen. + Centered, + /// The window is positioned with specific coordinates: `(X, Y)`. + /// + /// When the decorations of the window are enabled, Windows 10 will add some + /// invisible padding to the window. This padding gets included in the + /// position. So if you have decorations enabled and want the window to be + /// at (0, 0) you would have to set the position to + /// `(PADDING_X, PADDING_Y)`. + Specific(i32, i32), +} + +impl Default for Position { + fn default() -> Self { + Self::Default + } +} + +#[cfg(not(target_arch = "wasm32"))] +impl From<Position> for iced_winit::Position { + fn from(position: Position) -> Self { + match position { + Position::Default => Self::Default, + Position::Centered => Self::Centered, + Position::Specific(x, y) => Self::Specific(x, y), + } + } +} diff --git a/src/window/settings.rs b/src/window/settings.rs index 7bc49ce1..ec6c3071 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -1,4 +1,4 @@ -use crate::window::Icon; +use crate::window::{Icon, Position}; /// The window settings of an application. #[derive(Debug, Clone)] @@ -6,6 +6,9 @@ pub struct Settings { /// The initial size of the window. pub size: (u32, u32), + /// The initial position of the window. + pub position: Position, + /// The minimum size of the window. pub min_size: Option<(u32, u32)>, @@ -18,9 +21,12 @@ pub struct Settings { /// Whether the window should have a border, a title bar, etc. or not. pub decorations: bool, - /// Whether the window should be transparent + /// Whether the window should be transparent. pub transparent: bool, + /// Whether the window will always be on top of other windows. + pub always_on_top: bool, + /// The icon of the window. pub icon: Option<Icon>, } @@ -29,11 +35,13 @@ impl Default for Settings { fn default() -> Settings { Settings { size: (1024, 768), + position: Position::default(), min_size: None, max_size: None, resizable: true, decorations: true, transparent: false, + always_on_top: false, icon: None, } } @@ -44,11 +52,13 @@ impl From<Settings> for iced_winit::settings::Window { fn from(settings: Settings) -> Self { Self { size: settings.size, + position: iced_winit::Position::from(settings.position), min_size: settings.min_size, max_size: settings.max_size, resizable: settings.resizable, decorations: settings.decorations, transparent: settings.transparent, + always_on_top: settings.always_on_top, icon: settings.icon.map(Icon::into), platform_specific: Default::default(), } |