Write documentation for iced_pure
This commit is contained in:
parent
68e9eb0a9b
commit
e7d595c7de
26 changed files with 558 additions and 31 deletions
|
|
@ -8,25 +8,171 @@ use iced_native::mouse;
|
|||
use iced_native::renderer;
|
||||
use iced_native::{Clipboard, Length, Point, Rectangle, Shell};
|
||||
|
||||
/// A generic [`Widget`].
|
||||
///
|
||||
/// It is useful to build composable user interfaces that do not leak
|
||||
/// implementation details in their __view logic__.
|
||||
///
|
||||
/// If you have a [built-in widget], you should be able to use `Into<Element>`
|
||||
/// to turn it into an [`Element`].
|
||||
///
|
||||
/// [built-in widget]: crate::widget
|
||||
pub struct Element<'a, Message, Renderer> {
|
||||
widget: Box<dyn Widget<Message, Renderer> + 'a>,
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Element<'a, Message, Renderer> {
|
||||
/// Creates a new [`Element`] containing the given [`Widget`].
|
||||
pub fn new(widget: impl Widget<Message, Renderer> + 'a) -> Self {
|
||||
Self {
|
||||
widget: Box::new(widget),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the [`Widget`] of the [`Element`],
|
||||
pub fn as_widget(&self) -> &dyn Widget<Message, Renderer> {
|
||||
self.widget.as_ref()
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the [`Widget`] of the [`Element`],
|
||||
pub fn as_widget_mut(&mut self) -> &mut dyn Widget<Message, Renderer> {
|
||||
self.widget.as_mut()
|
||||
}
|
||||
|
||||
/// Applies a transformation to the produced message of the [`Element`].
|
||||
///
|
||||
/// This method is useful when you want to decouple different parts of your
|
||||
/// UI and make them __composable__.
|
||||
///
|
||||
/// # Example
|
||||
/// 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 {
|
||||
/// # type Text = iced_pure::widget::Text<iced_native::renderer::Null>;
|
||||
/// #
|
||||
/// # #[derive(Debug, Clone, Copy)]
|
||||
/// # pub enum Message {}
|
||||
/// # pub struct Counter;
|
||||
/// #
|
||||
/// # impl Counter {
|
||||
/// # pub fn view(&mut self) -> Text {
|
||||
/// # Text::new("")
|
||||
/// # }
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # mod iced_wgpu {
|
||||
/// # pub use iced_native::renderer::Null as Renderer;
|
||||
/// # }
|
||||
/// #
|
||||
/// # use counter::Counter;
|
||||
/// #
|
||||
/// # struct ManyCounters {
|
||||
/// # counters: Vec<Counter>,
|
||||
/// # }
|
||||
/// #
|
||||
/// # #[derive(Debug, Clone, Copy)]
|
||||
/// # pub enum Message {
|
||||
/// # Counter(usize, counter::Message)
|
||||
/// # }
|
||||
/// use iced_pure::Element;
|
||||
/// use iced_pure::widget::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<B>(
|
||||
self,
|
||||
f: impl Fn(Message) -> B + 'a,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue