diff options
author | 2019-08-30 02:59:53 +0200 | |
---|---|---|
committer | 2019-08-30 02:59:53 +0200 | |
commit | 072cdab48903863f8f5ebaea19bd537428197f51 (patch) | |
tree | 580fb9effb18d3f9c49e0042d20a270e7adbb3d3 /src | |
parent | dc4ce4d3b953aa41ff8d29c35b63c96327a2eb77 (diff) | |
download | iced-072cdab48903863f8f5ebaea19bd537428197f51.tar.gz iced-072cdab48903863f8f5ebaea19bd537428197f51.tar.bz2 iced-072cdab48903863f8f5ebaea19bd537428197f51.zip |
Write documentation example for `Element::map`
Diffstat (limited to 'src')
-rw-r--r-- | src/element.rs | 146 | ||||
-rw-r--r-- | src/lib.rs | 4 |
2 files changed, 146 insertions, 4 deletions
diff --git a/src/element.rs b/src/element.rs index e71465fb..098ca16f 100644 --- a/src/element.rs +++ b/src/element.rs @@ -43,12 +43,154 @@ impl<'a, Message, Renderer> Element<'a, Message, Renderer> { /// Applies a transformation to the produced message of the [`Element`]. /// /// This method is useful when you want to decouple different parts of your - /// UI. + /// UI and make them __composable__. /// /// [`Element`]: struct.Element.html /// /// # Example - /// TODO + /// Imagine we want to use [our counter](index.html#usage). But instead of + /// showing a single counter, we want to display many of them. We can reuse + /// the `Counter` type as it is! + /// + /// We use composition to model the __state__ of our new application: + /// + /// ``` + /// # mod counter { + /// # pub struct Counter; + /// # } + /// use counter::Counter; + /// + /// struct ManyCounters { + /// counters: Vec<Counter>, + /// } + /// ``` + /// + /// We can store the state of multiple counters now. However, the + /// __messages__ we implemented before describe the user interactions + /// of a __single__ counter. Right now, we need to also identify which + /// counter is receiving user interactions. Can we use composition again? + /// Yes. + /// + /// ``` + /// # mod counter { + /// # #[derive(Debug, Clone, Copy)] + /// # pub enum Message {} + /// # } + /// #[derive(Debug, Clone, Copy)] + /// pub enum Message { + /// Counter(usize, counter::Message) + /// } + /// ``` + /// + /// We compose the previous __messages__ with the index of the counter + /// producing them. Let's implement our __view logic__ now: + /// + /// ``` + /// # mod counter { + /// # use iced::{button, Button}; + /// # + /// # #[derive(Debug, Clone, Copy)] + /// # pub enum Message {} + /// # pub struct Counter(button::State); + /// # + /// # impl Counter { + /// # pub fn view(&mut self) -> Button<Message> { + /// # Button::new(&mut self.0, "_") + /// # } + /// # } + /// # } + /// # + /// # mod iced_wgpu { + /// # use iced::{ + /// # button, MouseCursor, Node, Point, Rectangle, Style, + /// # }; + /// # pub struct Renderer; + /// # + /// # impl button::Renderer for Renderer { + /// # fn draw( + /// # &mut self, + /// # _cursor_position: Point, + /// # _bounds: Rectangle<f32>, + /// # _state: &button::State, + /// # _label: &str, + /// # _class: button::Class, + /// # ) -> MouseCursor { + /// # MouseCursor::OutOfBounds + /// # } + /// # } + /// # } + /// # + /// # use counter::Counter; + /// # + /// # struct ManyCounters { + /// # counters: Vec<Counter>, + /// # } + /// # + /// # #[derive(Debug, Clone, Copy)] + /// # pub enum Message { + /// # Counter(usize, counter::Message) + /// # } + /// use iced::{Element, Row}; + /// use iced_wgpu::Renderer; + /// + /// impl ManyCounters { + /// pub fn view(&mut self) -> Row<Message, Renderer> { + /// // We can quickly populate a `Row` by folding over our counters + /// self.counters.iter_mut().enumerate().fold( + /// Row::new().spacing(20), + /// |row, (index, counter)| { + /// // We display the counter + /// let element: Element<counter::Message, Renderer> = + /// counter.view().into(); + /// + /// row.push( + /// // Here we turn our `Element<counter::Message>` into + /// // an `Element<Message>` by combining the `index` and the + /// // message of the `element`. + /// element.map(move |message| Message::Counter(index, message)) + /// ) + /// } + /// ) + /// } + /// } + /// ``` + /// + /// Finally, our __update logic__ is pretty straightforward: simple + /// delegation. + /// + /// ``` + /// # mod counter { + /// # #[derive(Debug, Clone, Copy)] + /// # pub enum Message {} + /// # pub struct Counter; + /// # + /// # impl Counter { + /// # pub fn update(&mut self, _message: Message) {} + /// # } + /// # } + /// # + /// # use counter::Counter; + /// # + /// # struct ManyCounters { + /// # counters: Vec<Counter>, + /// # } + /// # + /// # #[derive(Debug, Clone, Copy)] + /// # pub enum Message { + /// # Counter(usize, counter::Message) + /// # } + /// impl ManyCounters { + /// pub fn update(&mut self, message: Message) { + /// match message { + /// Message::Counter(index, counter_msg) => { + /// if let Some(counter) = self.counters.get_mut(index) { + /// counter.update(counter_msg); + /// } + /// } + /// } + /// } + /// } + /// ``` pub fn map<F, B>(self, f: F) -> Element<'a, B, Renderer> where Message: 'static + Copy, @@ -117,7 +117,7 @@ //! use iced_wgpu::Renderer; // Iced is renderer-agnostic! We need to bring our own! //! //! impl Counter { -//! fn view(&mut self) -> Column<Message, Renderer> { +//! pub fn view(&mut self) -> Column<Message, Renderer> { //! // We use a column: a simple vertical layout //! Column::new() //! .push( @@ -163,7 +163,7 @@ //! impl Counter { //! // ... //! -//! fn update(&mut self, message: Message) { +//! pub fn update(&mut self, message: Message) { //! match message { //! Message::IncrementPressed => { //! self.value += 1; |