diff options
author | 2020-04-16 13:22:00 +0200 | |
---|---|---|
committer | 2020-07-08 10:41:16 +0200 | |
commit | f064f0482b653a1fbee4afbddcecf91e3a399004 (patch) | |
tree | 2a468e4dc80be13cbf0ae7dd703607010e16697c /native/src/user_interface.rs | |
parent | c901f40fd6c5aa39f4dc056b2b59bc7133b287e6 (diff) | |
download | iced-f064f0482b653a1fbee4afbddcecf91e3a399004.tar.gz iced-f064f0482b653a1fbee4afbddcecf91e3a399004.tar.bz2 iced-f064f0482b653a1fbee4afbddcecf91e3a399004.zip |
Introduce `Layer` trait
Diffstat (limited to 'native/src/user_interface.rs')
-rw-r--r-- | native/src/user_interface.rs | 149 |
1 files changed, 115 insertions, 34 deletions
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index b9646043..6758bce3 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -1,4 +1,4 @@ -use crate::{layout, Clipboard, Element, Event, Layout, Point, Size}; +use crate::{layout, Clipboard, Element, Event, Layout, Overlay, Point, Size}; use std::hash::Hasher; @@ -19,12 +19,17 @@ use std::hash::Hasher; /// [`UserInterface`]: struct.UserInterface.html #[allow(missing_debug_implementations)] pub struct UserInterface<'a, Message, Renderer> { - hash: u64, - root: Element<'a, Message, Renderer>, - layout: layout::Node, + base: Layer<Element<'a, Message, Renderer>>, + overlay: Option<Layer<Overlay<'a, Message, Renderer>>>, bounds: Size, } +struct Layer<T> { + root: T, + layout: layout::Node, + hash: u64, +} + impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> where Renderer: crate::Renderer, @@ -92,27 +97,45 @@ where cache: Cache, renderer: &mut Renderer, ) -> Self { - let root = root.into(); + let mut root = root.into(); - let hash = { - let hasher = &mut crate::Hasher::default(); - root.hash_layout(hasher); + let (base, overlay) = { + let hash = { + let hasher = &mut crate::Hasher::default(); + root.hash_layout(hasher); - hasher.finish() - }; + hasher.finish() + }; - let layout_is_cached = hash == cache.hash && bounds == cache.bounds; + let layout_is_cached = hash == cache.hash && bounds == cache.bounds; - let layout = if layout_is_cached { - cache.layout - } else { - renderer.layout(&root, &layout::Limits::new(Size::ZERO, bounds)) + let layout = if layout_is_cached { + cache.layout + } else { + renderer.layout(&root, &layout::Limits::new(Size::ZERO, bounds)) + }; + + let overlay = root.overlay(Layout::new(&layout)); + + (Layer { root, layout, hash }, overlay) }; + let overlay = overlay.map(|root| { + let hash = { + let hasher = &mut crate::Hasher::default(); + root.hash_layout(hasher); + + hasher.finish() + }; + + let layout = root.layout(&renderer, bounds); + + Layer { root, layout, hash } + }); + UserInterface { - hash, - root, - layout, + base, + overlay, bounds, } } @@ -193,14 +216,42 @@ where let mut messages = Vec::new(); for event in events { - self.root.widget.on_event( - event, - Layout::new(&self.layout), - cursor_position, - &mut messages, - renderer, - clipboard, - ); + if let Some(overlay) = &mut self.overlay { + overlay.root.on_event( + event.clone(), + Layout::new(&overlay.layout), + cursor_position, + &mut messages, + renderer, + clipboard, + ); + + let base_cursor = + if overlay.layout.bounds().contains(cursor_position) { + // TODO: Encode cursor availability + Point::new(-1.0, -1.0) + } else { + cursor_position + }; + + self.base.root.widget.on_event( + event, + Layout::new(&self.base.layout), + base_cursor, + &mut messages, + renderer, + clipboard, + ); + } else { + self.base.root.widget.on_event( + event, + Layout::new(&self.base.layout), + cursor_position, + &mut messages, + renderer, + clipboard, + ); + } } messages @@ -280,12 +331,42 @@ where renderer: &mut Renderer, cursor_position: Point, ) -> Renderer::Output { - self.root.widget.draw( - renderer, - &Renderer::Defaults::default(), - Layout::new(&self.layout), - cursor_position, - ) + if let Some(overlay) = &self.overlay { + let overlay_bounds = overlay.layout.bounds(); + + let base_cursor = if overlay_bounds.contains(cursor_position) { + Point::new(-1.0, -1.0) + } else { + cursor_position + }; + + let base_primitives = self.base.root.widget.draw( + renderer, + &Renderer::Defaults::default(), + Layout::new(&self.base.layout), + base_cursor, + ); + + let overlay_primitives = overlay.root.draw( + renderer, + &Renderer::Defaults::default(), + Layout::new(&overlay.layout), + cursor_position, + ); + + renderer.overlay( + base_primitives, + overlay_primitives, + overlay_bounds, + ) + } else { + self.base.root.widget.draw( + renderer, + &Renderer::Defaults::default(), + Layout::new(&self.base.layout), + cursor_position, + ) + } } /// Extract the [`Cache`] of the [`UserInterface`], consuming it in the @@ -295,8 +376,8 @@ where /// [`UserInterface`]: struct.UserInterface.html pub fn into_cache(self) -> Cache { Cache { - hash: self.hash, - layout: self.layout, + hash: self.base.hash, + layout: self.base.layout, bounds: self.bounds, } } |