summaryrefslogtreecommitdiffstats
path: root/native/src/user_interface.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-07-27 06:49:20 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-07-27 06:49:20 +0200
commitff2519b1d43d481987351a83b6dd7237524c21f0 (patch)
tree5731eeb7eb1247d4a8951de0d5bc5d8102640559 /native/src/user_interface.rs
parentc44267b85f7aaa2997e3caf1323b837d95818c22 (diff)
downloadiced-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.rs103
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(),
+ }
}
}