Merge pull request #151 from hecrj/feature/build-with-dimensions
Make layout bounds explicit in `UserInterface`
This commit is contained in:
commit
c72739e966
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user