Introduce opaque window::Id type

This commit is contained in:
Richard 2022-06-21 15:59:45 -03:00 committed by bungoboingo
parent 8fdd5ee8b6
commit ec56c0686d
6 changed files with 48 additions and 12 deletions

View file

@ -1,10 +1,12 @@
//! Build window-based GUI applications. //! Build window-based GUI applications.
mod action; mod action;
mod event; mod event;
mod id;
mod mode; mod mode;
mod user_attention; mod user_attention;
pub use action::Action; pub use action::Action;
pub use event::Event; pub use event::Event;
pub use id::Id;
pub use mode::Mode; pub use mode::Mode;
pub use user_attention::UserAttention; pub use user_attention::UserAttention;

16
native/src/window/id.rs Normal file
View file

@ -0,0 +1,16 @@
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
#[derive(Debug, PartialEq, Eq, Hash)]
/// TODO(derezzedex)
pub struct Id(u64);
impl Id {
/// TODO(derezzedex)
pub fn new(id: impl Hash) -> Id {
let mut hasher = DefaultHasher::new();
id.hash(&mut hasher);
Id(hasher.finish())
}
}

View file

@ -1,3 +1,4 @@
use crate::window;
use crate::{Command, Element, Executor, Settings, Subscription}; use crate::{Command, Element, Executor, Settings, Subscription};
pub use iced_native::application::{Appearance, StyleSheet}; pub use iced_native::application::{Appearance, StyleSheet};
@ -45,6 +46,9 @@ pub trait Application: Sized {
/// title of your application when necessary. /// title of your application when necessary.
fn title(&self) -> String; fn title(&self) -> String;
/// TODO(derezzedex)
fn windows(&self) -> Vec<(window::Id, window::Settings)>;
/// Handles a __message__ and updates the state of the [`Application`]. /// Handles a __message__ and updates the state of the [`Application`].
/// ///
/// This is where you define your __update logic__. All the __messages__, /// This is where you define your __update logic__. All the __messages__,
@ -160,6 +164,16 @@ where
self.0.title() self.0.title()
} }
fn windows(&self) -> Vec<(window::Id, iced_winit::settings::Window)> {
self.0
.windows()
.into_iter()
.map(|(id, settings)| {
(id, iced_winit::settings::Window::from(settings))
})
.collect()
}
fn update(&mut self, message: Self::Message) -> Command<Self::Message> { fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
self.0.update(message) self.0.update(message)
} }

View file

