Synchronize window list with windows method

This commit is contained in:
Richard 2022-06-15 20:38:51 -03:00 committed by bungoboingo
parent 00d6baf861
commit 8fdd5ee8b6
2 changed files with 79 additions and 15 deletions

View file

@ -7,6 +7,7 @@ use crate::clipboard::{self, Clipboard};
use crate::conversion; use crate::conversion;
use crate::mouse; use crate::mouse;
use crate::renderer; use crate::renderer;
use crate::settings;
use crate::widget::operation; use crate::widget::operation;
use crate::{ use crate::{
Command, Debug, Element, Error, Executor, Proxy, Renderer, Runtime, Command, Debug, Element, Error, Executor, Proxy, Renderer, Runtime,
@ -28,10 +29,17 @@ use std::mem::ManuallyDrop;
// This is the an wrapper around the `Application::Message` associate type // This is the an wrapper around the `Application::Message` associate type
// to allows the `shell` to create internal messages, while still having // to allows the `shell` to create internal messages, while still having
// the current user specified custom messages. // the current user specified custom messages.
#[derive(Debug, Clone)] #[derive(Debug)]
pub enum Event<Message> { pub enum Event<Message> {
/// An [`Application`] generated message /// An [`Application`] generated message
Application(Message), Application(Message),
/// TODO(derezzedex)
// Create a wrapper variant of `window::Event` type instead
// (maybe we should also allow users to listen/react to those internal messages?)
NewWindow(usize, settings::Window),
/// TODO(derezzedex)
WindowCreated(usize, winit::window::Window),
} }
/// An interactive, native cross-platform application. /// An interactive, native cross-platform application.
@ -218,7 +226,7 @@ where
let mut context = task::Context::from_waker(task::noop_waker_ref()); let mut context = task::Context::from_waker(task::noop_waker_ref());
platform::run(event_loop, move |event, _, control_flow| { platform::run(event_loop, move |event, event_loop, control_flow| {
use winit::event_loop::ControlFlow; use winit::event_loop::ControlFlow;
if let ControlFlow::ExitWithCode(_) = control_flow { if let ControlFlow::ExitWithCode(_) = control_flow {
@ -237,6 +245,21 @@ where
event: winit::event::WindowEvent::Resized(*new_inner_size), event: winit::event::WindowEvent::Resized(*new_inner_size),
window_id, window_id,
}), }),
winit::event::Event::UserEvent(Event::NewWindow(id, settings)) => {
// TODO(derezzedex)
let window = settings
.into_builder(
"fix window title",
event_loop.primary_monitor(),
None,
)
.build(event_loop)
.expect("Failed to build window");
Some(winit::event::Event::UserEvent(Event::WindowCreated(
id, window,
)))
}
_ => event.to_static(), _ => event.to_static(),
}; };
@ -264,7 +287,7 @@ async fn run_instance<A, E, C>(
winit::event::Event<'_, Event<A::Message>>, winit::event::Event<'_, Event<A::Message>>,
>, >,
init_command: Command<A::Message>, init_command: Command<A::Message>,
windows: HashMap<usize, winit::window::Window>, mut windows: HashMap<usize, winit::window::Window>,
exit_on_close_request: bool, exit_on_close_request: bool,
) where ) where
A: Application + 'static, A: Application + 'static,
@ -275,12 +298,18 @@ async fn run_instance<A, E, C>(
use iced_futures::futures::stream::StreamExt; use iced_futures::futures::stream::StreamExt;
use winit::event; use winit::event;
let window = windows.values().next().expect("No window found"); // TODO(derezzedex)
let mut clipboard = Clipboard::connect(window); let mut clipboard =
Clipboard::connect(windows.values().next().expect("No window found"));
let mut cache = user_interface::Cache::default(); let mut cache = user_interface::Cache::default();
let mut surface = compositor.create_surface(&window); let mut surface = compositor
.create_surface(&windows.values().next().expect("No window found"));
let mut state = State::new(&application, window); // TODO(derezzedex)
let mut state = State::new(
&application,
windows.values().next().expect("No window found"),
);
let mut viewport_version = state.viewport_version(); let mut viewport_version = state.viewport_version();
let physical_size = state.physical_size(); let physical_size = state.physical_size();
@ -368,7 +397,7 @@ async fn run_instance<A, E, C>(
); );
// Update window // Update window
state.synchronize(&application, window); state.synchronize(&application, &windows, &proxy);
let should_exit = application.should_exit(); let should_exit = application.should_exit();
@ -396,6 +425,8 @@ async fn run_instance<A, E, C>(
); );
debug.draw_finished(); debug.draw_finished();
// TODO(derezzedex)
let window = windows.values().next().expect("No window found");
if new_mouse_interaction != mouse_interaction { if new_mouse_interaction != mouse_interaction {
window.set_cursor_icon(conversion::mouse_interaction( window.set_cursor_icon(conversion::mouse_interaction(
new_mouse_interaction, new_mouse_interaction,
@ -417,10 +448,15 @@ async fn run_instance<A, E, C>(
)), )),
)); ));
} }
event::Event::UserEvent(message) => { event::Event::UserEvent(event) => match event {
let Event::Application(message) = message; Event::Application(message) => {
messages.push(message); messages.push(message);
} }
Event::WindowCreated(id, window) => {
let _ = windows.insert(id, window);
}
Event::NewWindow(_, _) => unreachable!(),
},
event::Event::RedrawRequested(_) => { event::Event::RedrawRequested(_) => {
let physical_size = state.physical_size(); let physical_size = state.physical_size();
@ -451,6 +487,9 @@ async fn run_instance<A, E, C>(
state.cursor_position(), state.cursor_position(),
); );
// TODO(derezzedex)
let window =
windows.values().next().expect("No window found");
if new_mouse_interaction != mouse_interaction { if new_mouse_interaction != mouse_interaction {
window.set_cursor_icon(conversion::mouse_interaction( window.set_cursor_icon(conversion::mouse_interaction(
new_mouse_interaction, new_mouse_interaction,
@ -491,7 +530,12 @@ async fn run_instance<A, E, C>(
debug.render_finished(); debug.render_finished();
// Try rendering again next frame. // Try rendering again next frame.
window.request_redraw(); // TODO(derezzedex)
windows
.values()
.next()
.expect("No window found")
.request_redraw();
} }
}, },
} }
@ -506,6 +550,8 @@ async fn run_instance<A, E, C>(
break; break;
} }
// TODO(derezzedex)
let window = windows.values().next().expect("No window found");
state.update(window, &window_event, &mut debug); state.update(window, &window_event, &mut debug);
if let Some(event) = conversion::window_event( if let Some(event) = conversion::window_event(

View file

@ -1,10 +1,12 @@
use crate::application::{self, StyleSheet as _}; use crate::application::{self, StyleSheet as _};
use crate::conversion; use crate::conversion;
use crate::multi_window::Application; use crate::multi_window::{Application, Event};
use crate::{Color, Debug, Point, Size, Viewport}; use crate::{Color, Debug, Point, Size, Viewport};
use std::collections::HashMap;
use std::marker::PhantomData; use std::marker::PhantomData;
use winit::event::{Touch, WindowEvent}; use winit::event::{Touch, WindowEvent};
use winit::event_loop::EventLoopProxy;
use winit::window::Window; use winit::window::Window;
/// The state of a windowed [`Application`]. /// The state of a windowed [`Application`].
@ -181,7 +183,23 @@ where
/// and window after calling [`Application::update`]. /// and window after calling [`Application::update`].
/// ///
/// [`Application::update`]: crate::Program::update /// [`Application::update`]: crate::Program::update
pub fn synchronize(&mut self, application: &A, window: &Window) { pub fn synchronize(
&mut self,
application: &A,
windows: &HashMap<usize, Window>,
proxy: &EventLoopProxy<Event<A::Message>>,
) {
let new_windows = application.windows();
for (id, settings) in new_windows {
if !windows.contains_key(&id) {
proxy
.send_event(Event::NewWindow(id, settings))
.expect("Failed to send message");
}
}
let window = windows.values().next().expect("No window found");
// Update window title // Update window title
let new_title = application.title(); let new_title = application.title();