diff options
Diffstat (limited to '')
| -rw-r--r-- | examples/ggez/main.rs | 4 | ||||
| -rw-r--r-- | src/element.rs | 10 | ||||
| -rw-r--r-- | src/layout.rs | 2 | ||||
| -rw-r--r-- | src/user_interface.rs | 208 | ||||
| -rw-r--r-- | src/widget.rs | 4 | 
5 files changed, 214 insertions, 14 deletions
| diff --git a/examples/ggez/main.rs b/examples/ggez/main.rs index ad9051ff..329bde81 100644 --- a/examples/ggez/main.rs +++ b/examples/ggez/main.rs @@ -144,9 +144,9 @@ impl event::EventHandler for Game {                  &mut Renderer::new(context, self.spritesheet.clone());              let mut ui = iced::UserInterface::build( -                content.into(), -                renderer, +                content,                  self.cache.take().unwrap(), +                renderer,              );              let messages = ui.update(self.events.drain(..)); diff --git a/src/element.rs b/src/element.rs index 6bc0ad74..ca9d420b 100644 --- a/src/element.rs +++ b/src/element.rs @@ -4,10 +4,14 @@ use crate::{Event, Hasher, Layout, MouseCursor, Node, Point, Widget};  /// A generic [`Widget`].  /// -/// If you have a widget, you should be able to use `widget.into()` to turn it -/// into an [`Element`]. +/// It is useful to build composable user interfaces that do not leak +/// implementation details in their __view logic__.  /// -/// [`Widget`]: trait.Widget.html +/// If you have a [built-in widget], you should be able to use `Into<Element>` +/// to turn it into an [`Element`]. +/// +/// [built-in widget]: widget/index.html#built-in-widgets +/// [`Widget`]: widget/trait.Widget.html  /// [`Element`]: struct.Element.html  pub struct Element<'a, Message, Renderer> {      pub(crate) widget: Box<dyn Widget<Message, Renderer> + 'a>, diff --git a/src/layout.rs b/src/layout.rs index 481b4166..78c7f947 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -5,7 +5,7 @@ use crate::{Point, Rectangle, Vector};  /// The computed bounds of a [`Node`] and its children.  ///  /// This type is provided by the GUI runtime to [`Widget::on_event`] and -/// [`Widget::draw`], describing the layout of the produced [`Node`] by +/// [`Widget::draw`], describing the layout of the [`Node`] produced by  /// [`Widget::node`].  ///  /// [`Node`]: struct.Node.html diff --git a/src/user_interface.rs b/src/user_interface.rs index cb8d05ae..f64fe74b 100644 --- a/src/user_interface.rs +++ b/src/user_interface.rs @@ -3,7 +3,14 @@ use crate::{input::mouse, Column, Element, Event, Layout, MouseCursor, Point};  use std::hash::Hasher;  use stretch::result; -/// A set of interactive graphical elements with a specific layout. +/// A set of interactive graphical elements with a specific [`Layout`]. +/// +/// Use this to build, update, and draw your GUI! +/// +/// Iced tries to avoid dictating how to write your event loop. You are in +/// charge of integrating Iced in your system in any way you want. +/// +/// [`Layout`]: struct.Layout.html  pub struct UserInterface<'a, Message, Renderer> {      hash: u64,      root: Element<'a, Message, Renderer>, @@ -12,11 +19,72 @@ pub struct UserInterface<'a, Message, Renderer> {  }  impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> { -    pub fn build( -        root: Element<'a, Message, Renderer>, -        renderer: &Renderer, +    /// Builds a user interface for an [`Element`]. +    /// +    /// It is able to avoid expensive computations when using a [`Cache`] +    /// obtained from a previous instance of a [`UserInterface`]. +    /// +    /// [`Element`]: struct.Element.html +    /// [`Cache`]: struct.Cache.html +    /// [`UserInterface`]: struct.UserInterface.html +    /// +    /// # Example +    /// Imagine we want to build a [`UserInterface`] for +    /// [the counter example that we previously wrote](index.html#usage). Here +    /// is how we could build our GUI application indefinitely: +    /// +    /// ```no_run +    /// use iced::{UserInterface, Cache}; +    /// use iced_wgpu::Renderer; +    /// +    /// # mod iced_wgpu { +    /// #     pub struct Renderer; +    /// # +    /// #     impl Renderer { +    /// #         pub fn new() -> Self { Renderer } +    /// #     } +    /// # } +    /// # +    /// # use iced::Column; +    /// # +    /// # pub struct Counter; +    /// # +    /// # impl Counter { +    /// #     pub fn new() -> Self { Counter } +    /// #     pub fn view(&self) -> Column<(), Renderer> { +    /// #         Column::new() +    /// #     } +    /// # } +    /// // Initialization +    /// let mut counter = Counter::new(); +    /// let mut cache = Cache::new(); +    /// let mut renderer = Renderer::new(); +    /// +    /// // Application loop +    /// loop { +    ///     // Process system events here... +    /// +    ///     // Build the user interface +    ///     let user_interface = UserInterface::build( +    ///         counter.view(), +    ///         cache, +    ///         &renderer, +    ///     ); +    /// +    ///     // Update and draw the user interface here... +    ///     // ... +    /// +    ///     // Obtain the cache for the next iteration +    ///     cache = user_interface.into_cache(); +    /// } +    /// ``` +    pub fn build<E: Into<Element<'a, Message, Renderer>>>( +        root: E,          cache: Cache, +        renderer: &Renderer,      ) -> Self { +        let root = root.into(); +          let hasher = &mut crate::Hasher::default();          root.hash(hasher); @@ -36,6 +104,68 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {          }      } +    /// Updates the [`UserInterface`] by processing each provided [`Event`]. +    /// +    /// It returns __messages__ that may have been produced as a result of user +    /// interactions. You should feed these to your __update logic__. +    /// +    /// [`UserInterface`]: struct.UserInterface.html +    /// [`Event`]: enum.Event.html +    /// +    /// # Example +    /// Let's allow our [counter](index.html#usage) to change state by completing +    /// [the previous example](#example): +    /// +    /// ```no_run +    /// use iced::{UserInterface, Cache}; +    /// use iced_wgpu::Renderer; +    /// +    /// # mod iced_wgpu { +    /// #     pub struct Renderer; +    /// # +    /// #     impl Renderer { +    /// #         pub fn new() -> Self { Renderer } +    /// #     } +    /// # } +    /// # +    /// # use iced::Column; +    /// # +    /// # pub struct Counter; +    /// # +    /// # impl Counter { +    /// #     pub fn new() -> Self { Counter } +    /// #     pub fn view(&self) -> Column<(), Renderer> { +    /// #         Column::new() +    /// #     } +    /// #     pub fn update(&mut self, message: ()) {} +    /// # } +    /// let mut counter = Counter::new(); +    /// let mut cache = Cache::new(); +    /// let mut renderer = Renderer::new(); +    /// +    /// // Initialize our event storage +    /// let mut events = Vec::new(); +    /// +    /// loop { +    ///     // Process system events... +    /// +    ///     let mut user_interface = UserInterface::build( +    ///         counter.view(), +    ///         cache, +    ///         &renderer, +    ///     ); +    /// +    ///     // Update the user interface +    ///     let messages = user_interface.update(events.drain(..)); +    /// +    ///     cache = user_interface.into_cache(); +    /// +    ///     // Process the produced messages +    ///     for message in messages { +    ///         counter.update(message); +    ///     } +    /// } +    /// ```      pub fn update(          &mut self,          events: impl Iterator<Item = Event>, @@ -61,6 +191,71 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {          messages      } +    /// Draws the [`UserInterface`] with the provided [`Renderer`]. +    /// +    /// It returns the current state of the [`MouseCursor`]. You should update +    /// the icon of the mouse cursor accordingly in your system. +    /// +    /// [`UserInterface`]: struct.UserInterface.html +    /// [`Renderer`]: trait.Renderer.html +    /// [`MouseCursor`]: enum.MouseCursor.html +    /// +    /// # Example +    /// We can finally draw our [counter](index.html#usage) by +    /// [completing the last example](#example-1): +    /// +    /// ```no_run +    /// use iced::{UserInterface, Cache}; +    /// use iced_wgpu::Renderer; +    /// +    /// # mod iced_wgpu { +    /// #     pub struct Renderer; +    /// # +    /// #     impl Renderer { +    /// #         pub fn new() -> Self { Renderer } +    /// #     } +    /// # } +    /// # +    /// # use iced::Column; +    /// # +    /// # pub struct Counter; +    /// # +    /// # impl Counter { +    /// #     pub fn new() -> Self { Counter } +    /// #     pub fn view(&self) -> Column<(), Renderer> { +    /// #         Column::new() +    /// #     } +    /// #     pub fn update(&mut self, message: ()) {} +    /// # } +    /// let mut counter = Counter::new(); +    /// let mut cache = Cache::new(); +    /// let mut renderer = Renderer::new(); +    /// let mut events = Vec::new(); +    /// +    /// loop { +    ///     // Process system events... +    /// +    ///     let mut user_interface = UserInterface::build( +    ///         counter.view(), +    ///         cache, +    ///         &renderer, +    ///     ); +    /// +    ///     let messages = user_interface.update(events.drain(..)); +    /// +    ///     // Draw the user interface +    ///     let mouse_cursor = user_interface.draw(&mut renderer); +    /// +    ///     cache = user_interface.into_cache(); +    /// +    ///     for message in messages { +    ///         counter.update(message); +    ///     } +    /// +    ///     // Update mouse cursor icon... +    ///     // Flush rendering operations... +    /// } +    /// ```      pub fn draw(&self, renderer: &mut Renderer) -> MouseCursor {          let cursor = self.root.widget.draw(              renderer, @@ -71,6 +266,11 @@ impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer> {          cursor      } +    /// Extract the [`Cache`] of the [`UserInterface`], consuming it in the +    /// process. +    /// +    /// [`Cache`]: struct.Cache.html +    /// [`UserInterface`]: struct.UserInterface.html      pub fn into_cache(self) -> Cache {          Cache {              hash: self.hash, diff --git a/src/widget.rs b/src/widget.rs index cd3ff7a2..ef5bd7b5 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -44,10 +44,6 @@ use crate::{Event, Hasher, Layout, MouseCursor, Node, Point};  /// If you want to build your own widgets, you will need to implement this  /// trait.  /// -/// Additionally, remember to also provide [`Into<Element>`] so your users can -/// easily turn your [`Widget`] into a generic [`Element`]. -/// -/// [`Into<Element>`]: ../struct.Element.html  /// [`Widget`]: trait.Widget.html  /// [`Element`]: ../struct.Element.html  pub trait Widget<Message, Renderer>: std::fmt::Debug { | 
