diff options
author | 2022-07-27 06:49:20 +0200 | |
---|---|---|
committer | 2022-07-27 06:49:20 +0200 | |
commit | ff2519b1d43d481987351a83b6dd7237524c21f0 (patch) | |
tree | 5731eeb7eb1247d4a8951de0d5bc5d8102640559 /native/src/user_interface.rs | |
parent | c44267b85f7aaa2997e3caf1323b837d95818c22 (diff) | |
download | iced-ff2519b1d43d481987351a83b6dd7237524c21f0.tar.gz iced-ff2519b1d43d481987351a83b6dd7237524c21f0.tar.bz2 iced-ff2519b1d43d481987351a83b6dd7237524c21f0.zip |
Replace stateful widgets with new `iced_pure` API
Diffstat (limited to 'native/src/user_interface.rs')
-rw-r--r-- | native/src/user_interface.rs | 103 |
1 files changed, 63 insertions, 40 deletions
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index ef6f437e..9f3a8e21 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -4,6 +4,7 @@ use crate::event::{self, Event}; use crate::layout; use crate::mouse; use crate::renderer; +use crate::widget; use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size}; /// A set of interactive graphical elements with a specific [`Layout`]. @@ -22,6 +23,7 @@ use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size}; pub struct UserInterface<'a, Message, Renderer> { root: Element<'a, Message, Renderer>, base: layout::Node, + state: widget::Tree, overlay: Option<layout::Node>, bounds: Size, } @@ -88,7 +90,7 @@ where pub fn build<E: Into<Element<'a, Message, Renderer>>>( root: E, bounds: Size, - _cache: Cache, + cache: Cache, renderer: &mut Renderer, ) -> Self { let root = root.into(); @@ -96,9 +98,13 @@ where let base = renderer.layout(&root, &layout::Limits::new(Size::ZERO, bounds)); + let Cache { mut state } = cache; + state.diff(root.as_widget()); + UserInterface { root, base, + state, overlay: None, bounds, } @@ -182,9 +188,12 @@ where use std::mem::ManuallyDrop; let mut state = State::Updated; - let mut manual_overlay = ManuallyDrop::new( - self.root.overlay(Layout::new(&self.base), renderer), - ); + let mut manual_overlay = + ManuallyDrop::new(self.root.as_widget().overlay( + &mut self.state, + Layout::new(&self.base), + renderer, + )); let (base_cursor, overlay_statuses) = if manual_overlay.is_some() { let bounds = self.bounds; @@ -215,9 +224,12 @@ where &layout::Limits::new(Size::ZERO, self.bounds), ); - manual_overlay = ManuallyDrop::new( - self.root.overlay(Layout::new(&self.base), renderer), - ); + manual_overlay = + ManuallyDrop::new(self.root.as_widget().overlay( + &mut self.state, + Layout::new(&self.base), + renderer, + )); if manual_overlay.is_none() { break; @@ -262,7 +274,8 @@ where let mut shell = Shell::new(messages); - let event_status = self.root.widget.on_event( + let event_status = self.root.as_widget_mut().on_event( + &mut self.state, event, Layout::new(&self.base), base_cursor, @@ -377,9 +390,11 @@ where let viewport = Rectangle::with_size(self.bounds); - let base_cursor = if let Some(overlay) = - self.root.overlay(Layout::new(&self.base), renderer) - { + let base_cursor = if let Some(overlay) = self.root.as_widget().overlay( + &mut self.state, + Layout::new(&self.base), + renderer, + ) { let overlay_layout = self .overlay .take() @@ -399,7 +414,8 @@ where cursor_position }; - self.root.widget.draw( + self.root.as_widget().draw( + &self.state, renderer, theme, style, @@ -408,7 +424,8 @@ where &viewport, ); - let base_interaction = self.root.widget.mouse_interaction( + let base_interaction = self.root.as_widget().mouse_interaction( + &self.state, Layout::new(&self.base), cursor_position, &viewport, @@ -430,32 +447,34 @@ where overlay .as_ref() .and_then(|layout| { - root.overlay(Layout::new(base), renderer).map(|overlay| { - let overlay_interaction = overlay.mouse_interaction( - Layout::new(layout), - cursor_position, - &viewport, - renderer, - ); - - let overlay_bounds = layout.bounds(); - - renderer.with_layer(overlay_bounds, |renderer| { - overlay.draw( - renderer, - theme, - style, + root.as_widget() + .overlay(&mut self.state, Layout::new(base), renderer) + .map(|overlay| { + let overlay_interaction = overlay.mouse_interaction( Layout::new(layout), cursor_position, + &viewport, + renderer, ); - }); - if overlay_bounds.contains(cursor_position) { - overlay_interaction - } else { - base_interaction - } - }) + let overlay_bounds = layout.bounds(); + + renderer.with_layer(overlay_bounds, |renderer| { + overlay.draw( + renderer, + theme, + style, + Layout::new(layout), + cursor_position, + ); + }); + + if overlay_bounds.contains(cursor_position) { + overlay_interaction + } else { + base_interaction + } + }) }) .unwrap_or(base_interaction) } @@ -463,19 +482,21 @@ where /// Relayouts and returns a new [`UserInterface`] using the provided /// bounds. pub fn relayout(self, bounds: Size, renderer: &mut Renderer) -> Self { - Self::build(self.root, bounds, Cache, renderer) + Self::build(self.root, bounds, Cache { state: self.state }, renderer) } /// Extract the [`Cache`] of the [`UserInterface`], consuming it in the /// process. pub fn into_cache(self) -> Cache { - Cache + Cache { state: self.state } } } /// Reusable data of a specific [`UserInterface`]. -#[derive(Debug, Clone)] -pub struct Cache; +#[derive(Debug)] +pub struct Cache { + state: widget::Tree, +} impl Cache { /// Creates an empty [`Cache`]. @@ -483,7 +504,9 @@ impl Cache { /// You should use this to initialize a [`Cache`] before building your first /// [`UserInterface`]. pub fn new() -> Cache { - Cache + Cache { + state: widget::Tree::empty(), + } } } |