summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Richard <richardsoncusto@gmail.com>2022-04-01 17:16:15 -0300
committerLibravatar bungoboingo <shankern@protonmail.com>2023-01-09 11:27:03 -0800
commit529589d7fe9278858e3f251b559a1118598a8250 (patch)
treec82aedce4bace32865d67e4c9ce4057af6d16d21 /src
parent7ccd87c36b54e0d53f65f5774f140a0528ae4504 (diff)
downloadiced-529589d7fe9278858e3f251b559a1118598a8250.tar.gz
iced-529589d7fe9278858e3f251b559a1118598a8250.tar.bz2
iced-529589d7fe9278858e3f251b559a1118598a8250.zip
Introduce `multi_window` from `pure`
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs3
-rw-r--r--src/multi_window.rs4
-rw-r--r--src/multi_window/application.rs196
3 files changed, 203 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index a0e31be4..6cda8c41 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -181,6 +181,9 @@ pub mod touch;
pub mod widget;
pub mod window;
+#[cfg(feature = "multi_window")]
+pub mod multi_window;
+
#[cfg(all(not(feature = "glow"), feature = "wgpu"))]
use iced_winit as runtime;
diff --git a/src/multi_window.rs b/src/multi_window.rs
new file mode 100644
index 00000000..5b7a00b4
--- /dev/null
+++ b/src/multi_window.rs
@@ -0,0 +1,4 @@
+//! Leverage multi-window support in your application.
+mod application;
+
+pub use application::Application;
diff --git a/src/multi_window/application.rs b/src/multi_window/application.rs
new file mode 100644
index 00000000..db41d54a
--- /dev/null
+++ b/src/multi_window/application.rs
@@ -0,0 +1,196 @@
+use crate::{Command, Element, Executor, Settings, Subscription};
+
+pub use iced_native::application::{Appearance, StyleSheet};
+
+/// A pure version of [`Application`].
+///
+/// Unlike the impure version, the `view` method of this trait takes an
+/// immutable reference to `self` and returns a pure [`Element`].
+///
+/// [`Application`]: crate::Application
+/// [`Element`]: pure::Element
+pub trait Application: Sized {
+ /// The [`Executor`] that will run commands and subscriptions.
+ ///
+ /// The [default executor] can be a good starting point!
+ ///
+ /// [`Executor`]: Self::Executor
+ /// [default executor]: crate::executor::Default
+ type Executor: Executor;
+
+ /// The type of __messages__ your [`Application`] will produce.
+ type Message: std::fmt::Debug + Send;
+
+ /// The theme of your [`Application`].
+ type Theme: Default + StyleSheet;
+
+ /// The data needed to initialize your [`Application`].
+ type Flags;
+
+ /// Initializes the [`Application`] with the flags provided to
+ /// [`run`] as part of the [`Settings`].
+ ///
+ /// Here is where you should return the initial state of your app.
+ ///
+ /// 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.
+ ///
+ /// [`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.
+ fn title(&self) -> String;
+
+ /// Handles a __message__ and updates the state of the [`Application`].
+ ///
+ /// This is where you define your __update logic__. All the __messages__,
+ /// produced by either user interactions or commands, will be handled by
+ /// this method.
+ ///
+ /// Any [`Command`] returned will be executed immediately in the background.
+ fn update(&mut self, message: Self::Message) -> Command<Self::Message>;
+
+ /// Returns the current [`Theme`] of the [`Application`].
+ ///
+ /// [`Theme`]: Self::Theme
+ fn theme(&self) -> Self::Theme {
+ Self::Theme::default()
+ }
+
+ /// Returns the current [`Style`] of the [`Theme`].
+ ///
+ /// [`Style`]: <Self::Theme as StyleSheet>::Style
+ /// [`Theme`]: Self::Theme
+ fn style(&self) -> <Self::Theme as StyleSheet>::Style {
+ <Self::Theme as StyleSheet>::Style::default()
+ }
+
+ /// 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`].
+ 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.
+ fn view(&self) -> Element<'_, Self::Message, crate::Renderer<Self::Theme>>;
+
+ /// Returns the scale factor of the [`Application`].
+ ///
+ /// It can be used to dynamically control the size of the UI at runtime
+ /// (i.e. zooming).
+ ///
+ /// For instance, a scale factor of `2.0` will make widgets twice as big,
+ /// while a scale factor of `0.5` will shrink them to half their size.
+ ///
+ /// By default, it returns `1.0`.
+ 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
+ }
+
+ /// Runs the [`Application`].
+ ///
+ /// On native platforms, this method will take control of the current thread
+ /// until the [`Application`] exits.
+ ///
+ /// On the web platform, this method __will NOT return__ unless there is an
+ /// [`Error`] during startup.
+ ///
+ /// [`Error`]: crate::Error
+ fn run(settings: Settings<Self::Flags>) -> crate::Result
+ where
+ Self: 'static,
+ {
+ #[allow(clippy::needless_update)]
+ 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::from_env()
+ };
+
+ Ok(crate::runtime::application::run::<
+ Instance<Self>,
+ Self::Executor,
+ crate::renderer::window::Compositor<Self::Theme>,
+ >(settings.into(), renderer_settings)?)
+ }
+}
+
+struct Instance<A: Application>(A);
+
+impl<A> iced_winit::Program for Instance<A>
+where
+ A: Application,
+{
+ type Renderer = crate::Renderer<A::Theme>;
+ type Message = A::Message;
+
+ fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
+ self.0.update(message)
+ }
+
+ fn view(&self) -> Element<'_, Self::Message, Self::Renderer> {
+ self.0.view()
+ }
+}
+
+impl<A> crate::runtime::Application for Instance<A>
+where
+ A: Application,
+{
+ type Flags = A::Flags;
+
+ fn new(flags: Self::Flags) -> (Self, Command<A::Message>) {
+ let (app, command) = A::new(flags);
+
+ (Instance(app), command)
+ }
+
+ fn title(&self) -> String {
+ self.0.title()
+ }
+
+ fn theme(&self) -> A::Theme {
+ self.0.theme()
+ }
+
+ fn style(&self) -> <A::Theme as StyleSheet>::Style {
+ self.0.style()
+ }
+
+ fn subscription(&self) -> Subscription<Self::Message> {
+ self.0.subscription()
+ }
+
+ fn scale_factor(&self) -> f64 {
+ self.0.scale_factor()
+ }
+
+ fn should_exit(&self) -> bool {
+ self.0.should_exit()
+ }
+}