@ -9,6 +9,7 @@ use crate::mouse;
use crate::renderer; use crate::renderer;
use crate::settings; use crate::settings;
use crate::widget::operation; use crate::widget::operation;
use crate::window;
use crate::{ use crate::{
Command, Debug, Element, Error, Executor, Proxy, Renderer, Runtime, Command, Debug, Element, Error, Executor, Proxy, Renderer, Runtime,
Settings, Size, Subscription, Settings, Size, Subscription,
@ -17,7 +18,6 @@ use crate::{
use iced_futures::futures::channel::mpsc; use iced_futures::futures::channel::mpsc;
use iced_futures::futures::{self, FutureExt}; use iced_futures::futures::{self, FutureExt};
use iced_graphics::compositor; use iced_graphics::compositor;
use iced_graphics::window;
use iced_native::user_interface::{self, UserInterface}; use iced_native::user_interface::{self, UserInterface};
pub use iced_native::application::{Appearance, StyleSheet}; pub use iced_native::application::{Appearance, StyleSheet};
@ -37,9 +37,9 @@ pub enum Event<Message> {
/// TODO(derezzedex) /// TODO(derezzedex)
// Create a wrapper variant of `window::Event` type instead // Create a wrapper variant of `window::Event` type instead
// (maybe we should also allow users to listen/react to those internal messages?) // (maybe we should also allow users to listen/react to those internal messages?)
NewWindow(usize, settings::Window), NewWindow(window::Id, settings::Window),
/// TODO(derezzedex) /// TODO(derezzedex)
WindowCreated(usize, winit::window::Window), WindowCreated(window::Id, winit::window::Window),
} }
/// An interactive, native cross-platform application. /// An interactive, native cross-platform application.
@ -66,6 +66,9 @@ where
/// The type of __messages__ your [`Program`] will produce. /// The type of __messages__ your [`Program`] will produce.
type Message: std::fmt::Debug + Send; type Message: std::fmt::Debug + Send;
/// TODO(derezzedex)
fn windows(&self) -> Vec<(window::Id, settings::Window)>;
/// Handles a __message__ and updates the state of the [`Program`]. /// Handles a __message__ and updates the state of the [`Program`].
/// ///
/// This is where you define your __update logic__. All the __messages__, /// This is where you define your __update logic__. All the __messages__,
@ -150,7 +153,7 @@ pub fn run<A, E, C>(
where where
A: Application + 'static, A: Application + 'static,
E: Executor + 'static, E: Executor + 'static,
C: window::Compositor<Renderer = A::Renderer> + 'static, C: iced_graphics::window::Compositor<Renderer = A::Renderer> + 'static,
<A::Renderer as crate::Renderer>::Theme: StyleSheet, <A::Renderer as crate::Renderer>::Theme: StyleSheet,
{ {
use futures::task; use futures::task;
@ -188,8 +191,8 @@ where
.build(&event_loop) .build(&event_loop)
.map_err(Error::WindowCreationFailed)?; .map_err(Error::WindowCreationFailed)?;
let windows: HashMap<usize, winit::window::Window> = let windows: HashMap<window::Id, winit::window::Window> =
HashMap::from([(0usize, window)]); HashMap::from([(window::Id::new(0usize), window)]);
let window = windows.values().next().expect("No window found"); let window = windows.values().next().expect("No window found");
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -287,12 +290,12 @@ 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>,
mut windows: HashMap<usize, winit::window::Window>, mut windows: HashMap<window::Id, winit::window::Window>,
exit_on_close_request: bool, exit_on_close_request: bool,
) where ) where
A: Application + 'static, A: Application + 'static,
E: Executor + 'static, E: Executor + 'static,
C: window::Compositor<Renderer = A::Renderer> + 'static, C: iced_graphics::window::Compositor<Renderer = A::Renderer> + 'static,
<A::Renderer as crate::Renderer>::Theme: StyleSheet, <A::Renderer as crate::Renderer>::Theme: StyleSheet,
{ {
use iced_futures::futures::stream::StreamExt; use iced_futures::futures::stream::StreamExt;
@ -629,7 +632,7 @@ pub fn update<A: Application, E: Executor>(
proxy: &mut winit::event_loop::EventLoopProxy<Event<A::Message>>, proxy: &mut winit::event_loop::EventLoopProxy<Event<A::Message>>,
debug: &mut Debug, debug: &mut Debug,
messages: &mut Vec<A::Message>, messages: &mut Vec<A::Message>,
windows: &HashMap<usize, winit::window::Window>, windows: &HashMap<window::Id, winit::window::Window>,
graphics_info: impl FnOnce() -> compositor::Information + Copy, graphics_info: impl FnOnce() -> compositor::Information + Copy,
) where ) where
<A::Renderer as crate::Renderer>::Theme: StyleSheet, <A::Renderer as crate::Renderer>::Theme: StyleSheet,
@ -671,7 +674,7 @@ pub fn run_command<A, E>(
clipboard: &mut Clipboard, clipboard: &mut Clipboard,
proxy: &mut winit::event_loop::EventLoopProxy<Event<A::Message>>, proxy: &mut winit::event_loop::EventLoopProxy<Event<A::Message>>,
debug: &mut Debug, debug: &mut Debug,
windows: &HashMap<usize, winit::window::Window>, windows: &HashMap<window::Id, winit::window::Window>,
_graphics_info: impl FnOnce() -> compositor::Information + Copy, _graphics_info: impl FnOnce() -> compositor::Information + Copy,
) where ) where
A: Application, A: Application,

View file

@ -1,6 +1,7 @@
use crate::application::{self, StyleSheet as _}; use crate::application::{self, StyleSheet as _};
use crate::conversion; use crate::conversion;
use crate::multi_window::{Application, Event}; use crate::multi_window::{Application, Event};
use crate::window;
use crate::{Color, Debug, Point, Size, Viewport}; use crate::{Color, Debug, Point, Size, Viewport};
use std::collections::HashMap; use std::collections::HashMap;
@ -186,7 +187,7 @@ where
pub fn synchronize( pub fn synchronize(
&mut self, &mut self,
application: &A, application: &A,
windows: &HashMap<usize, Window>, windows: &HashMap<window::Id, Window>,
proxy: &EventLoopProxy<Event<A::Message>>, proxy: &EventLoopProxy<Event<A::Message>>,
) { ) {
let new_windows = application.windows(); let new_windows = application.windows();

View file

@ -2,7 +2,7 @@
use crate::command::{self, Command}; use crate::command::{self, Command};
use iced_native::window; use iced_native::window;
pub use window::{Event, Mode, UserAttention}; pub use window::{Id, Event, Mode, UserAttention};
/// Closes the current window and exits the application. /// Closes the current window and exits the application.
pub fn close<Message>() -> Command<Message> { pub fn close<Message>() -> Command<Message> {