diff options
Diffstat (limited to '')
| -rw-r--r-- | native/src/lib.rs | 4 | ||||
| -rw-r--r-- | native/src/program/state.rs | 12 | ||||
| -rw-r--r-- | native/src/shell.rs | 20 | ||||
| -rw-r--r-- | native/src/user_interface.rs | 45 | ||||
| -rw-r--r-- | native/src/widget/responsive.rs | 4 | 
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( | 
