From fee46fd653c716328d0afaee8e5558e5b408ad24 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 4 Nov 2020 22:46:32 +0100 Subject: Introduce `application::State` in `iced_winit` --- winit/src/application/state.rs | 171 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 winit/src/application/state.rs (limited to 'winit/src/application/state.rs') diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs new file mode 100644 index 00000000..7de3ecef --- /dev/null +++ b/winit/src/application/state.rs @@ -0,0 +1,171 @@ +use crate::conversion; +use crate::{Application, Color, Debug, Mode, Point, Size, Viewport}; + +use std::marker::PhantomData; +use winit::event::WindowEvent; +use winit::window::Window; + +#[derive(Debug, Clone)] +pub struct State { + title: String, + mode: Mode, + background_color: Color, + scale_factor: f64, + viewport: Viewport, + cursor_position: winit::dpi::PhysicalPosition, + modifiers: winit::event::ModifiersState, + application: PhantomData, +} + +impl State { + pub fn new(application: &A, window: &Window) -> Self { + let title = application.title(); + let mode = application.mode(); + let background_color = application.background_color(); + let scale_factor = application.scale_factor(); + + let viewport = { + let physical_size = window.inner_size(); + + Viewport::with_physical_size( + Size::new(physical_size.width, physical_size.height), + window.scale_factor() * scale_factor, + ) + }; + + Self { + title, + mode, + background_color, + scale_factor, + viewport, + // TODO: Encode cursor availability in the type-system + cursor_position: winit::dpi::PhysicalPosition::new(-1.0, -1.0), + modifiers: winit::event::ModifiersState::default(), + application: PhantomData, + } + } + + pub fn background_color(&self) -> Color { + self.background_color + } + + pub fn viewport(&self) -> &Viewport { + &self.viewport + } + + pub fn physical_size(&self) -> Size { + self.viewport.physical_size() + } + + pub fn logical_size(&self) -> Size { + self.viewport.logical_size() + } + + pub fn scale_factor(&self) -> f64 { + self.viewport.scale_factor() + } + + pub fn cursor_position(&self) -> Point { + conversion::cursor_position( + self.cursor_position, + self.viewport.scale_factor(), + ) + } + + pub fn modifiers(&self) -> winit::event::ModifiersState { + self.modifiers + } + + pub fn update( + &mut self, + window: &Window, + event: &WindowEvent<'_>, + _debug: &mut Debug, + ) { + match event { + WindowEvent::Resized(new_size) => { + let size = Size::new(new_size.width, new_size.height); + + self.viewport = Viewport::with_physical_size( + size, + window.scale_factor() * self.scale_factor, + ); + } + WindowEvent::ScaleFactorChanged { + scale_factor: new_scale_factor, + new_inner_size, + } => { + let size = + Size::new(new_inner_size.width, new_inner_size.height); + + self.viewport = Viewport::with_physical_size( + size, + new_scale_factor * self.scale_factor, + ); + } + WindowEvent::CursorMoved { position, .. } => { + self.cursor_position = *position; + } + WindowEvent::CursorLeft { .. } => { + // TODO: Encode cursor availability in the type-system + self.cursor_position = + winit::dpi::PhysicalPosition::new(-1.0, -1.0); + } + WindowEvent::ModifiersChanged(new_modifiers) => { + self.modifiers = *new_modifiers; + } + #[cfg(feature = "debug")] + WindowEvent::KeyboardInput { + input: + winit::event::KeyboardInput { + virtual_keycode: Some(winit::event::VirtualKeyCode::F12), + state: winit::event::ElementState::Pressed, + .. + }, + .. + } => _debug.toggle(), + _ => {} + } + } + + pub fn synchronize(&mut self, application: &A, window: &Window) { + // Update window title + let new_title = application.title(); + + if self.title != new_title { + window.set_title(&new_title); + + self.title = new_title; + } + + // Update window mode + let new_mode = application.mode(); + + if self.mode != new_mode { + window.set_fullscreen(conversion::fullscreen( + window.current_monitor(), + new_mode, + )); + + self.mode = new_mode; + } + + // Update background color + self.background_color = application.background_color(); + + // Update scale factor + let new_scale_factor = application.scale_factor(); + + if self.scale_factor != new_scale_factor { + let size = window.inner_size(); + + self.viewport = Viewport::with_physical_size( + Size::new(size.width, size.height), + window.scale_factor() * new_scale_factor, + ); + + self.scale_factor = new_scale_factor; + } + } +} -- cgit From 88993fb092fb0391ea42ffd725f680d1c98c95d7 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 5 Nov 2020 02:11:11 +0100 Subject: Relayout `UserInterface` on resize in `iced_winit` --- winit/src/application/state.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'winit/src/application/state.rs') diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 7de3ecef..1f3c77a0 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -12,6 +12,7 @@ pub struct State { background_color: Color, scale_factor: f64, viewport: Viewport, + viewport_version: usize, cursor_position: winit::dpi::PhysicalPosition, modifiers: winit::event::ModifiersState, application: PhantomData, @@ -39,6 +40,7 @@ impl State { background_color, scale_factor, viewport, + viewport_version: 0, // TODO: Encode cursor availability in the type-system cursor_position: winit::dpi::PhysicalPosition::new(-1.0, -1.0), modifiers: winit::event::ModifiersState::default(), @@ -54,6 +56,10 @@ impl State { &self.viewport } + pub fn viewport_version(&self) -> usize { + self.viewport_version + } + pub fn physical_size(&self) -> Size { self.viewport.physical_size() } @@ -91,6 +97,8 @@ impl State { size, window.scale_factor() * self.scale_factor, ); + + self.viewport_version = self.viewport_version.wrapping_add(1); } WindowEvent::ScaleFactorChanged { scale_factor: new_scale_factor, @@ -103,6 +111,8 @@ impl State { size, new_scale_factor * self.scale_factor, ); + + self.viewport_version = self.viewport_version.wrapping_add(1); } WindowEvent::CursorMoved { position, .. } => { self.cursor_position = *position; -- cgit From 631c9e4a215d8f044d76ea926117f9a9bdd24d5d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 6 Nov 2020 02:25:56 +0100 Subject: Write missing documentation in `iced_winit` --- winit/src/application/state.rs | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'winit/src/application/state.rs') diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 1f3c77a0..4c0bfd34 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -5,6 +5,9 @@ use std::marker::PhantomData; use winit::event::WindowEvent; use winit::window::Window; +/// The state of a windowed [`Application`]. +/// +/// [`Application`]: ../trait.Application.html #[derive(Debug, Clone)] pub struct State { title: String, @@ -19,6 +22,10 @@ pub struct State { } impl State { + /// Creates a new [`State`] for the provided [`Application`] and window. + /// + /// [`State`]: struct.State.html + /// [`Application`]: ../trait.Application.html pub fn new(application: &A, window: &Window) -> Self { let title = application.title(); let mode = application.mode(); @@ -48,30 +55,61 @@ impl State { } } + /// Returns the current background [`Color`] of the [`State`]. + /// + /// [`Color`]: ../struct.Color.html + /// [`State`]: struct.State.html pub fn background_color(&self) -> Color { self.background_color } + /// Returns the current [`Viewport`] of the [`State`]. + /// + /// [`Viewport`]: ../struct.Viewport.html + /// [`State`]: struct.State.html pub fn viewport(&self) -> &Viewport { &self.viewport } + /// Returns the version of the [`Viewport`] of the [`State`]. + /// + /// The version is incremented every time the [`Viewport`] changes. + /// + /// [`Viewport`]: ../struct.Viewport.html + /// [`State`]: struct.State.html pub fn viewport_version(&self) -> usize { self.viewport_version } + /// Returns the physical [`Size`] of the [`Viewport`] of the [`State`]. + /// + /// [`Size`]: ../struct.Size.html + /// [`Viewport`]: ../struct.Viewport.html + /// [`State`]: struct.State.html pub fn physical_size(&self) -> Size { self.viewport.physical_size() } + /// Returns the logical [`Size`] of the [`Viewport`] of the [`State`]. + /// + /// [`Size`]: ../struct.Size.html + /// [`Viewport`]: ../struct.Viewport.html + /// [`State`]: struct.State.html pub fn logical_size(&self) -> Size { self.viewport.logical_size() } + /// Returns the current scale factor of the [`Viewport`] of the [`State`]. + /// + /// [`Viewport`]: ../struct.Viewport.html + /// [`State`]: struct.State.html pub fn scale_factor(&self) -> f64 { self.viewport.scale_factor() } + /// Returns the current cursor position of the [`State`]. + /// + /// [`State`]: struct.State.html pub fn cursor_position(&self) -> Point { conversion::cursor_position( self.cursor_position, @@ -79,10 +117,17 @@ impl State { ) } + /// Returns the current keyboard modifiers of the [`State`]. + /// + /// [`State`]: struct.State.html pub fn modifiers(&self) -> winit::event::ModifiersState { self.modifiers } + /// Processes the provided window event and updates the [`State`] + /// accordingly. + /// + /// [`State`]: struct.State.html pub fn update( &mut self, window: &Window, @@ -139,6 +184,15 @@ impl State { } } + /// Synchronizes the [`State`] with its [`Application`] and its respective + /// window. + /// + /// Normally an [`Application`] should be synchronized with its [`State`] + /// and window after calling [`Application::update`]. + /// + /// [`State`]: struct.State.html + /// [`Application`]: ../trait.Application.html + /// [`Application::update`]: ../trait.Application.html#tymethod.update pub fn synchronize(&mut self, application: &A, window: &Window) { // Update window title let new_title = application.title(); -- cgit