summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-01-11 13:47:43 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-01-11 13:47:43 +0700
commit6ab4611a6eec9c4bb4ca1ff1bb580bb7edf49add (patch)
treec96d3eb77ffe99a580ed13efecc50d2857f1b8f0 /native
parent90c20ac46b72b6d8f735f7efd283b9d1dfecfb9d (diff)
downloadiced-6ab4611a6eec9c4bb4ca1ff1bb580bb7edf49add.tar.gz
iced-6ab4611a6eec9c4bb4ca1ff1bb580bb7edf49add.tar.bz2
iced-6ab4611a6eec9c4bb4ca1ff1bb580bb7edf49add.zip
Invalidate widget tree from `Responsive` widget
... by introducing a new `invalidate_widgets` method to `Shell`
Diffstat (limited to 'native')
-rw-r--r--native/src/lib.rs4
-rw-r--r--native/src/program/state.rs12
-rw-r--r--native/src/shell.rs20
-rw-r--r--native/src/user_interface.rs45
-rw-r--r--native/src/widget/responsive.rs4
5 files changed, 63 insertions, 22 deletions
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 4211995f..c527a69a 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -50,6 +50,7 @@ pub mod subscription;
pub mod svg;
pub mod text;
pub mod touch;
+pub mod user_interface;
pub mod widget;
pub mod window;
@@ -57,7 +58,6 @@ mod element;
mod hasher;
mod runtime;
mod shell;
-mod user_interface;
// We disable debug capabilities on release builds unless the `debug` feature
// is explicitly enabled.
@@ -91,5 +91,5 @@ pub use renderer::Renderer;
pub use runtime::Runtime;
pub use shell::Shell;
pub use subscription::Subscription;
-pub use user_interface::{Cache, UserInterface};
+pub use user_interface::UserInterface;
pub use widget::Widget;
diff --git a/native/src/program/state.rs b/native/src/program/state.rs
index 26c0eb21..cb87a628 100644
--- a/native/src/program/state.rs
+++ b/native/src/program/state.rs
@@ -1,8 +1,6 @@
use crate::mouse;
-use crate::{
- Cache, Clipboard, Command, Debug, Event, Point, Program, Size,
- UserInterface,
-};
+use crate::user_interface::{self, UserInterface};
+use crate::{Clipboard, Command, Debug, Event, Point, Program, Size};
/// The execution state of a [`Program`]. It leverages caching, event
/// processing, and rendering primitive storage.
@@ -12,7 +10,7 @@ where
P: Program + 'static,
{
program: P,
- cache: Option<Cache>,
+ cache: Option<user_interface::Cache>,
queued_events: Vec<Event>,
queued_messages: Vec<P::Message>,
mouse_interaction: mouse::Interaction,
@@ -32,7 +30,7 @@ where
) -> Self {
let user_interface = build_user_interface(
&mut program,
- Cache::default(),
+ user_interface::Cache::default(),
renderer,
bounds,
debug,
@@ -161,7 +159,7 @@ where
fn build_user_interface<'a, P: Program>(
program: &'a mut P,
- cache: Cache,
+ cache: user_interface::Cache,
renderer: &mut P::Renderer,
size: Size,
debug: &mut Debug,
diff --git a/native/src/shell.rs b/native/src/shell.rs
index e916f52d..4a0aa9c6 100644
--- a/native/src/shell.rs
+++ b/native/src/shell.rs
@@ -8,6 +8,7 @@
pub struct Shell<'a, Message> {
messages: &'a mut Vec<Message>,
is_layout_invalid: bool,
+ are_widgets_invalid: bool,
}
impl<'a, Message> Shell<'a, Message> {
@@ -16,12 +17,13 @@ impl<'a, Message> Shell<'a, Message> {
Self {
messages,
is_layout_invalid: false,
+ are_widgets_invalid: false,
}
}
/// Triggers the given function if the layout is invalid, cleaning it in the
/// process.
- pub fn with_invalid_layout(&mut self, f: impl FnOnce()) {
+ pub fn revalidate_layout(&mut self, f: impl FnOnce()) {
if self.is_layout_invalid {
self.is_layout_invalid = false;
@@ -41,6 +43,13 @@ impl<'a, Message> Shell<'a, Message> {
self.is_layout_invalid = true;
}
+ /// Invalidates the current application widgets.
+ ///
+ /// The shell will rebuild and relayout the widget tree.
+ pub fn invalidate_widgets(&mut self) {
+ self.are_widgets_invalid = true;
+ }
+
/// Merges the current [`Shell`] with another one by applying the given
/// function to the messages of the latter.
///
@@ -50,5 +59,14 @@ impl<'a, Message> Shell<'a, Message> {
self.is_layout_invalid =
self.is_layout_invalid || other.is_layout_invalid;
+
+ self.are_widgets_invalid =
+ self.are_widgets_invalid || other.are_widgets_invalid;
+ }
+
+ /// Returns whether the widgets of the current application have been
+ /// invalidated.
+ pub fn are_widgets_invalid(&self) -> bool {
+ self.are_widgets_invalid
}
}
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index 40f7a204..1c78b754 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -42,7 +42,8 @@ where
/// is naive way to set up our application loop:
///
/// ```no_run
- /// use iced_native::{UserInterface, Cache, Size};
+ /// use iced_native::Size;
+ /// use iced_native::user_interface::{self, UserInterface};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -61,7 +62,7 @@ where
/// # }
/// // Initialization
/// let mut counter = Counter::new();
- /// let mut cache = Cache::new();
+ /// let mut cache = user_interface::Cache::new();
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
///
@@ -136,7 +137,8 @@ where
/// completing [the previous example](#example):
///
/// ```no_run
- /// use iced_native::{clipboard, UserInterface, Cache, Size, Point};
+ /// use iced_native::{clipboard, Size, Point};
+ /// use iced_native::user_interface::{self, UserInterface};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -155,7 +157,7 @@ where
/// # pub fn update(&mut self, message: ()) {}
/// # }
/// let mut counter = Counter::new();
- /// let mut cache = Cache::new();
+ /// let mut cache = user_interface::Cache::new();
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// let mut cursor_position = Point::default();
@@ -176,7 +178,7 @@ where
/// );
///
/// // Update the user interface
- /// let event_statuses = user_interface.update(
+ /// let (state, event_statuses) = user_interface.update(
/// &events,
/// cursor_position,
/// &mut renderer,
@@ -199,7 +201,9 @@ where
renderer: &mut Renderer,
clipboard: &mut dyn Clipboard,
messages: &mut Vec<Message>,
- ) -> Vec<event::Status> {
+ ) -> (State, Vec<event::Status>) {
+ let mut state = State::Updated;
+
let (base_cursor, overlay_statuses) = if let Some(mut overlay) =
self.root.overlay(Layout::new(&self.base.layout))
{
@@ -227,7 +231,7 @@ where
&mut shell,
);
- shell.with_invalid_layout(|| {
+ shell.revalidate_layout(|| {
layer = Self::overlay_layer(
None,
bounds,
@@ -236,6 +240,10 @@ where
);
});
+ if shell.are_widgets_invalid() {
+ state = State::Outdated;
+ }
+
event_status
})
.collect();
@@ -255,7 +263,7 @@ where
(cursor_position, vec![event::Status::Ignored; events.len()])
};
- events
+ let event_statuses = events
.iter()
.cloned()
.zip(overlay_statuses.into_iter())
@@ -271,7 +279,7 @@ where
&mut shell,
);
- shell.with_invalid_layout(|| {
+ shell.revalidate_layout(|| {
let hash = {
let hasher = &mut crate::Hasher::default();
self.root.hash_layout(hasher);
@@ -288,9 +296,15 @@ where
self.overlay = None;
});
+ if shell.are_widgets_invalid() {
+ state = State::Outdated;
+ }
+
event_status.merge(overlay_status)
})
- .collect()
+ .collect();
+
+ (state, event_statuses)
}
/// Draws the [`UserInterface`] with the provided [`Renderer`].
@@ -306,7 +320,8 @@ where
/// [completing the last example](#example-1):
///
/// ```no_run
- /// use iced_native::{clipboard, UserInterface, Cache, Size, Point};
+ /// use iced_native::{clipboard, Size, Point};
+ /// use iced_native::user_interface::{self, UserInterface};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -325,7 +340,7 @@ where
/// # pub fn update(&mut self, message: ()) {}
/// # }
/// let mut counter = Counter::new();
- /// let mut cache = Cache::new();
+ /// let mut cache = user_interface::Cache::new();
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// let mut cursor_position = Point::default();
@@ -548,3 +563,9 @@ impl Default for Cache {
Cache::new()
}
}
+
+#[derive(Debug, Clone, Copy)]
+pub enum State {
+ Outdated,
+ Updated,
+}
diff --git a/native/src/widget/responsive.rs b/native/src/widget/responsive.rs
index 0cb85d45..becaa980 100644
--- a/native/src/widget/responsive.rs
+++ b/native/src/widget/responsive.rs
@@ -80,6 +80,10 @@ where
let Internal { content, state } = internal.deref_mut();
+ if state.last_size != Some(state.last_layout.size()) {
+ shell.invalidate_widgets();
+ }
+
let content = content.resolve(state, renderer);
let content_layout = Layout::with_offset(