From e6aa25a1032f583ced7f6f02806991ffb4cde140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 10 Jan 2020 03:10:58 +0100 Subject: [PATCH] Make layout bounds explicit in `UserInterface` --- native/src/renderer.rs | 3 +- native/src/user_interface.rs | 30 +++++++++++---- wgpu/src/renderer.rs | 3 +- winit/src/application.rs | 74 +++++++++++++++++++----------------- 4 files changed, 65 insertions(+), 45 deletions(-) diff --git a/native/src/renderer.rs b/native/src/renderer.rs index ff90fdd9..a16df72b 100644 --- a/native/src/renderer.rs +++ b/native/src/renderer.rs @@ -52,7 +52,8 @@ pub trait Renderer: Sized { fn layout<'a, Message>( &mut self, element: &Element<'a, Message, Self>, + limits: &layout::Limits, ) -> layout::Node { - element.layout(self, &layout::Limits::NONE) + element.layout(self, limits) } } diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 970bf0c1..85b25bc7 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -17,6 +17,7 @@ pub struct UserInterface<'a, Message, Renderer> { hash: u64, root: Element<'a, Message, Renderer>, layout: layout::Node, + bounds: Size, cursor_position: Point, } @@ -39,7 +40,7 @@ where /// is naive way to set up our application loop: /// /// ```no_run - /// use iced_native::{UserInterface, Cache}; + /// use iced_native::{UserInterface, Cache, Size}; /// use iced_wgpu::Renderer; /// /// # mod iced_wgpu { @@ -60,6 +61,7 @@ where /// let mut counter = Counter::new(); /// let mut cache = Cache::new(); /// let mut renderer = Renderer::new(); + /// let mut window_size = Size::new(1024.0, 768.0); /// /// // Application loop /// loop { @@ -68,6 +70,7 @@ where /// // Build the user interface /// let user_interface = UserInterface::build( /// counter.view(), + /// window_size, /// cache, /// &mut renderer, /// ); @@ -81,26 +84,30 @@ where /// ``` pub fn build>>( root: E, + bounds: Size, cache: Cache, renderer: &mut Renderer, ) -> Self { let root = root.into(); - let hasher = &mut crate::Hasher::default(); - root.hash_layout(hasher); + let hash = { + let hasher = &mut crate::Hasher::default(); + root.hash_layout(hasher); - let hash = hasher.finish(); + hasher.finish() + }; - let layout = if hash == cache.hash { + let layout = if hash == cache.hash && bounds == cache.bounds { cache.layout } else { - renderer.layout(&root) + renderer.layout(&root, &layout::Limits::new(Size::ZERO, bounds)) }; UserInterface { hash, root, layout, + bounds, cursor_position: cache.cursor_position, } } @@ -118,7 +125,7 @@ where /// completing [the previous example](#example): /// /// ```no_run - /// use iced_native::{UserInterface, Cache}; + /// use iced_native::{UserInterface, Cache, Size}; /// use iced_wgpu::Renderer; /// /// # mod iced_wgpu { @@ -139,6 +146,7 @@ where /// let mut counter = Counter::new(); /// let mut cache = Cache::new(); /// let mut renderer = Renderer::new(); + /// let mut window_size = Size::new(1024.0, 768.0); /// /// // Initialize our event storage /// let mut events = Vec::new(); @@ -148,6 +156,7 @@ where /// /// let mut user_interface = UserInterface::build( /// counter.view(), + /// window_size, /// cache, /// &mut renderer, /// ); @@ -203,7 +212,7 @@ where /// [completing the last example](#example-1): /// /// ```no_run - /// use iced_native::{UserInterface, Cache}; + /// use iced_native::{UserInterface, Cache, Size}; /// use iced_wgpu::Renderer; /// /// # mod iced_wgpu { @@ -224,6 +233,7 @@ where /// let mut counter = Counter::new(); /// let mut cache = Cache::new(); /// let mut renderer = Renderer::new(); + /// let mut window_size = Size::new(1024.0, 768.0); /// let mut events = Vec::new(); /// /// loop { @@ -231,6 +241,7 @@ where /// /// let mut user_interface = UserInterface::build( /// counter.view(), + /// window_size, /// cache, /// &mut renderer, /// ); @@ -268,6 +279,7 @@ where Cache { hash: self.hash, layout: self.layout, + bounds: self.bounds, cursor_position: self.cursor_position, } } @@ -280,6 +292,7 @@ where pub struct Cache { hash: u64, layout: layout::Node, + bounds: Size, cursor_position: Point, } @@ -295,6 +308,7 @@ impl Cache { Cache { hash: 0, layout: layout::Node::new(Size::new(0.0, 0.0)), + bounds: Size::ZERO, cursor_position: Point::new(-1.0, -1.0), } } diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 56fe45af..6f35e247 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -445,8 +445,9 @@ impl iced_native::Renderer for Renderer { fn layout<'a, Message>( &mut self, element: &iced_native::Element<'a, Message, Self>, + limits: &iced_native::layout::Limits, ) -> iced_native::layout::Node { - let node = element.layout(self, &iced_native::layout::Limits::NONE); + let node = element.layout(self, limits); self.text_pipeline.clear_measurement_cache(); diff --git a/winit/src/application.rs b/winit/src/application.rs index 10c5a7ac..a712632e 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1,8 +1,8 @@ use crate::{ - container, conversion, + conversion, input::{keyboard, mouse}, - subscription, window, Cache, Clipboard, Command, Container, Debug, Element, - Event, Length, MouseCursor, Settings, Subscription, UserInterface, + subscription, window, Cache, Clipboard, Command, Debug, Element, Event, + MouseCursor, Settings, Size, Subscription, UserInterface, }; /// An interactive, native cross-platform application. @@ -17,7 +17,7 @@ pub trait Application: Sized { /// The renderer to use to draw the [`Application`]. /// /// [`Application`]: trait.Application.html - type Renderer: window::Renderer + container::Renderer; + type Renderer: window::Renderer; /// The type of __messages__ your [`Application`] will produce. /// @@ -152,13 +152,13 @@ pub trait Application: Sized { ) }; - debug.layout_started(); - let user_interface = UserInterface::build( - document(&mut application, size, &mut debug), + let user_interface = build_user_interface( + &mut application, Cache::default(), &mut renderer, + size, + &mut debug, ); - debug.layout_finished(); debug.draw_started(); let mut primitive = user_interface.draw(&mut renderer); @@ -183,13 +183,13 @@ pub trait Application: Sized { // // This will allow us to rebuild it only when a message is // handled. - debug.layout_started(); - let mut user_interface = UserInterface::build( - document(&mut application, size, &mut debug), + let mut user_interface = build_user_interface( + &mut application, cache.take().unwrap(), &mut renderer, + size, + &mut debug, ); - debug.layout_finished(); debug.event_processing_started(); events.iter().for_each(|event| { @@ -244,13 +244,13 @@ pub trait Application: Sized { title = new_title; } - debug.layout_started(); - let user_interface = UserInterface::build( - document(&mut application, size, &mut debug), + let user_interface = build_user_interface( + &mut application, temp_cache, &mut renderer, + size, + &mut debug, ); - debug.layout_finished(); debug.draw_started(); primitive = user_interface.draw(&mut renderer); @@ -390,6 +390,29 @@ pub trait Application: Sized { } } +fn build_user_interface<'a, A: Application>( + application: &'a mut A, + cache: Cache, + renderer: &mut A::Renderer, + size: winit::dpi::LogicalSize, + debug: &mut Debug, +) -> UserInterface<'a, A::Message, A::Renderer> { + debug.view_started(); + let view = application.view(); + debug.view_finished(); + + debug.layout_started(); + let user_interface = UserInterface::build( + view, + Size::new(size.width.round() as f32, size.height.round() as f32), + cache, + renderer, + ); + debug.layout_finished(); + + user_interface +} + fn to_physical(size: winit::dpi::LogicalSize, dpi: f64) -> (u16, u16) { let physical_size = size.to_physical(dpi); @@ -399,25 +422,6 @@ fn to_physical(size: winit::dpi::LogicalSize, dpi: f64) -> (u16, u16) { ) } -fn document<'a, Application>( - application: &'a mut Application, - size: winit::dpi::LogicalSize, - debug: &mut Debug, -) -> Element<'a, Application::Message, Application::Renderer> -where - Application: self::Application, - Application::Message: 'static, -{ - debug.view_started(); - let view = application.view(); - debug.view_finished(); - - Container::new(view) - .width(Length::Units(size.width.round() as u16)) - .height(Length::Units(size.height.round() as u16)) - .into() -} - fn spawn( command: Command, thread_pool: &mut futures::executor::ThreadPool,