Merge pull request #151 from hecrj/feature/build-with-dimensions

Make layout bounds explicit in `UserInterface`
This commit is contained in:
Héctor Ramón 2020-01-10 19:11:24 +01:00 committed by GitHub
commit c72739e966
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 45 deletions

View File

@ -52,7 +52,8 @@ pub trait Renderer: Sized {
fn layout<'a, Message>( fn layout<'a, Message>(
&mut self, &mut self,
element: &Element<'a, Message, Self>, element: &Element<'a, Message, Self>,
limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
element.layout(self, &layout::Limits::NONE) element.layout(self, limits)
} }
} }

View File

@ -17,6 +17,7 @@ pub struct UserInterface<'a, Message, Renderer> {
hash: u64, hash: u64,
root: Element<'a, Message, Renderer>, root: Element<'a, Message, Renderer>,
layout: layout::Node, layout: layout::Node,
bounds: Size,
cursor_position: Point, cursor_position: Point,
} }
@ -39,7 +40,7 @@ where
/// is naive way to set up our application loop: /// is naive way to set up our application loop:
/// ///
/// ```no_run /// ```no_run
/// use iced_native::{UserInterface, Cache}; /// use iced_native::{UserInterface, Cache, Size};
/// use iced_wgpu::Renderer; /// use iced_wgpu::Renderer;
/// ///
/// # mod iced_wgpu { /// # mod iced_wgpu {
@ -60,6 +61,7 @@ where
/// let mut counter = Counter::new(); /// let mut counter = Counter::new();
/// let mut cache = Cache::new(); /// let mut cache = Cache::new();
/// let mut renderer = Renderer::new(); /// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// ///
/// // Application loop /// // Application loop
/// loop { /// loop {
@ -68,6 +70,7 @@ where
/// // Build the user interface /// // Build the user interface
/// let user_interface = UserInterface::build( /// let user_interface = UserInterface::build(
/// counter.view(), /// counter.view(),
/// window_size,
/// cache, /// cache,
/// &mut renderer, /// &mut renderer,
/// ); /// );
@ -81,26 +84,30 @@ where
/// ``` /// ```
pub fn build<E: Into<Element<'a, Message, Renderer>>>( pub fn build<E: Into<Element<'a, Message, Renderer>>>(
root: E, root: E,
bounds: Size,
cache: Cache, cache: Cache,
renderer: &mut Renderer, renderer: &mut Renderer,
) -> Self { ) -> Self {
let root = root.into(); let root = root.into();
let hasher = &mut crate::Hasher::default(); let hash = {
root.hash_layout(hasher); 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 cache.layout
} else { } else {
renderer.layout(&root) renderer.layout(&root, &layout::Limits::new(Size::ZERO, bounds))
}; };
UserInterface { UserInterface {
hash, hash,
root, root,
layout, layout,
bounds,
cursor_position: cache.cursor_position, cursor_position: cache.cursor_position,
} }
} }
@ -118,7 +125,7 @@ where
/// completing [the previous example](#example): /// completing [the previous example](#example):
/// ///
/// ```no_run /// ```no_run
/// use iced_native::{UserInterface, Cache}; /// use iced_native::{UserInterface, Cache, Size};
/// use iced_wgpu::Renderer; /// use iced_wgpu::Renderer;
/// ///
/// # mod iced_wgpu { /// # mod iced_wgpu {
@ -139,6 +146,7 @@ where
/// let mut counter = Counter::new(); /// let mut counter = Counter::new();
/// let mut cache = Cache::new(); /// let mut cache = Cache::new();
/// let mut renderer = Renderer::new(); /// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// ///
/// // Initialize our event storage /// // Initialize our event storage
/// let mut events = Vec::new(); /// let mut events = Vec::new();
@ -148,6 +156,7 @@ where
/// ///
/// let mut user_interface = UserInterface::build( /// let mut user_interface = UserInterface::build(
/// counter.view(), /// counter.view(),
/// window_size,
/// cache, /// cache,
/// &mut renderer, /// &mut renderer,
/// ); /// );
@ -203,7 +212,7 @@ where
/// [completing the last example](#example-1): /// [completing the last example](#example-1):
/// ///
/// ```no_run /// ```no_run
/// use iced_native::{UserInterface, Cache}; /// use iced_native::{UserInterface, Cache, Size};
/// use iced_wgpu::Renderer; /// use iced_wgpu::Renderer;
/// ///
/// # mod iced_wgpu { /// # mod iced_wgpu {
@ -224,6 +233,7 @@ where
/// let mut counter = Counter::new(); /// let mut counter = Counter::new();
/// let mut cache = Cache::new(); /// let mut cache = Cache::new();
/// let mut renderer = Renderer::new(); /// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// let mut events = Vec::new(); /// let mut events = Vec::new();
/// ///
/// loop { /// loop {
@ -231,6 +241,7 @@ where
/// ///
/// let mut user_interface = UserInterface::build( /// let mut user_interface = UserInterface::build(
/// counter.view(), /// counter.view(),
/// window_size,
/// cache, /// cache,
/// &mut renderer, /// &mut renderer,
/// ); /// );
@ -268,6 +279,7 @@ where
Cache { Cache {
hash: self.hash, hash: self.hash,
layout: self.layout, layout: self.layout,
bounds: self.bounds,
cursor_position: self.cursor_position, cursor_position: self.cursor_position,
} }
} }
@ -280,6 +292,7 @@ where
pub struct Cache { pub struct Cache {
hash: u64, hash: u64,
layout: layout::Node, layout: layout::Node,
bounds: Size,
cursor_position: Point, cursor_position: Point,
} }
@ -295,6 +308,7 @@ impl Cache {
Cache { Cache {
hash: 0, hash: 0,
layout: layout::Node::new(Size::new(0.0, 0.0)), layout: layout::Node::new(Size::new(0.0, 0.0)),
bounds: Size::ZERO,
cursor_position: Point::new(-1.0, -1.0), cursor_position: Point::new(-1.0, -1.0),
} }
} }

