From 76698ff2b5753e637b14533650c0d28e681be3c5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 1 Sep 2021 19:21:49 +0700 Subject: Make `Command` implementations platform-specific This allows us to introduce a platform-specific `Action` to both `iced_native` and `iced_web` and remove the `Clipboard` from `Application::update` to maintain purity. Additionally, this should let us implement further actions to let users query and modify the shell environment (e.g. window, clipboard, and more!) --- winit/src/application.rs | 28 ++++++++++++++++++++++------ winit/src/window.rs | 7 +++++++ 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 winit/src/window.rs (limited to 'winit') diff --git a/winit/src/application.rs b/winit/src/application.rs index b683e592..99118ad1 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -30,7 +30,7 @@ use std::mem::ManuallyDrop; /// /// When using an [`Application`] with the `debug` feature enabled, a debug view /// can be toggled by pressing `F12`. -pub trait Application: Program { +pub trait Application: Program { /// The data needed to initialize your [`Application`]. type Flags; @@ -143,7 +143,7 @@ where let subscription = application.subscription(); - runtime.spawn(init_command); + run_command(init_command, &mut runtime); runtime.track(subscription); let window = settings @@ -290,7 +290,6 @@ async fn run_instance( &mut application, &mut runtime, &mut debug, - &mut clipboard, &mut messages, ); @@ -492,19 +491,36 @@ pub fn update( application: &mut A, runtime: &mut Runtime, A::Message>, debug: &mut Debug, - clipboard: &mut A::Clipboard, messages: &mut Vec, ) { for message in messages.drain(..) { debug.log_message(&message); debug.update_started(); - let command = runtime.enter(|| application.update(message, clipboard)); + let command = runtime.enter(|| application.update(message)); debug.update_finished(); - runtime.spawn(command); + run_command(command, runtime); } let subscription = application.subscription(); runtime.track(subscription); } + +/// Runs the actions of a [`Command`]. +pub fn run_command( + command: Command, + runtime: &mut Runtime, Message>, +) { + use iced_native::command; + + for action in command.actions() { + match action { + command::Action::Future(future) => { + runtime.spawn(future); + } + command::Action::Clipboard(_action) => unimplemented! {}, + command::Action::Window(_action) => unimplemented! {}, + } + } +} diff --git a/winit/src/window.rs b/winit/src/window.rs new file mode 100644 index 00000000..8ccb13ed --- /dev/null +++ b/winit/src/window.rs @@ -0,0 +1,7 @@ +pub use iced_native::window::*; + +/// The window of an [`Application`]. +/// +/// [`Application`]: crate::Application +#[derive(Debug)] +pub struct Window {} -- cgit From c9711ff48fa1ad16365bc7eb37fa7153143bcee6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 2 Sep 2021 13:46:01 +0700 Subject: Handle `clipboard::Action` in `iced_winit` shell --- winit/src/application.rs | 42 +++++++++++++++++++++++++++++++++--------- winit/src/clipboard.rs | 3 +++ winit/src/lib.rs | 2 +- 3 files changed, 37 insertions(+), 10 deletions(-) (limited to 'winit') diff --git a/winit/src/application.rs b/winit/src/application.rs index 99118ad1..f97f9bf1 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -3,11 +3,12 @@ mod state; pub use state::State; +use crate::clipboard::{self, Clipboard}; use crate::conversion; use crate::mouse; use crate::{ - Clipboard, Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime, - Settings, Size, Subscription, + Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings, + Size, Subscription, }; use iced_futures::futures; @@ -127,6 +128,7 @@ where debug.startup_started(); let event_loop = EventLoop::with_user_event(); + let mut proxy = event_loop.create_proxy(); let mut runtime = { let proxy = Proxy::new(event_loop.create_proxy()); @@ -143,9 +145,6 @@ where let subscription = application.subscription(); - run_command(init_command, &mut runtime); - runtime.track(subscription); - let window = settings .window .into_builder( @@ -158,6 +157,11 @@ where .build(&event_loop) .map_err(Error::WindowCreationFailed)?; + let mut clipboard = Clipboard::connect(&window); + + run_command(init_command, &mut runtime, &mut clipboard, &mut proxy); + runtime.track(subscription); + let (compositor, renderer) = C::new(compositor_settings, Some(&window))?; let (mut sender, receiver) = mpsc::unbounded(); @@ -167,6 +171,8 @@ where compositor, renderer, runtime, + clipboard, + proxy, debug, receiver, window, @@ -215,6 +221,8 @@ async fn run_instance( mut compositor: C, mut renderer: A::Renderer, mut runtime: Runtime, A::Message>, + mut clipboard: Clipboard, + mut proxy: winit::event_loop::EventLoopProxy, mut debug: Debug, mut receiver: mpsc::UnboundedReceiver>, window: winit::window::Window, @@ -228,7 +236,6 @@ async fn run_instance( use winit::event; let mut surface = compositor.create_surface(&window); - let mut clipboard = Clipboard::connect(&window); let mut state = State::new(&application, &window); let mut viewport_version = state.viewport_version(); @@ -289,6 +296,8 @@ async fn run_instance( update( &mut application, &mut runtime, + &mut clipboard, + &mut proxy, &mut debug, &mut messages, ); @@ -490,6 +499,8 @@ pub fn build_user_interface<'a, A: Application>( pub fn update( application: &mut A, runtime: &mut Runtime, A::Message>, + clipboard: &mut Clipboard, + proxy: &mut winit::event_loop::EventLoopProxy, debug: &mut Debug, messages: &mut Vec, ) { @@ -500,7 +511,7 @@ pub fn update( let command = runtime.enter(|| application.update(message)); debug.update_finished(); - run_command(command, runtime); + run_command(command, runtime, clipboard, proxy); } let subscription = application.subscription(); @@ -508,9 +519,11 @@ pub fn update( } /// Runs the actions of a [`Command`]. -pub fn run_command( +pub fn run_command( command: Command, runtime: &mut Runtime, Message>, + clipboard: &mut Clipboard, + proxy: &mut winit::event_loop::EventLoopProxy, ) { use iced_native::command; @@ -519,7 +532,18 @@ pub fn run_command( command::Action::Future(future) => { runtime.spawn(future); } - command::Action::Clipboard(_action) => unimplemented! {}, + command::Action::Clipboard(action) => match action { + clipboard::Action::Read(tag) => { + let message = tag(clipboard.read()); + + proxy + .send_event(message) + .expect("Send message to event loop"); + } + clipboard::Action::Write(contents) => { + clipboard.write(contents); + } + }, command::Action::Window(_action) => unimplemented! {}, } } diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index ca25c065..9d0663fa 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -1,3 +1,6 @@ +//! Access the clipboard. +pub use iced_native::clipboard::Action; + /// A buffer for short-term storage and transfer within and between /// applications. #[allow(missing_debug_implementations)] diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 1707846a..12df9d8e 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -25,10 +25,10 @@ pub use iced_native::*; pub use winit; pub mod application; +pub mod clipboard; pub mod conversion; pub mod settings; -mod clipboard; mod error; mod mode; mod position; -- cgit From 7a335a0408b3ee426949a1936255666bc3383ea9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 2 Sep 2021 15:12:55 +0700 Subject: Implement and expose `read` and `write` helpers for `clipboard` --- winit/src/clipboard.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'winit') diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 9d0663fa..05d991ff 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -1,6 +1,8 @@ //! Access the clipboard. pub use iced_native::clipboard::Action; +use crate::command::{self, Command}; + /// A buffer for short-term storage and transfer within and between /// applications. #[allow(missing_debug_implementations)] @@ -55,3 +57,15 @@ impl iced_native::Clipboard for Clipboard { self.write(contents) } } + +/// Read the current contents of the clipboard. +pub fn read( + f: impl Fn(Option) -> Message + 'static, +) -> Command { + Command::Single(command::Action::Clipboard(Action::Read(Box::new(f)))) +} + +/// Write the given contents to the clipboard. +pub fn write(contents: String) -> Command { + Command::Single(command::Action::Clipboard(Action::Write(contents))) +} -- cgit From 6fce35393fb2dc3dcbc5f423fa8472f5ce1f7027 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 2 Sep 2021 15:50:00 +0700 Subject: Hide implementation details of `Command` in `iced_futures` --- winit/src/clipboard.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'winit') diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 05d991ff..1b92b28d 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -62,10 +62,10 @@ impl iced_native::Clipboard for Clipboard { pub fn read( f: impl Fn(Option) -> Message + 'static, ) -> Command { - Command::Single(command::Action::Clipboard(Action::Read(Box::new(f)))) + Command::single(command::Action::Clipboard(Action::Read(Box::new(f)))) } /// Write the given contents to the clipboard. pub fn write(contents: String) -> Command { - Command::Single(command::Action::Clipboard(Action::Write(contents))) + Command::single(command::Action::Clipboard(Action::Write(contents))) } -- cgit From 7cb6e7438f7fb5d0d8be4528a31b888e2b12cd51 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 2 Sep 2021 16:30:14 +0700 Subject: Implement `move_to` and `resize` commands for `window` --- winit/src/application.rs | 29 ++++++++++++++++++++++++++--- winit/src/lib.rs | 1 + winit/src/window.rs | 23 +++++++++++++++++------ 3 files changed, 44 insertions(+), 9 deletions(-) (limited to 'winit') diff --git a/winit/src/application.rs b/winit/src/application.rs index f97f9bf1..722b4757 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -159,7 +159,13 @@ where let mut clipboard = Clipboard::connect(&window); - run_command(init_command, &mut runtime, &mut clipboard, &mut proxy); + run_command( + init_command, + &mut runtime, + &mut clipboard, + &mut proxy, + &window, + ); runtime.track(subscription); let (compositor, renderer) = C::new(compositor_settings, Some(&window))?; @@ -300,6 +306,7 @@ async fn run_instance( &mut proxy, &mut debug, &mut messages, + &window, ); // Update window @@ -503,6 +510,7 @@ pub fn update( proxy: &mut winit::event_loop::EventLoopProxy, debug: &mut Debug, messages: &mut Vec, + window: &winit::window::Window, ) { for message in messages.drain(..) { debug.log_message(&message); @@ -511,7 +519,7 @@ pub fn update( let command = runtime.enter(|| application.update(message)); debug.update_finished(); - run_command(command, runtime, clipboard, proxy); + run_command(command, runtime, clipboard, proxy, window); } let subscription = application.subscription(); @@ -524,8 +532,10 @@ pub fn run_command( runtime: &mut Runtime, Message>, clipboard: &mut Clipboard, proxy: &mut winit::event_loop::EventLoopProxy, + window: &winit::window::Window, ) { use iced_native::command; + use iced_native::window; for action in command.actions() { match action { @@ -544,7 +554,20 @@ pub fn run_command( clipboard.write(contents); } }, - command::Action::Window(_action) => unimplemented! {}, + command::Action::Window(action) => match action { + window::Action::Resize { width, height } => { + window.set_inner_size(winit::dpi::LogicalSize { + width, + height, + }); + } + window::Action::Move { x, y } => { + window.set_outer_position(winit::dpi::LogicalPosition { + x, + y, + }); + } + }, } } } diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 12df9d8e..30813152 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -28,6 +28,7 @@ pub mod application; pub mod clipboard; pub mod conversion; pub mod settings; +pub mod window; mod error; mod mode; diff --git a/winit/src/window.rs b/winit/src/window.rs index 8ccb13ed..f3207e68 100644 --- a/winit/src/window.rs +++ b/winit/src/window.rs @@ -1,7 +1,18 @@ -pub use iced_native::window::*; +//! Interact with the window of your application. +use crate::command::{self, Command}; +use iced_native::window; -/// The window of an [`Application`]. -/// -/// [`Application`]: crate::Application -#[derive(Debug)] -pub struct Window {} +pub use window::Event; + +/// Resizes the window to the given logical dimensions. +pub fn resize(width: u32, height: u32) -> Command { + Command::single(command::Action::Window(window::Action::Resize { + width, + height, + })) +} + +/// Moves a window to the given logical coordinates. +pub fn move_to(x: i32, y: i32) -> Command { + Command::single(command::Action::Window(window::Action::Move { x, y })) +} -- cgit