From ab34ef45e0d9a17d6aee3eadf52b753fce73e3b6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 10 Oct 2019 05:50:01 +0200 Subject: Move `winit::Application` to its own module --- winit/src/application.rs | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 winit/src/application.rs (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs new file mode 100644 index 00000000..9e23cd40 --- /dev/null +++ b/winit/src/application.rs @@ -0,0 +1,125 @@ +use crate::renderer::Windowed; +use crate::{Cache, Column, Element, Length, UserInterface}; + +pub trait Application { + type Renderer: Windowed + iced_native::column::Renderer; + + type Message; + + fn update(&mut self, message: Self::Message); + + fn view(&mut self) -> Element; + + fn run(mut self) + where + Self: 'static + Sized, + { + use winit::{ + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, + }; + + let event_loop = EventLoop::new(); + + // TODO: Ask for window settings and configure this properly + let window = WindowBuilder::new() + .build(&event_loop) + .expect("Open window"); + + let size = window.inner_size().to_physical(window.hidpi_factor());; + let (width, height) = (size.width as u16, size.height as u16); + + let mut renderer = Self::Renderer::new(&window); + let mut target = renderer.target(width, height); + + let user_interface = UserInterface::build( + document(&mut self, width, height), + Cache::default(), + &mut renderer, + ); + + let mut primitive = user_interface.draw(&mut renderer); + let mut cache = Some(user_interface.into_cache()); + let mut events = Vec::new(); + + window.request_redraw(); + + event_loop.run(move |event, _, control_flow| match event { + Event::EventsCleared => { + // TODO: We should be able to keep a user interface alive + // between events once we remove state references. + // + // This will allow us to rebuild it only when a message is + // handled. + let mut user_interface = UserInterface::build( + document(&mut self, width, height), + cache.take().unwrap(), + &mut renderer, + ); + + let messages = user_interface.update(events.drain(..)); + + if messages.is_empty() { + primitive = user_interface.draw(&mut renderer); + + cache = Some(user_interface.into_cache()); + } else { + // When there are messages, we are forced to rebuild twice + // for now :^) + let temp_cache = user_interface.into_cache(); + + for message in messages { + self.update(message); + } + + let user_interface = UserInterface::build( + document(&mut self, width, height), + temp_cache, + &mut renderer, + ); + + primitive = user_interface.draw(&mut renderer); + + cache = Some(user_interface.into_cache()); + } + + window.request_redraw(); + } + Event::WindowEvent { + event: WindowEvent::RedrawRequested, + .. + } => { + renderer.draw(&mut target, &primitive); + + // TODO: Handle animations! + // Maybe we can use `ControlFlow::WaitUntil` for this. + } + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => { + *control_flow = ControlFlow::Exit; + } + _ => { + *control_flow = ControlFlow::Wait; + } + }) + } +} + +fn document( + application: &mut Application, + width: u16, + height: u16, +) -> Element +where + Application: self::Application, + Application::Message: 'static, +{ + Column::new() + .width(Length::Units(width)) + .height(Length::Units(height)) + .push(application.view()) + .into() +} -- cgit From ae585eb9cb043f2f6565bbe9c80c50cb7ded8bac Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 10 Oct 2019 05:52:35 +0200 Subject: Process `winit` mouse input and cursor movement --- winit/src/application.rs | 55 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index 9e23cd40..d09aad7a 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1,8 +1,10 @@ -use crate::renderer::Windowed; -use crate::{Cache, Column, Element, Length, UserInterface}; +use crate::{ + column, conversion, input::mouse, renderer::Windowed, Cache, Column, + Element, Event, Length, UserInterface, +}; pub trait Application { - type Renderer: Windowed + iced_native::column::Renderer; + type Renderer: Windowed + column::Renderer; type Message; @@ -15,7 +17,7 @@ pub trait Application { Self: 'static + Sized, { use winit::{ - event::{Event, WindowEvent}, + event::{self, WindowEvent}, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder, }; @@ -46,7 +48,7 @@ pub trait Application { window.request_redraw(); event_loop.run(move |event, _, control_flow| match event { - Event::EventsCleared => { + event::Event::EventsCleared => { // TODO: We should be able to keep a user interface alive // between events once we remove state references. // @@ -70,6 +72,8 @@ pub trait Application { let temp_cache = user_interface.into_cache(); for message in messages { + log::debug!("Updating"); + self.update(message); } @@ -86,21 +90,36 @@ pub trait Application { window.request_redraw(); } - Event::WindowEvent { - event: WindowEvent::RedrawRequested, + event::Event::WindowEvent { + event: window_event, .. - } => { - renderer.draw(&mut target, &primitive); + } => match window_event { + WindowEvent::RedrawRequested => { + renderer.draw(&mut target, &primitive); - // TODO: Handle animations! - // Maybe we can use `ControlFlow::WaitUntil` for this. - } - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - *control_flow = ControlFlow::Exit; - } + // TODO: Handle animations! + // Maybe we can use `ControlFlow::WaitUntil` for this. + } + WindowEvent::CursorMoved { position, .. } => { + let physical_position = + position.to_physical(window.hidpi_factor()); + + events.push(Event::Mouse(mouse::Event::CursorMoved { + x: physical_position.x as f32, + y: physical_position.y as f32, + })); + } + WindowEvent::MouseInput { button, state, .. } => { + events.push(Event::Mouse(mouse::Event::Input { + button: conversion::mouse_button(button), + state: conversion::button_state(state), + })); + } + WindowEvent::CloseRequested => { + *control_flow = ControlFlow::Exit; + } + _ => {} + }, _ => { *control_flow = ControlFlow::Wait; } -- cgit From 2fe01a0b1ee930759d2180fe25666c0701bffd40 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 10 Oct 2019 05:53:57 +0200 Subject: Use improved `RedrawRequested` API in `iced_winit` --- winit/src/application.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index d09aad7a..ab6a43f5 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -48,7 +48,7 @@ pub trait Application { window.request_redraw(); event_loop.run(move |event, _, control_flow| match event { - event::Event::EventsCleared => { + event::Event::MainEventsCleared => { // TODO: We should be able to keep a user interface alive // between events once we remove state references. // @@ -90,16 +90,16 @@ pub trait Application { window.request_redraw(); } + event::Event::RedrawRequested(_) => { + renderer.draw(&mut target, &primitive); + + // TODO: Handle animations! + // Maybe we can use `ControlFlow::WaitUntil` for this. + } event::Event::WindowEvent { event: window_event, .. } => match window_event { - WindowEvent::RedrawRequested => { - renderer.draw(&mut target, &primitive); - - // TODO: Handle animations! - // Maybe we can use `ControlFlow::WaitUntil` for this. - } WindowEvent::CursorMoved { position, .. } => { let physical_position = position.to_physical(window.hidpi_factor()); -- cgit From 1f60ca3ab4287b5f9bf605fcb7b3cdcf20e17074 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 10 Oct 2019 05:58:42 +0200 Subject: Update mouse cursor icon properly in `iced_winit` --- winit/src/application.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index ab6a43f5..ac3a4619 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1,6 +1,6 @@ use crate::{ column, conversion, input::mouse, renderer::Windowed, Cache, Column, - Element, Event, Length, UserInterface, + Element, Event, Length, MouseCursor, UserInterface, }; pub trait Application { @@ -44,6 +44,7 @@ pub trait Application { let mut primitive = user_interface.draw(&mut renderer); let mut cache = Some(user_interface.into_cache()); let mut events = Vec::new(); + let mut mouse_cursor = MouseCursor::OutOfBounds; window.request_redraw(); @@ -91,7 +92,15 @@ pub trait Application { window.request_redraw(); } event::Event::RedrawRequested(_) => { - renderer.draw(&mut target, &primitive); + let new_mouse_cursor = renderer.draw(&mut target, &primitive); + + if new_mouse_cursor != mouse_cursor { + window.set_cursor_icon(conversion::mouse_cursor( + new_mouse_cursor, + )); + + mouse_cursor = new_mouse_cursor; + } // TODO: Handle animations! // Maybe we can use `ControlFlow::WaitUntil` for this. -- cgit From 650d020fde6e684bf3c865de823ace08194b5220 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 11 Oct 2019 21:16:36 +0200 Subject: Handle window resizes in `iced_winit` --- winit/src/application.rs | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index ac3a4619..54c31126 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -29,14 +29,17 @@ pub trait Application { .build(&event_loop) .expect("Open window"); - let size = window.inner_size().to_physical(window.hidpi_factor());; - let (width, height) = (size.width as u16, size.height as u16); + let mut size: Size = window + .inner_size() + .to_physical(window.hidpi_factor()) + .into(); + let mut new_size: Option = None; let mut renderer = Self::Renderer::new(&window); - let mut target = renderer.target(width, height); + let mut target = renderer.target(size.width, size.height); let user_interface = UserInterface::build( - document(&mut self, width, height), + document(&mut self, size), Cache::default(), &mut renderer, ); @@ -56,7 +59,7 @@ pub trait Application { // This will allow us to rebuild it only when a message is // handled. let mut user_interface = UserInterface::build( - document(&mut self, width, height), + document(&mut self, size), cache.take().unwrap(), &mut renderer, ); @@ -79,7 +82,7 @@ pub trait Application { } let user_interface = UserInterface::build( - document(&mut self, width, height), + document(&mut self, size), temp_cache, &mut renderer, ); @@ -92,6 +95,11 @@ pub trait Application { window.request_redraw(); } event::Event::RedrawRequested(_) => { + if let Some(new_size) = new_size.take() { + target = renderer.target(new_size.width, new_size.height); + size = new_size; + } + let new_mouse_cursor = renderer.draw(&mut target, &primitive); if new_mouse_cursor != mouse_cursor { @@ -127,6 +135,12 @@ pub trait Application { WindowEvent::CloseRequested => { *control_flow = ControlFlow::Exit; } + WindowEvent::Resized(size) => { + new_size = + Some(size.to_physical(window.hidpi_factor()).into()); + + log::debug!("Resized: {:?}", new_size); + } _ => {} }, _ => { @@ -136,18 +150,32 @@ pub trait Application { } } -fn document( - application: &mut Application, +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +struct Size { width: u16, height: u16, +} + +impl From for Size { + fn from(physical_size: winit::dpi::PhysicalSize) -> Self { + Self { + width: physical_size.width.round() as u16, + height: physical_size.height.round() as u16, + } + } +} + +fn document( + application: &mut Application, + size: Size, ) -> Element where Application: self::Application, Application::Message: 'static, { Column::new() - .width(Length::Units(width)) - .height(Length::Units(height)) + .width(Length::Units(size.width)) + .height(Length::Units(size.height)) .push(application.view()) .into() } -- cgit From 8846a239cf14edd464b1d09f6d6d57ad9b5c9fc7 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 11 Oct 2019 22:15:39 +0200 Subject: Rename `Renderer::Primitive` to `Renderer::Output` --- winit/src/application.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index 54c31126..2ea52e5f 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -100,7 +100,7 @@ pub trait Application { size = new_size; } - let new_mouse_cursor = renderer.draw(&mut target, &primitive); + let new_mouse_cursor = renderer.draw(&primitive, &mut target); if new_mouse_cursor != mouse_cursor { window.set_cursor_icon(conversion::mouse_cursor( -- cgit From c63bdacaad7d923358863e3b6b2524893788d91c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 11 Oct 2019 23:45:01 +0200 Subject: Make `Renderer` immutable in `UserInterface::build` --- winit/src/application.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index 2ea52e5f..8345a5ed 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -41,7 +41,7 @@ pub trait Application { let user_interface = UserInterface::build( document(&mut self, size), Cache::default(), - &mut renderer, + &renderer, ); let mut primitive = user_interface.draw(&mut renderer); @@ -61,7 +61,7 @@ pub trait Application { let mut user_interface = UserInterface::build( document(&mut self, size), cache.take().unwrap(), - &mut renderer, + &renderer, ); let messages = user_interface.update(events.drain(..)); @@ -84,7 +84,7 @@ pub trait Application { let user_interface = UserInterface::build( document(&mut self, size), temp_cache, - &mut renderer, + &renderer, ); primitive = user_interface.draw(&mut renderer); -- cgit From 99e1a3780a1ea3ccb173d1fb4cbe889bb08b9643 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 23 Oct 2019 04:44:33 +0200 Subject: Set initial window size to 1280x1024 for now This will be configurable when calling `Application::run` in the future. --- winit/src/application.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'winit/src/application.rs') diff --git a/winit/src/application.rs b/winit/src/application.rs index 8345a5ed..418ee3c4 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -26,6 +26,10 @@ pub trait Application { // TODO: Ask for window settings and configure this properly let window = WindowBuilder::new() + .with_inner_size(winit::dpi::LogicalSize { + width: 1280.0, + height: 1024.0, + }) .build(&event_loop) .expect("Open window"); -- cgit