View File

@ -445,8 +445,9 @@ impl iced_native::Renderer for Renderer {
fn layout<'a, Message>( fn layout<'a, Message>(
&mut self, &mut self,
element: &iced_native::Element<'a, Message, Self>, element: &iced_native::Element<'a, Message, Self>,
limits: &iced_native::layout::Limits,
) -> iced_native::layout::Node { ) -> 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(); self.text_pipeline.clear_measurement_cache();

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
container, conversion, conversion,
input::{keyboard, mouse}, input::{keyboard, mouse},
subscription, window, Cache, Clipboard, Command, Container, Debug, Element, subscription, window, Cache, Clipboard, Command, Debug, Element, Event,
Event, Length, MouseCursor, Settings, Subscription, UserInterface, MouseCursor, Settings, Size, Subscription, UserInterface,
}; };
/// An interactive, native cross-platform application. /// An interactive, native cross-platform application.
@ -17,7 +17,7 @@ pub trait Application: Sized {
/// The renderer to use to draw the [`Application`]. /// The renderer to use to draw the [`Application`].
/// ///
/// [`Application`]: trait.Application.html /// [`Application`]: trait.Application.html
type Renderer: window::Renderer + container::Renderer; type Renderer: window::Renderer;
/// The type of __messages__ your [`Application`] will produce. /// The type of __messages__ your [`Application`] will produce.
/// ///
@ -152,13 +152,13 @@ pub trait Application: Sized {
) )
}; };
debug.layout_started(); let user_interface = build_user_interface(
let user_interface = UserInterface::build( &mut application,
document(&mut application, size, &mut debug),
Cache::default(), Cache::default(),
&mut renderer, &mut renderer,
size,
&mut debug,
); );
debug.layout_finished();
debug.draw_started(); debug.draw_started();
let mut primitive = user_interface.draw(&mut renderer); 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 // This will allow us to rebuild it only when a message is
// handled. // handled.
debug.layout_started(); let mut user_interface = build_user_interface(
let mut user_interface = UserInterface::build( &mut application,
document(&mut application, size, &mut debug),
cache.take().unwrap(), cache.take().unwrap(),
&mut renderer, &mut renderer,
size,
&mut debug,
); );
debug.layout_finished();
debug.event_processing_started(); debug.event_processing_started();
events.iter().for_each(|event| { events.iter().for_each(|event| {
@ -244,13 +244,13 @@ pub trait Application: Sized {
title = new_title; title = new_title;
} }
debug.layout_started(); let user_interface = build_user_interface(
let user_interface = UserInterface::build( &mut application,
document(&mut application, size, &mut debug),
temp_cache, temp_cache,
&mut renderer, &mut renderer,
size,
&mut debug,
); );
debug.layout_finished();
debug.draw_started(); debug.draw_started();
primitive = user_interface.draw(&mut renderer); 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) { fn to_physical(size: winit::dpi::LogicalSize, dpi: f64) -> (u16, u16) {
let physical_size = size.to_physical(dpi); 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<Message: Send>( fn spawn<Message: Send>(
command: Command<Message>, command: Command<Message>,
thread_pool: &mut futures::executor::ThreadPool, thread_pool: &mut futures::executor::ThreadPool,