add window::Id to Event and Action

This commit is contained in:
Richard 2022-09-19 20:59:37 -03:00 committed by bungoboingo
parent 974cc6b6f5
commit 0ad53a3d5c
11 changed files with 99 additions and 78 deletions

View file

@ -52,7 +52,7 @@ impl Application for Events {
} }
} }
Message::EventOccurred(event) => { Message::EventOccurred(event) => {
if let Event::Window(window::Event::CloseRequested) = event { if let Event::Window(_, window::Event::CloseRequested) = event {
self.should_exit = true; self.should_exit = true;
} }
} }

View file

@ -13,6 +13,7 @@ use iced_glow::{Backend, Renderer, Settings, Viewport};
use iced_glutin::conversion; use iced_glutin::conversion;
use iced_glutin::glutin; use iced_glutin::glutin;
use iced_glutin::renderer; use iced_glutin::renderer;
use iced_glutin::window;
use iced_glutin::{program, Clipboard, Color, Debug, Size}; use iced_glutin::{program, Clipboard, Color, Debug, Size};
pub fn main() { pub fn main() {
@ -107,6 +108,7 @@ pub fn main() {
// Map window event to iced event // Map window event to iced event
if let Some(event) = iced_winit::conversion::window_event( if let Some(event) = iced_winit::conversion::window_event(
window::Id::MAIN,
&event, &event,
windowed_context.window().scale_factor(), windowed_context.window().scale_factor(),
modifiers, modifiers,

View file

@ -6,8 +6,8 @@ use scene::Scene;
use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport}; use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport};
use iced_winit::{ use iced_winit::{
conversion, futures, program, renderer, winit, Clipboard, Color, Debug, conversion, futures, program, renderer, window, winit, Clipboard, Color,
Size, Debug, Size,
}; };
use winit::{ use winit::{
@ -169,6 +169,7 @@ pub fn main() {
// Map window event to iced event // Map window event to iced event
if let Some(event) = iced_winit::conversion::window_event( if let Some(event) = iced_winit::conversion::window_event(
window::Id::MAIN,
&event, &event,
window.scale_factor(), window.scale_factor(),
modifiers, modifiers,

View file

@ -435,6 +435,7 @@ async fn run_instance<A, E, C>(
state.update(context.window(), &window_event, &mut debug); state.update(context.window(), &window_event, &mut debug);
if let Some(event) = conversion::window_event( if let Some(event) = conversion::window_event(
crate::window::Id::MAIN,
&window_event, &window_event,
state.scale_factor(), state.scale_factor(),
state.modifiers(), state.modifiers(),

View file

@ -20,7 +20,7 @@ pub enum Action<T> {
Clipboard(clipboard::Action<T>), Clipboard(clipboard::Action<T>),
/// Run a window action. /// Run a window action.
Window(window::Action<T>), Window(window::Id, window::Action<T>),
/// Run a system action. /// Run a system action.
System(system::Action<T>), System(system::Action<T>),
@ -46,7 +46,7 @@ impl<T> Action<T> {
match self { match self {
Self::Future(future) => Action::Future(Box::pin(future.map(f))), Self::Future(future) => Action::Future(Box::pin(future.map(f))),
Self::Clipboard(action) => Action::Clipboard(action.map(f)), Self::Clipboard(action) => Action::Clipboard(action.map(f)),
Self::Window(window) => Action::Window(window.map(f)), Self::Window(id, window) => Action::Window(id, window.map(f)),
Self::System(system) => Action::System(system.map(f)), Self::System(system) => Action::System(system.map(f)),
Self::Widget(widget) => Action::Widget(widget.map(f)), Self::Widget(widget) => Action::Widget(widget.map(f)),
} }
@ -60,7 +60,9 @@ impl<T> fmt::Debug for Action<T> {
Self::Clipboard(action) => { Self::Clipboard(action) => {
write!(f, "Action::Clipboard({:?})", action) write!(f, "Action::Clipboard({:?})", action)
} }
Self::Window(action) => write!(f, "Action::Window({:?})", action), Self::Window(id, action) => {
write!(f, "Action::Window({:?}, {:?})", id, action)
}
Self::System(action) => write!(f, "Action::System({:?})", action), Self::System(action) => write!(f, "Action::System({:?})", action),
Self::Widget(_action) => write!(f, "Action::Widget"), Self::Widget(_action) => write!(f, "Action::Widget"),
} }

View file

@ -19,7 +19,7 @@ pub enum Event {
Mouse(mouse::Event), Mouse(mouse::Event),
/// A window event /// A window event
Window(window::Event), Window(window::Id, window::Event),
/// A touch event /// A touch event
Touch(touch::Event), Touch(touch::Event),

View file

@ -6,6 +6,9 @@ use std::hash::{Hash, Hasher};
pub struct Id(u64); pub struct Id(u64);
impl Id { impl Id {
/// TODO(derezzedex): maybe change `u64` to an enum `Type::{Single, Multi(u64)}`
pub const MAIN: Self = Id(0);
/// TODO(derezzedex) /// TODO(derezzedex)
pub fn new(id: impl Hash) -> Id { pub fn new(id: impl Hash) -> Id {
let mut hasher = DefaultHasher::new(); let mut hasher = DefaultHasher::new();

View file

@ -502,6 +502,7 @@ async fn run_instance<A, E, C>(
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(
crate::window::Id::MAIN,
&window_event, &window_event,
state.scale_factor(), state.scale_factor(),
state.modifiers(), state.modifiers(),
@ -667,7 +668,7 @@ pub fn run_command<A, E>(
clipboard.write(contents); clipboard.write(contents);
} }
}, },
command::Action::Window(action) => match action { command::Action::Window(_id, action) => match action {
window::Action::Close => { window::Action::Close => {
*should_exit = true; *should_exit = true;
} }

View file

@ -10,6 +10,7 @@ use crate::{Event, Point, Position};
/// Converts a winit window event into an iced event. /// Converts a winit window event into an iced event.
pub fn window_event( pub fn window_event(
id: window::Id,
event: &winit::event::WindowEvent<'_>, event: &winit::event::WindowEvent<'_>,
scale_factor: f64, scale_factor: f64,
modifiers: winit::event::ModifiersState, modifiers: winit::event::ModifiersState,
@ -20,21 +21,27 @@ pub fn window_event(
WindowEvent::Resized(new_size) => { WindowEvent::Resized(new_size) => {
let logical_size = new_size.to_logical(scale_factor); let logical_size = new_size.to_logical(scale_factor);
Some(Event::Window(window::Event::Resized { Some(Event::Window(
width: logical_size.width, id,
height: logical_size.height, window::Event::Resized {
})) width: logical_size.width,
height: logical_size.height,
},
))
} }
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
let logical_size = new_inner_size.to_logical(scale_factor); let logical_size = new_inner_size.to_logical(scale_factor);
Some(Event::Window(window::Event::Resized { Some(Event::Window(
width: logical_size.width, id,
height: logical_size.height, window::Event::Resized {
})) width: logical_size.width,
height: logical_size.height,
},
))
} }
WindowEvent::CloseRequested => { WindowEvent::CloseRequested => {
Some(Event::Window(window::Event::CloseRequested)) Some(Event::Window(id, window::Event::CloseRequested))
} }
WindowEvent::CursorMoved { position, .. } => { WindowEvent::CursorMoved { position, .. } => {
let position = position.to_logical::<f64>(scale_factor); let position = position.to_logical::<f64>(scale_factor);
@ -112,19 +119,22 @@ pub fn window_event(
WindowEvent::ModifiersChanged(new_modifiers) => Some(Event::Keyboard( WindowEvent::ModifiersChanged(new_modifiers) => Some(Event::Keyboard(
keyboard::Event::ModifiersChanged(self::modifiers(*new_modifiers)), keyboard::Event::ModifiersChanged(self::modifiers(*new_modifiers)),
)), )),
WindowEvent::Focused(focused) => Some(Event::Window(if *focused { WindowEvent::Focused(focused) => Some(Event::Window(
window::Event::Focused id,
} else { if *focused {
window::Event::Unfocused window::Event::Focused
})), } else {
window::Event::Unfocused
},
)),
WindowEvent::HoveredFile(path) => { WindowEvent::HoveredFile(path) => {
Some(Event::Window(window::Event::FileHovered(path.clone()))) Some(Event::Window(id, window::Event::FileHovered(path.clone())))
} }
WindowEvent::DroppedFile(path) => { WindowEvent::DroppedFile(path) => {
Some(Event::Window(window::Event::FileDropped(path.clone()))) Some(Event::Window(id, window::Event::FileDropped(path.clone())))
} }
WindowEvent::HoveredFileCancelled => { WindowEvent::HoveredFileCancelled => {
Some(Event::Window(window::Event::FilesHoveredLeft)) Some(Event::Window(id, window::Event::FilesHoveredLeft))
} }
WindowEvent::Touch(touch) => { WindowEvent::Touch(touch) => {
Some(Event::Touch(touch_event(*touch, scale_factor))) Some(Event::Touch(touch_event(*touch, scale_factor)))
@ -133,7 +143,7 @@ pub fn window_event(
let winit::dpi::LogicalPosition { x, y } = let winit::dpi::LogicalPosition { x, y } =
position.to_logical(scale_factor); position.to_logical(scale_factor);
Some(Event::Window(window::Event::Moved { x, y })) Some(Event::Window(id, window::Event::Moved { x, y }))
} }
_ => None, _ => None,
} }

View file

@ -363,7 +363,6 @@ async fn run_instance<A, E, C>(
&mut proxy, &mut proxy,
&mut debug, &mut debug,
&windows, &windows,
&window_ids,
|| compositor.fetch_information(), || compositor.fetch_information(),
); );
} }
@ -456,7 +455,6 @@ async fn run_instance<A, E, C>(
&mut debug, &mut debug,
&mut messages, &mut messages,
&windows, &windows,
&window_ids,
|| compositor.fetch_information(), || compositor.fetch_information(),
); );
@ -701,6 +699,7 @@ async fn run_instance<A, E, C>(
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(
*window_ids.get(&window_id).unwrap(),
&window_event, &window_event,
state.scale_factor(), state.scale_factor(),
state.modifiers(), state.modifiers(),
@ -787,7 +786,6 @@ pub fn update<A: Application, E: Executor>(
debug: &mut Debug, debug: &mut Debug,
messages: &mut Vec<A::Message>, messages: &mut Vec<A::Message>,
windows: &HashMap<window::Id, winit::window::Window>, windows: &HashMap<window::Id, winit::window::Window>,
window_ids: &HashMap<winit::window::WindowId, window::Id>,
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,
@ -810,7 +808,6 @@ pub fn update<A: Application, E: Executor>(
proxy, proxy,
debug, debug,
windows, windows,
window_ids,
graphics_info, graphics_info,
); );
} }
@ -831,7 +828,6 @@ pub fn run_command<A, E>(
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<window::Id, winit::window::Window>, windows: &HashMap<window::Id, winit::window::Window>,
window_ids: &HashMap<winit::window::WindowId, window::Id>,
_graphics_info: impl FnOnce() -> compositor::Information + Copy, _graphics_info: impl FnOnce() -> compositor::Information + Copy,
) where ) where
A: Application, A: Application,
@ -842,10 +838,6 @@ pub fn run_command<A, E>(
use iced_native::system; use iced_native::system;
use iced_native::window; use iced_native::window;
// TODO(derezzedex)
let window = windows.values().next().expect("No window found");
let id = *window_ids.get(&window.id()).unwrap();
for action in command.actions() { for action in command.actions() {
match action { match action {
command::Action::Future(future) => { command::Action::Future(future) => {
@ -863,38 +855,41 @@ pub fn run_command<A, E>(
clipboard.write(contents); clipboard.write(contents);
} }
}, },
command::Action::Window(action) => match action { command::Action::Window(id, action) => {
window::Action::Resize { width, height } => { let window = windows.get(&id).expect("No window found");
window.set_inner_size(winit::dpi::LogicalSize {
width,
height,
});
}
window::Action::Move { x, y } => {
window.set_outer_position(winit::dpi::LogicalPosition {
x,
y,
});
}
window::Action::SetMode(mode) => {
window.set_visible(conversion::visible(mode));
window.set_fullscreen(conversion::fullscreen(
window.primary_monitor(),
mode,
));
}
window::Action::FetchMode(tag) => {
let mode = if window.is_visible().unwrap_or(true) {
conversion::mode(window.fullscreen())
} else {
window::Mode::Hidden
};
proxy match action {
.send_event(Event::Application(tag(mode))) window::Action::Resize { width, height } => {
.expect("Send message to event loop"); window.set_inner_size(winit::dpi::LogicalSize {
width,
height,
});
}
window::Action::Move { x, y } => {
window.set_outer_position(
winit::dpi::LogicalPosition { x, y },
);
}
window::Action::SetMode(mode) => {
window.set_visible(conversion::visible(mode));
window.set_fullscreen(conversion::fullscreen(
window.primary_monitor(),
mode,
));
}
window::Action::FetchMode(tag) => {
let mode = if window.is_visible().unwrap_or(true) {
conversion::mode(window.fullscreen())
} else {
window::Mode::Hidden
};
proxy
.send_event(Event::Application(tag(mode)))
.expect("Send message to event loop");
}
} }
}, }
command::Action::System(action) => match action { command::Action::System(action) => match action {
system::Action::QueryInformation(_tag) => { system::Action::QueryInformation(_tag) => {
#[cfg(feature = "system")] #[cfg(feature = "system")]
@ -925,7 +920,7 @@ pub fn run_command<A, E>(
renderer, renderer,
state.logical_size(), state.logical_size(),
debug, debug,
id, window::Id::MAIN, // TODO(derezzedex): run the operation on every widget tree
); );
while let Some(mut operation) = current_operation.take() { while let Some(mut operation) = current_operation.take() {

View file

@ -15,11 +15,15 @@ pub fn drag<Message>() -> Command<Message> {
} }
/// Resizes the window to the given logical dimensions. /// Resizes the window to the given logical dimensions.
pub fn resize<Message>(width: u32, height: u32) -> Command<Message> { pub fn resize<Message>(
Command::single(command::Action::Window(window::Action::Resize { id: window::Id,
width, width: u32,
height, height: u32,
})) ) -> Command<Message> {
Command::single(command::Action::Window(
id,
window::Action::Resize { width, height },
))
} }
/// Sets the window to maximized or back. /// Sets the window to maximized or back.
@ -33,13 +37,13 @@ pub fn minimize<Message>(value: bool) -> Command<Message> {
} }
/// Moves a window to the given logical coordinates. /// Moves a window to the given logical coordinates.
pub fn move_to<Message>(x: i32, y: i32) -> Command<Message> { pub fn move_to<Message>(id: window::Id, x: i32, y: i32) -> Command<Message> {
Command::single(command::Action::Window(window::Action::Move { x, y })) Command::single(command::Action::Window(id, window::Action::Move { x, y }))
} }
/// Sets the [`Mode`] of the window. /// Sets the [`Mode`] of the window.
pub fn set_mode<Message>(mode: Mode) -> Command<Message> { pub fn set_mode<Message>(id: window::Id, mode: Mode) -> Command<Message> {
Command::single(command::Action::Window(window::Action::SetMode(mode))) Command::single(command::Action::Window(id, window::Action::SetMode(mode)))
} }
/// Sets the window to maximized or back. /// Sets the window to maximized or back.
@ -49,9 +53,11 @@ pub fn toggle_maximize<Message>() -> Command<Message> {
/// Fetches the current [`Mode`] of the window. /// Fetches the current [`Mode`] of the window.
pub fn fetch_mode<Message>( pub fn fetch_mode<Message>(
id: window::Id,
f: impl FnOnce(Mode) -> Message + 'static, f: impl FnOnce(Mode) -> Message + 'static,
) -> Command<Message> { ) -> Command<Message> {
Command::single(command::Action::Window(window::Action::FetchMode( Command::single(command::Action::Window(
Box::new(f), id,
))) window::Action::FetchMode(Box::new(f)),
))
} }