summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2022-05-02 21:21:24 +0200
committerLibravatar GitHub <noreply@github.com>2022-05-02 21:21:24 +0200
commit5acba65c1135d8ebbda94efc74ea0bebb29c438a (patch)
tree88673403313ad90cec226ee92d4ebf4ef0a24bdc
parenta17a7103d382f02c64e7b271d953ea6babffac97 (diff)
parent7e111f273fb22a6ffc7a4fd24bea5e838d276758 (diff)
downloadiced-5acba65c1135d8ebbda94efc74ea0bebb29c438a.tar.gz
iced-5acba65c1135d8ebbda94efc74ea0bebb29c438a.tar.bz2
iced-5acba65c1135d8ebbda94efc74ea0bebb29c438a.zip
Merge pull request #1327 from iced-rs/update-docs
Update documentation
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Cargo.toml2
-rw-r--r--README.md30
-rw-r--r--core/src/keyboard/modifiers.rs8
-rw-r--r--core/src/lib.rs7
-rw-r--r--futures/src/command.rs2
-rw-r--r--futures/src/runtime.rs6
-rw-r--r--futures/src/subscription.rs6
-rw-r--r--glow/README.md6
-rw-r--r--glow/src/backend.rs2
-rw-r--r--glow/src/lib.rs6
-rw-r--r--graphics/src/lib.rs4
-rw-r--r--graphics/src/widget/canvas.rs8
-rw-r--r--graphics/src/widget/pure/canvas/program.rs4
-rw-r--r--graphics/src/window/compositor.rs5
-rw-r--r--lazy/src/lib.rs5
-rw-r--r--native/src/command/action.rs4
-rw-r--r--native/src/image.rs4
-rw-r--r--native/src/lib.rs4
-rw-r--r--native/src/overlay.rs2
-rw-r--r--native/src/renderer.rs23
-rw-r--r--native/src/svg.rs4
-rw-r--r--native/src/text.rs2
-rw-r--r--native/src/user_interface.rs7
-rw-r--r--native/src/widget.rs10
-rw-r--r--native/src/widget/checkbox.rs2
-rw-r--r--native/src/widget/column.rs2
-rw-r--r--native/src/widget/pane_grid.rs2
-rw-r--r--native/src/widget/pane_grid/configuration.rs4
-rw-r--r--native/src/widget/pane_grid/content.rs2
-rw-r--r--native/src/widget/pane_grid/state.rs22
-rw-r--r--native/src/widget/pane_grid/title_bar.rs2
-rw-r--r--native/src/widget/row.rs2
-rw-r--r--native/src/widget/text.rs6
-rw-r--r--native/src/widget/text_input.rs9
-rw-r--r--native/src/widget/toggler.rs2
-rw-r--r--native/src/widget/tooltip.rs2
-rw-r--r--pure/src/element.rs146
-rw-r--r--pure/src/flex.rs2
-rw-r--r--pure/src/helpers.rs60
-rw-r--r--pure/src/lib.rs120
-rw-r--r--pure/src/overlay.rs5
-rw-r--r--pure/src/widget.rs49
-rw-r--r--pure/src/widget/button.rs36
-rw-r--r--pure/src/widget/checkbox.rs1
-rw-r--r--pure/src/widget/column.rs13
-rw-r--r--pure/src/widget/image.rs1
-rw-r--r--pure/src/widget/pane_grid.rs4
-rw-r--r--pure/src/widget/pane_grid/content.rs6
-rw-r--r--pure/src/widget/pane_grid/title_bar.rs6
-rw-r--r--pure/src/widget/pick_list.rs5
-rw-r--r--pure/src/widget/progress_bar.rs1
-rw-r--r--pure/src/widget/radio.rs1
-rw-r--r--pure/src/widget/row.rs13
-rw-r--r--pure/src/widget/rule.rs1
-rw-r--r--pure/src/widget/scrollable.rs1
-rw-r--r--pure/src/widget/slider.rs7
-rw-r--r--pure/src/widget/svg.rs1
-rw-r--r--pure/src/widget/text_input.rs20
-rw-r--r--pure/src/widget/toggler.rs1
-rw-r--r--pure/src/widget/tooltip.rs2
-rw-r--r--pure/src/widget/tree.rs48
-rw-r--r--src/application.rs18
-rw-r--r--src/lib.rs17
-rw-r--r--src/pure.rs79
-rw-r--r--src/pure/widget.rs2
-rw-r--r--src/sandbox.rs22
-rw-r--r--src/widget.rs10
-rw-r--r--wgpu/src/lib.rs2
-rw-r--r--winit/README.md2
-rw-r--r--winit/src/conversion.rs12
-rw-r--r--winit/src/lib.rs4
-rw-r--r--winit/src/settings.rs4
73 files changed, 755 insertions, 187 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cf6655f5..8782a2e3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
Thank you for considering contributing to Iced! Feel free to read [the ecosystem overview] and [the roadmap] to get an idea of the current state of the library.
-The main advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion in an issue](https://github.com/hecrj/iced/issues) explaining what you have in mind (do not be afraid of duplicated issues!). If you want to talk directly to me (@hecrj), you can also find me on Discord (`lone_scientist#9554`).
+The main advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion in an issue](https://github.com/iced-rs/iced/issues) explaining what you have in mind (do not be afraid of duplicated issues!). If you want to talk directly to me (@hecrj), you can also find me on Discord (`lone_scientist#9554`).
This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Please, do not skip it! Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]!
diff --git a/Cargo.toml b/Cargo.toml
index 9c4b8181..899d392a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -116,4 +116,4 @@ iced_wgpu = { version = "0.4", path = "wgpu", features = ["webgl"], optional = t
[package.metadata.docs.rs]
rustdoc-args = ["--cfg", "docsrs"]
-features = ["image", "svg", "canvas", "qr_code"]
+features = ["image", "svg", "canvas", "qr_code", "pure"]
diff --git a/README.md b/README.md
index e73891ce..2c3286e1 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,13 @@
<img src="docs/logo.svg" width="140px" />
-# iced
+# Iced
[![Documentation](https://docs.rs/iced/badge.svg)][documentation]
[![Crates.io](https://img.shields.io/crates/v/iced.svg)](https://crates.io/crates/iced)
-[![License](https://img.shields.io/crates/l/iced.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
+[![License](https://img.shields.io/crates/l/iced.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE)
[![Downloads](https://img.shields.io/crates/d/iced.svg)](https://crates.io/crates/iced)
-[![Test Status](https://github.com/hecrj/iced/workflows/Test/badge.svg?event=push)](https://github.com/hecrj/iced/actions)
+[![Test Status](https://github.com/iced-rs/iced/workflows/Test/badge.svg?event=push)](https://github.com/iced-rs/iced/actions)
[![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd)
A cross-platform GUI library for Rust focused on simplicity and type-safety.
@@ -40,11 +40,11 @@ Inspired by [Elm].
* A [windowing shell]
* A [web runtime] leveraging the DOM
-__iced is currently experimental software.__ [Take a look at the roadmap],
+__Iced is currently experimental software.__ [Take a look at the roadmap],
[check out the issues], and [feel free to contribute!]
[Cross-platform support]: https://raw.githubusercontent.com/iced-rs/iced/master/docs/images/todos_desktop.jpg
-[the Web]: https://iced.rs/
+[the Web]: https://github.com/iced-rs/iced_web
[text inputs]: https://gfycat.com/alertcalmcrow-rust-gui
[scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui
[Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee
@@ -69,13 +69,13 @@ Add `iced` as a dependency in your `Cargo.toml`:
iced = "0.3"
```
-__iced moves fast and the `master` branch can contain breaking changes!__ If
+__Iced moves fast and the `master` branch can contain breaking changes!__ If
you want to learn about a specific release, check out [the release list].
[the release list]: https://github.com/iced-rs/iced/releases
## Overview
-Inspired by [The Elm Architecture], iced expects you to split user interfaces
+Inspired by [The Elm Architecture], Iced expects you to split user interfaces
into four different concepts:
* __State__ — the state of your application
@@ -165,7 +165,7 @@ impl Counter {
}
```
-And that's everything! We just wrote a whole user interface. iced is now able
+And that's everything! We just wrote a whole user interface. Iced is now able
to:
1. Take the result of our __view logic__ and layout its widgets.
@@ -176,7 +176,7 @@ to:
Browse the [documentation] and the [examples] to learn more!
## Implementation details
-iced was originally born as an attempt at bringing the simplicity of [Elm] and
+Iced was originally born as an attempt at bringing the simplicity of [Elm] and
[The Elm Architecture] into [Coffee], a 2D game engine I am working on.
The core of the library was implemented during May 2019 in [this pull request].
@@ -189,7 +189,7 @@ end-user-oriented GUI library, while keeping [the ecosystem] modular:
<p align="center">
<a href="ECOSYSTEM.md">
- <img alt="iced ecosystem" src="docs/graphs/ecosystem.png" width="80%">
+ <img alt="The Iced Ecosystem" src="docs/graphs/ecosystem.png" width="80%">
</a>
</p>
@@ -222,7 +222,7 @@ iced = { version = "0.3", default-features = false, features = ["glow"] }
but if you don't, right now there's no software fallback, so it means your hardware
doesn't support Iced.
-[built-in renderer]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md#Renderers
+[built-in renderer]: https://github.com/iced-rs/iced/blob/master/ECOSYSTEM.md#Renderers
## Contributing / Feedback
Contributions are greatly appreciated! If you want to contribute, please
@@ -234,15 +234,15 @@ awesome folks) over the `#games-and-graphics` and `#gui-and-ui` channels in
the [Rust Community Discord]. I go by `lone_scientist#9554` there.
## Sponsors
-The development of iced is sponsored by the [Cryptowatch] team at [Kraken.com]
+The development of Iced is sponsored by the [Cryptowatch] team at [Kraken.com]
[documentation]: https://docs.rs/iced/
-[examples]: https://github.com/hecrj/iced/tree/master/examples
+[examples]: https://github.com/iced-rs/iced/tree/master/examples
[Coffee]: https://github.com/hecrj/coffee
[Elm]: https://elm-lang.org/
[The Elm Architecture]: https://guide.elm-lang.org/architecture/
-[the current issues]: https://github.com/hecrj/iced/issues
-[contributing guidelines]: https://github.com/hecrj/iced/blob/master/CONTRIBUTING.md
+[the current issues]: https://github.com/iced-rs/iced/issues
+[contributing guidelines]: https://github.com/iced-rs/iced/blob/master/CONTRIBUTING.md
[Discord server]: https://discord.gg/3xZJ65GAhd
[Rust Community Discord]: https://bit.ly/rust-community
[Cryptowatch]: https://cryptowat.ch/charts
diff --git a/core/src/keyboard/modifiers.rs b/core/src/keyboard/modifiers.rs
index e61f145a..ff5b08f2 100644
--- a/core/src/keyboard/modifiers.rs
+++ b/core/src/keyboard/modifiers.rs
@@ -41,21 +41,29 @@ impl Modifiers {
};
/// Returns true if the [`SHIFT`] key is pressed in the [`Modifiers`].
+ ///
+ /// [`SHIFT`]: Self::SHIFT
pub fn shift(self) -> bool {
self.contains(Self::SHIFT)
}
/// Returns true if the [`CTRL`] key is pressed in the [`Modifiers`].
+ ///
+ /// [`CTRL`]: Self::CTRL
pub fn control(self) -> bool {
self.contains(Self::CTRL)
}
/// Returns true if the [`ALT`] key is pressed in the [`Modifiers`].
+ ///
+ /// [`ALT`]: Self::ALT
pub fn alt(self) -> bool {
self.contains(Self::ALT)
}
/// Returns true if the [`LOGO`] key is pressed in the [`Modifiers`].
+ ///
+ /// [`LOGO`]: Self::LOGO
pub fn logo(self) -> bool {
self.contains(Self::LOGO)
}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 3eb9f659..7b0dc57b 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -7,8 +7,11 @@
//! ![The foundations of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/foundations.png?raw=true)
//!
//! [Iced]: https://github.com/iced-rs/iced
-//! [`iced_native`]: https://github.com/iced-rs/iced/tree/master/native
-//! [`iced_web`]: https://github.com/iced-rs/iced/tree/master/web
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
+//! [`iced_web`]: https://github.com/iced-rs/iced_web
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
+)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
diff --git a/futures/src/command.rs b/futures/src/command.rs
index d8adfe49..05c3a1d0 100644
--- a/futures/src/command.rs
+++ b/futures/src/command.rs
@@ -17,7 +17,7 @@ impl<T> Command<T> {
Self(Internal::None)
}
- /// Creates a [`Command`] that performs a single [`Action`].
+ /// Creates a [`Command`] that performs a single action.
pub const fn single(action: T) -> Self {
Self(Internal::Single(action))
}
diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs
index 2034ed6c..34f6b6dd 100644
--- a/futures/src/runtime.rs
+++ b/futures/src/runtime.rs
@@ -9,6 +9,8 @@ use std::marker::PhantomData;
///
/// If you have an [`Executor`], a [`Runtime`] can be leveraged to run any
/// [`Command`] or [`Subscription`] and get notified of the results!
+///
+/// [`Command`]: crate::Command
#[derive(Debug)]
pub struct Runtime<Hasher, Event, Executor, Sender, Message> {
executor: Executor,
@@ -51,10 +53,12 @@ where
self.executor.enter(f)
}
- /// Spawns a [`Command`] in the [`Runtime`].
+ /// Spawns a [`Future`] in the [`Runtime`].
///
/// The resulting `Message` will be forwarded to the `Sender` of the
/// [`Runtime`].
+ ///
+ /// [`Future`]: BoxFuture
pub fn spawn(&mut self, future: BoxFuture<Message>) {
use futures::{FutureExt, SinkExt};
diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs
index 6f261827..0085886d 100644
--- a/futures/src/subscription.rs
+++ b/futures/src/subscription.rs
@@ -125,9 +125,9 @@ impl<I, O, H> std::fmt::Debug for Subscription<I, O, H> {
/// - [`stopwatch`], a watch with start/stop and reset buttons showcasing how
/// to listen to time.
///
-/// [examples]: https://github.com/iced-rs/iced/tree/0.3/examples
-/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.3/examples/download_progress
-/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.3/examples/stopwatch
+/// [examples]: https://github.com/iced-rs/iced/tree/0.4/examples
+/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.4/examples/download_progress
+/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.4/examples/stopwatch
pub trait Recipe<Hasher: std::hash::Hasher, Event> {
/// The events that will be produced by a [`Subscription`] with this
/// [`Recipe`].
diff --git a/glow/README.md b/glow/README.md
index 5e37b7a2..00f38f64 100644
--- a/glow/README.md
+++ b/glow/README.md
@@ -1,12 +1,12 @@
# `iced_glow`
[![Documentation](https://docs.rs/iced_glow/badge.svg)][documentation]
[![Crates.io](https://img.shields.io/crates/v/iced_glow.svg)](https://crates.io/crates/iced_glow)
-[![License](https://img.shields.io/crates/l/iced_glow.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
+[![License](https://img.shields.io/crates/l/iced_glow.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE)
[![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd)
`iced_glow` is a [`glow`] renderer for [`iced_native`]. This renderer supports OpenGL 3.0+ and OpenGL ES 2.0.
-This is renderer is mostly used as a fallback for hardware that doesn't support [`wgpu`] (Vulkan, Metal or DX12).
+This renderer is mostly used as a fallback for hardware that doesn't support [`wgpu`] (Vulkan, Metal or DX12).
Currently, `iced_glow` supports the following primitives:
- Text, which is rendered using [`glow_glyph`]. No shaping at all.
@@ -34,7 +34,7 @@ iced_glow = "0.2"
__Iced moves fast and the `master` branch can contain breaking changes!__ If
you want to learn about a specific release, check out [the release list].
-[the release list]: https://github.com/hecrj/iced/releases
+[the release list]: https://github.com/iced-rs/iced/releases
## Current limitations
diff --git a/glow/src/backend.rs b/glow/src/backend.rs
index 89dc1aaa..f63135a4 100644
--- a/glow/src/backend.rs
+++ b/glow/src/backend.rs
@@ -13,7 +13,7 @@ use iced_native::{Font, Size};
/// A [`glow`] graphics backend for [`iced`].
///
/// [`glow`]: https://github.com/grovesNL/glow
-/// [`iced`]: https://github.com/hecrj/iced
+/// [`iced`]: https://github.com/iced-rs/iced
#[derive(Debug)]
pub struct Backend {
quad_pipeline: quad::Pipeline,
diff --git a/glow/src/lib.rs b/glow/src/lib.rs
index 05435b54..d7c0854d 100644
--- a/glow/src/lib.rs
+++ b/glow/src/lib.rs
@@ -1,9 +1,9 @@
//! A [`glow`] renderer for [`iced_native`].
//!
-//! ![The native path of the Iced ecosystem](https://github.com/hecrj/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
+//! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
//!
//! [`glow`]: https://github.com/grovesNL/glow
-//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
#![doc(
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
)]
@@ -37,5 +37,5 @@ pub use iced_native::{Alignment, Background, Color, Command, Length, Vector};
/// A [`glow`] graphics renderer for [`iced`].
///
/// [`glow`]: https://github.com/grovesNL/glow
-/// [`iced`]: https://github.com/hecrj/iced
+/// [`iced`]: https://github.com/iced-rs/iced
pub type Renderer = iced_graphics::Renderer<Backend>;
diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs
index b3be62af..9661f6ef 100644
--- a/graphics/src/lib.rs
+++ b/graphics/src/lib.rs
@@ -1,9 +1,9 @@
//! A bunch of backend-agnostic types that can be leveraged to build a renderer
//! for [`iced`].
//!
-//! ![The native path of the Iced ecosystem](https://github.com/hecrj/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
+//! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
//!
-//! [`iced`]: https://github.com/hecrj/iced
+//! [`iced`]: https://github.com/iced-rs/iced
#![doc(
html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
)]
diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs
index 6c526e35..23444b2b 100644
--- a/graphics/src/widget/canvas.rs
+++ b/graphics/src/widget/canvas.rs
@@ -51,10 +51,10 @@ use std::marker::PhantomData;
/// - [`solar_system`], an animated solar system drawn using the [`Canvas`] widget
/// and showcasing how to compose different transforms.
///
-/// [examples]: https://github.com/hecrj/iced/tree/master/examples
-/// [`clock`]: https://github.com/hecrj/iced/tree/master/examples/clock
-/// [`game_of_life`]: https://github.com/hecrj/iced/tree/master/examples/game_of_life
-/// [`solar_system`]: https://github.com/hecrj/iced/tree/master/examples/solar_system
+/// [examples]: https://github.com/iced-rs/iced/tree/0.4/examples
+/// [`clock`]: https://github.com/iced-rs/iced/tree/0.4/examples/clock
+/// [`game_of_life`]: https://github.com/iced-rs/iced/tree/0.4/examples/game_of_life
+/// [`solar_system`]: https://github.com/iced-rs/iced/tree/0.4/examples/solar_system
///
/// ## Drawing a simple circle
/// If you want to get a quick overview, here's how we can draw a simple circle:
diff --git a/graphics/src/widget/pure/canvas/program.rs b/graphics/src/widget/pure/canvas/program.rs
index ee74c27f..058b364b 100644
--- a/graphics/src/widget/pure/canvas/program.rs
+++ b/graphics/src/widget/pure/canvas/program.rs
@@ -10,10 +10,10 @@ use crate::Rectangle;
///
/// [`Canvas`]: crate::widget::Canvas
pub trait Program<Message> {
- /// The internal [`State`] mutated by the [`Program`].
+ /// The internal state mutated by the [`Program`].
type State: Default + 'static;
- /// Updates the state of the [`Program`].
+ /// Updates the [`State`](Self::State) of the [`Program`].
///
/// When a [`Program`] is used in a [`Canvas`], the runtime will call this
/// method for each [`Event`].
diff --git a/graphics/src/window/compositor.rs b/graphics/src/window/compositor.rs
index 9ea040cd..04a87bc6 100644
--- a/graphics/src/window/compositor.rs
+++ b/graphics/src/window/compositor.rs
@@ -40,7 +40,8 @@ pub trait Compositor: Sized {
/// Presents the [`Renderer`] primitives to the next frame of the given [`Surface`].
///
- /// [`SwapChain`]: Self::SwapChain
+ /// [`Renderer`]: Self::Renderer
+ /// [`Surface`]: Self::Surface
fn present<T: AsRef<str>>(
&mut self,
renderer: &mut Self::Renderer,
@@ -51,7 +52,7 @@ pub trait Compositor: Sized {
) -> Result<(), SurfaceError>;
}
-/// Result of an unsuccessful call to [`Compositor::draw`].
+/// Result of an unsuccessful call to [`Compositor::present`].
#[derive(Clone, PartialEq, Eq, Debug, Error)]
pub enum SurfaceError {
/// A timeout was encountered while trying to acquire the next frame.
diff --git a/lazy/src/lib.rs b/lazy/src/lib.rs
index 5d7d10e4..916f9458 100644
--- a/lazy/src/lib.rs
+++ b/lazy/src/lib.rs
@@ -1,7 +1,12 @@
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
+)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
pub mod component;
pub mod responsive;
#[cfg(feature = "pure")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pure")))]
pub mod pure;
pub use component::Component;
diff --git a/native/src/command/action.rs b/native/src/command/action.rs
index 5c7509c8..cd4309ed 100644
--- a/native/src/command/action.rs
+++ b/native/src/command/action.rs
@@ -10,6 +10,8 @@ use std::fmt;
/// [`Command`]: crate::Command
pub enum Action<T> {
/// Run a [`Future`] to completion.
+ ///
+ /// [`Future`]: iced_futures::BoxFuture
Future(iced_futures::BoxFuture<T>),
/// Run a clipboard action.
@@ -21,6 +23,8 @@ pub enum Action<T> {
impl<T> Action<T> {
/// Applies a transformation to the result of a [`Command`].
+ ///
+ /// [`Command`]: crate::Command
pub fn map<A>(
self,
f: impl Fn(T) -> A + 'static + MaybeSend + Sync,
diff --git a/native/src/image.rs b/native/src/image.rs
index 43bba4f1..516eb2db 100644
--- a/native/src/image.rs
+++ b/native/src/image.rs
@@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher as _};
use std::path::PathBuf;
use std::sync::Arc;
-/// An [`Image`] handle.
+/// A handle of some image data.
#[derive(Debug, Clone)]
pub struct Handle {
id: u64,
@@ -79,7 +79,7 @@ impl Hash for Handle {
}
}
-/// The data of an [`Image`].
+/// The data of a raster image.
#[derive(Clone, Hash)]
pub enum Data {
/// File data
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 5c9c24c9..a37535a7 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -23,8 +23,8 @@
//! - Build a new renderer, see the [renderer] module.
//! - Build a custom widget, start at the [`Widget`] trait.
//!
-//! [`iced_core`]: https://github.com/iced-rs/iced/tree/master/core
-//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/master/winit
+//! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.4/core
+//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.4/winit
//! [`druid`]: https://github.com/xi-editor/druid
//! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle
//! [renderer]: crate::renderer
diff --git a/native/src/overlay.rs b/native/src/overlay.rs
index 124bcac2..86878f6a 100644
--- a/native/src/overlay.rs
+++ b/native/src/overlay.rs
@@ -63,7 +63,7 @@ where
event::Status::Ignored
}
- /// Returns the current [`mouse::Interaction`] of the [`Widget`].
+ /// Returns the current [`mouse::Interaction`] of the [`Overlay`].
///
/// By default, it returns [`mouse::Interaction::Idle`].
fn mouse_interaction(
diff --git a/native/src/renderer.rs b/native/src/renderer.rs
index ca7ad5a2..73d2f401 100644
--- a/native/src/renderer.rs
+++ b/native/src/renderer.rs
@@ -1,24 +1,4 @@
//! Write your own renderer.
-//!
-//! You will need to implement the `Renderer` trait first. It simply contains
-//! an `Output` associated type.
-//!
-//! There is no common trait to draw all the widgets. Instead, every [`Widget`]
-//! constrains its generic `Renderer` type as necessary.
-//!
-//! This approach is flexible and composable. For instance, the
-//! [`Text`] widget only needs a [`text::Renderer`] while a [`Checkbox`] widget
-//! needs both a [`text::Renderer`] and a [`checkbox::Renderer`], reusing logic.
-//!
-//! In the end, a __renderer__ satisfying all the constraints is
-//! needed to build a [`UserInterface`].
-//!
-//! [`Widget`]: crate::Widget
-//! [`UserInterface`]: crate::UserInterface
-//! [`Text`]: crate::widget::Text
-//! [`text::Renderer`]: crate::widget::text::Renderer
-//! [`Checkbox`]: crate::widget::Checkbox
-//! [`checkbox::Renderer`]: crate::widget::checkbox::Renderer
#[cfg(debug_assertions)]
mod null;
#[cfg(debug_assertions)]
@@ -27,8 +7,7 @@ pub use null::Null;
use crate::layout;
use crate::{Background, Color, Element, Rectangle, Vector};
-/// A component that can take the state of a user interface and produce an
-/// output for its users.
+/// A component that can be used by widgets to draw themselves on a screen.
pub trait Renderer: Sized {
/// Lays out the elements of a user interface.
///
diff --git a/native/src/svg.rs b/native/src/svg.rs
index 90eff87e..f86fec5b 100644
--- a/native/src/svg.rs
+++ b/native/src/svg.rs
@@ -5,7 +5,7 @@ use std::hash::{Hash, Hasher as _};
use std::path::PathBuf;
use std::sync::Arc;
-/// An [`Svg`] handle.
+/// A handle of Svg data.
#[derive(Debug, Clone)]
pub struct Handle {
id: u64,
@@ -55,7 +55,7 @@ impl Hash for Handle {
}
}
-/// The data of an [`Svg`].
+/// The data of a vectorial image.
#[derive(Clone, Hash)]
pub enum Data {
/// File data
diff --git a/native/src/text.rs b/native/src/text.rs
index 256a9c5a..6e28681d 100644
--- a/native/src/text.rs
+++ b/native/src/text.rs
@@ -39,7 +39,7 @@ pub enum Hit {
}
impl Hit {
- /// Computes the cursor position corresponding to this [`HitTestResult`] .
+ /// Computes the cursor position of the [`Hit`] .
pub fn cursor(self) -> usize {
match self {
Self::CharOffset(i) => i,
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index 6fc6a479..f80786aa 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -16,7 +16,7 @@ use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
/// The [`integration` example] uses a [`UserInterface`] to integrate Iced in
/// an existing graphical application.
///
-/// [`integration` example]: https://github.com/iced-rs/iced/tree/0.3/examples/integration
+/// [`integration` example]: https://github.com/iced-rs/iced/tree/0.4/examples/integration
#[allow(missing_debug_implementations)]
pub struct UserInterface<'a, Message, Renderer> {
root: Element<'a, Message, Renderer>,
@@ -264,11 +264,10 @@ where
/// Draws the [`UserInterface`] with the provided [`Renderer`].
///
- /// It returns the some [`Renderer::Output`]. You should update the icon of
- /// the mouse cursor accordingly in your system.
+ /// It returns the current [`mouse::Interaction`]. You should update the
+ /// icon of the mouse cursor accordingly in your system.
///
/// [`Renderer`]: crate::Renderer
- /// [`Renderer::Output`]: crate::Renderer::Output
///
/// # Example
/// We can finally draw our [counter](index.html#usage) by
diff --git a/native/src/widget.rs b/native/src/widget.rs
index aacdc3d9..8417dad1 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -93,12 +93,12 @@ use crate::{Clipboard, Layout, Length, Point, Rectangle, Shell};
/// - [`geometry`], a custom widget showcasing how to draw geometry with the
/// `Mesh2D` primitive in [`iced_wgpu`].
///
-/// [examples]: https://github.com/iced-rs/iced/tree/0.3/examples
-/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.3/examples/bezier_tool
-/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.3/examples/custom_widget
-/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.3/examples/geometry
+/// [examples]: https://github.com/iced-rs/iced/tree/0.4/examples
+/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.4/examples/bezier_tool
+/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.4/examples/custom_widget
+/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.4/examples/geometry
/// [`lyon`]: https://github.com/nical/lyon
-/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.3/wgpu
+/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.4/wgpu
pub trait Widget<Message, Renderer>
where
Renderer: crate::Renderer,
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index 122c5e52..b6d920df 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -102,7 +102,7 @@ impl<'a, Message, Renderer: text::Renderer> Checkbox<'a, Message, Renderer> {
/// Sets the [`Font`] of the text of the [`Checkbox`].
///
- /// [`Font`]: crate::widget::text::Renderer::Font
+ /// [`Font`]: crate::text::Renderer::Font
pub fn font(mut self, font: Renderer::Font) -> Self {
self.font = font;
self
diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs
index f161d1f2..268218b1 100644
--- a/native/src/widget/column.rs
+++ b/native/src/widget/column.rs
@@ -48,7 +48,7 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
/// Sets the vertical spacing _between_ elements.
///
- /// Custom margins per element do not exist in Iced. You should use this
+ /// Custom margins per element do not exist in iced. You should use this
/// method instead! While less flexible, it helps you keep spacing between
/// elements consistent.
pub fn spacing(mut self, units: u16) -> Self {
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs
index 2093886e..0ceec83e 100644
--- a/native/src/widget/pane_grid.rs
+++ b/native/src/widget/pane_grid.rs
@@ -6,7 +6,7 @@
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
//! drag and drop, and hotkey support.
//!
-//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.3/examples/pane_grid
+//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid
mod axis;
mod configuration;
mod content;
diff --git a/native/src/widget/pane_grid/configuration.rs b/native/src/widget/pane_grid/configuration.rs
index 4c52bad4..7d68fb46 100644
--- a/native/src/widget/pane_grid/configuration.rs
+++ b/native/src/widget/pane_grid/configuration.rs
@@ -2,7 +2,7 @@ use crate::widget::pane_grid::Axis;
/// The arrangement of a [`PaneGrid`].
///
-/// [`PaneGrid`]: crate::pane_grid::PaneGrid
+/// [`PaneGrid`]: crate::widget::PaneGrid
#[derive(Debug, Clone)]
pub enum Configuration<T> {
/// A split of the available space.
@@ -21,6 +21,6 @@ pub enum Configuration<T> {
},
/// A [`Pane`].
///
- /// [`Pane`]: crate::pane_grid::Pane
+ /// [`Pane`]: crate::widget::pane_grid::Pane
Pane(T),
}
diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs
index f0ed0426..407f5458 100644
--- a/native/src/widget/pane_grid/content.rs
+++ b/native/src/widget/pane_grid/content.rs
@@ -55,7 +55,7 @@ where
{
/// Draws the [`Content`] with the provided [`Renderer`] and [`Layout`].
///
- /// [`Renderer`]: crate::widget::pane_grid::Renderer
+ /// [`Renderer`]: crate::Renderer
pub fn draw(
&self,
renderer: &mut Renderer,
diff --git a/native/src/widget/pane_grid/state.rs b/native/src/widget/pane_grid/state.rs
index f9ea21f4..6a282d24 100644
--- a/native/src/widget/pane_grid/state.rs
+++ b/native/src/widget/pane_grid/state.rs
@@ -1,4 +1,6 @@
//! The state of a [`PaneGrid`].
+//!
+//! [`PaneGrid`]: crate::widget::PaneGrid
use crate::widget::pane_grid::{
Axis, Configuration, Direction, Node, Pane, Split,
};
@@ -21,9 +23,13 @@ use std::collections::{BTreeMap, HashMap};
#[derive(Debug, Clone)]
pub struct State<T> {
/// The panes of the [`PaneGrid`].
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
pub panes: HashMap<Pane, T>,
/// The internal state of the [`PaneGrid`].
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
pub internal: Internal,
pub(super) action: Action,
@@ -198,6 +204,8 @@ impl<T> State<T> {
}
/// The internal state of a [`PaneGrid`].
+///
+/// [`PaneGrid`]: crate::widget::PaneGrid
#[derive(Debug, Clone)]
pub struct Internal {
layout: Node,
@@ -207,6 +215,8 @@ pub struct Internal {
impl Internal {
/// Initializes the [`Internal`] state of a [`PaneGrid`] from a
/// [`Configuration`].
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
pub fn from_configuration<T>(
panes: &mut HashMap<Pane, T>,
content: Configuration<T>,
@@ -248,11 +258,17 @@ impl Internal {
}
/// The current action of a [`PaneGrid`].
+///
+/// [`PaneGrid`]: crate::widget::PaneGrid
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Action {
/// The [`PaneGrid`] is idle.
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
Idle,
/// A [`Pane`] in the [`PaneGrid`] is being dragged.
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
Dragging {
/// The [`Pane`] being dragged.
pane: Pane,
@@ -260,6 +276,8 @@ pub enum Action {
origin: Point,
},
/// A [`Split`] in the [`PaneGrid`] is being dragged.
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
Resizing {
/// The [`Split`] being dragged.
split: Split,
@@ -288,6 +306,8 @@ impl Action {
impl Internal {
/// Calculates the current [`Pane`] regions from the [`PaneGrid`] layout.
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
pub fn pane_regions(
&self,
spacing: f32,
@@ -297,6 +317,8 @@ impl Internal {
}
/// Calculates the current [`Split`] regions from the [`PaneGrid`] layout.
+ ///
+ /// [`PaneGrid`]: crate::widget::PaneGrid
pub fn split_regions(
&self,
spacing: f32,
diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs
index d56972ec..a10181af 100644
--- a/native/src/widget/pane_grid/title_bar.rs
+++ b/native/src/widget/pane_grid/title_bar.rs
@@ -82,7 +82,7 @@ where
{
/// Draws the [`TitleBar`] with the provided [`Renderer`] and [`Layout`].
///
- /// [`Renderer`]: crate::widget::pane_grid::Renderer
+ /// [`Renderer`]: crate::Renderer
pub fn draw(
&self,
renderer: &mut Renderer,
diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs
index e34befb2..7a7c70c6 100644
--- a/native/src/widget/row.rs
+++ b/native/src/widget/row.rs
@@ -48,7 +48,7 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
/// Sets the horizontal spacing _between_ elements.
///
- /// Custom margins per element do not exist in Iced. You should use this
+ /// Custom margins per element do not exist in iced. You should use this
/// method instead! While less flexible, it helps you keep spacing between
/// elements consistent.
pub fn spacing(mut self, units: u16) -> Self {
diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs
index 6f00c9c8..a7855c30 100644
--- a/native/src/widget/text.rs
+++ b/native/src/widget/text.rs
@@ -59,7 +59,7 @@ impl<Renderer: text::Renderer> Text<Renderer> {
/// Sets the [`Font`] of the [`Text`].
///
- /// [`Font`]: Renderer::Font
+ /// [`Font`]: crate::text::Renderer::Font
pub fn font(mut self, font: impl Into<Renderer::Font>) -> Self {
self.font = font.into();
self
@@ -77,7 +77,7 @@ impl<Renderer: text::Renderer> Text<Renderer> {
self
}
- /// Sets the [`HorizontalAlignment`] of the [`Text`].
+ /// Sets the [`alignment::Horizontal`] of the [`Text`].
pub fn horizontal_alignment(
mut self,
alignment: alignment::Horizontal,
@@ -86,7 +86,7 @@ impl<Renderer: text::Renderer> Text<Renderer> {
self
}
- /// Sets the [`VerticalAlignment`] of the [`Text`].
+ /// Sets the [`alignment::Vertical`] of the [`Text`].
pub fn vertical_alignment(
mut self,
alignment: alignment::Vertical,
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index a206a0c7..5ecd68e9 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -108,10 +108,9 @@ where
self
}
- /// Sets the [`Font`] of the [`Text`].
+ /// Sets the [`Font`] of the [`TextInput`].
///
- /// [`Font`]: crate::widget::text::Renderer::Font
- /// [`Text`]: crate::widget::Text
+ /// [`Font`]: crate::text::Renderer::Font
pub fn font(mut self, font: Renderer::Font) -> Self {
self.font = font;
self
@@ -157,6 +156,8 @@ where
/// Draws the [`TextInput`] with the given [`Renderer`], overriding its
/// [`Value`] if provided.
+ ///
+ /// [`Renderer`]: text::Renderer
pub fn draw(
&self,
renderer: &mut Renderer,
@@ -570,6 +571,8 @@ where
/// Draws the [`TextInput`] with the given [`Renderer`], overriding its
/// [`Value`] if provided.
+///
+/// [`Renderer`]: text::Renderer
pub fn draw<Renderer>(
renderer: &mut Renderer,
layout: Layout<'_>,
diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs
index 536aef78..6d7592f3 100644
--- a/native/src/widget/toggler.rs
+++ b/native/src/widget/toggler.rs
@@ -107,6 +107,8 @@ impl<'a, Message, Renderer: text::Renderer> Toggler<'a, Message, Renderer> {
}
/// Sets the [`Font`] of the text of the [`Toggler`]
+ ///
+ /// [`Font`]: crate::text::Renderer::Font
pub fn font(mut self, font: Renderer::Font) -> Self {
self.font = font;
self
diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs
index e178c8b2..c929395f 100644
--- a/native/src/widget/tooltip.rs
+++ b/native/src/widget/tooltip.rs
@@ -29,7 +29,7 @@ where
/// The default padding of a [`Tooltip`] drawn by this renderer.
const DEFAULT_PADDING: u16 = 5;
- /// Creates an empty [`Tooltip`].
+ /// Creates a new [`Tooltip`].
///
/// [`Tooltip`]: struct.Tooltip.html
pub fn new(
diff --git a/pure/src/element.rs b/pure/src/element.rs
index 08096103..704b3d0b 100644
--- a/pure/src/element.rs
+++ b/pure/src/element.rs
@@ -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,
diff --git a/pure/src/flex.rs b/pure/src/flex.rs
index 8d473f08..3f65a28b 100644
--- a/pure/src/flex.rs
+++ b/pure/src/flex.rs
@@ -65,7 +65,7 @@ pub fn resolve<Message, Renderer>(
padding: Padding,
spacing: f32,
align_items: Alignment,
- items: &[Element<Message, Renderer>],
+ items: &[Element<'_, Message, Renderer>],
) -> Node
where
Renderer: iced_native::Renderer,
diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs
index 2ddab3ae..2c4a37be 100644
--- a/pure/src/helpers.rs
+++ b/pure/src/helpers.rs
@@ -1,3 +1,4 @@
+//! Helper functions to create pure widgets.
use crate::widget;
use crate::Element;
@@ -5,6 +6,9 @@ use iced_native::Length;
use std::borrow::Cow;
use std::ops::RangeInclusive;
+/// Creates a new [`Container`] with the provided content.
+///
+/// [`Container`]: widget::Container
pub fn container<'a, Message, Renderer>(
content: impl Into<Element<'a, Message, Renderer>>,
) -> widget::Container<'a, Message, Renderer>
@@ -14,15 +18,24 @@ where
widget::Container::new(content)
}
+/// Creates a new [`Column`].
+///
+/// [`Column`]: widget::Column
pub fn column<'a, Message, Renderer>() -> widget::Column<'a, Message, Renderer>
{
widget::Column::new()
}
+/// Creates a new [`Row`].
+///
+/// [`Row`]: widget::Row
pub fn row<'a, Message, Renderer>() -> widget::Row<'a, Message, Renderer> {
widget::Row::new()
}
+/// Creates a new [`Scrollable`] with the provided content.
+///
+/// [`Scrollable`]: widget::Scrollable
pub fn scrollable<'a, Message, Renderer>(
content: impl Into<Element<'a, Message, Renderer>>,
) -> widget::Scrollable<'a, Message, Renderer>
@@ -32,12 +45,19 @@ where
widget::Scrollable::new(content)
}
+/// Creates a new [`Button`] with the provided content.
+///
+/// [`Button`]: widget::Button
pub fn button<'a, Message, Renderer>(
content: impl Into<Element<'a, Message, Renderer>>,
) -> widget::Button<'a, Message, Renderer> {
widget::Button::new(content)
}
+/// Creates a new [`Tooltip`] with the provided content, tooltip text, and [`tooltip::Position`].
+///
+/// [`Tooltip`]: widget::Tooltip
+/// [`tooltip::Position`]: widget::tooltip::Position
pub fn tooltip<'a, Message, Renderer>(
content: impl Into<Element<'a, Message, Renderer>>,
tooltip: impl ToString,
@@ -49,6 +69,9 @@ where
widget::Tooltip::new(content, tooltip, position)
}
+/// Creates a new [`Text`] widget with the provided content.
+///
+/// [`Text`]: widget::Text
pub fn text<Renderer>(text: impl Into<String>) -> widget::Text<Renderer>
where
Renderer: iced_native::text::Renderer,
@@ -56,6 +79,9 @@ where
widget::Text::new(text)
}
+/// Creates a new [`Checkbox`].
+///
+/// [`Checkbox`]: widget::Checkbox
pub fn checkbox<'a, Message, Renderer>(
label: impl Into<String>,
is_checked: bool,
@@ -67,6 +93,9 @@ where
widget::Checkbox::new(is_checked, label, f)
}
+/// Creates a new [`Radio`].
+///
+/// [`Radio`]: widget::Radio
pub fn radio<'a, Message, Renderer, V>(
label: impl Into<String>,
value: V,
@@ -81,6 +110,9 @@ where
widget::Radio::new(value, label, selected, on_click)
}
+/// Creates a new [`Toggler`].
+///
+/// [`Toggler`]: widget::Toggler
pub fn toggler<'a, Message, Renderer>(
label: impl Into<Option<String>>,
is_checked: bool,
@@ -92,6 +124,9 @@ where
widget::Toggler::new(is_checked, label, f)
}
+/// Creates a new [`TextInput`].
+///
+/// [`TextInput`]: widget::TextInput
pub fn text_input<'a, Message, Renderer>(
placeholder: &str,
value: &str,
@@ -104,6 +139,9 @@ where
widget::TextInput::new(placeholder, value, on_change)
}
+/// Creates a new [`Slider`].
+///
+/// [`Slider`]: widget::Slider
pub fn slider<'a, Message, T>(
range: std::ops::RangeInclusive<T>,
value: T,
@@ -116,6 +154,9 @@ where
widget::Slider::new(range, value, on_change)
}
+/// Creates a new [`PickList`].
+///
+/// [`PickList`]: widget::PickList
pub fn pick_list<'a, Message, Renderer, T>(
options: impl Into<Cow<'a, [T]>>,
selected: Option<T>,
@@ -129,24 +170,37 @@ where
widget::PickList::new(options, selected, on_selected)
}
+/// Creates a new [`Image`].
+///
+/// [`Image`]: widget::Image
pub fn image<Handle>(handle: impl Into<Handle>) -> widget::Image<Handle> {
widget::Image::new(handle.into())
}
+/// Creates a new horizontal [`Space`] with the given [`Length`].
+///
+/// [`Space`]: widget::Space
pub fn horizontal_space(width: Length) -> widget::Space {
widget::Space::with_width(width)
}
+/// Creates a new vertical [`Space`] with the given [`Length`].
+///
+/// [`Space`]: widget::Space
pub fn vertical_space(height: Length) -> widget::Space {
widget::Space::with_height(height)
}
/// Creates a horizontal [`Rule`] with the given height.
+///
+/// [`Rule`]: widget::Rule
pub fn horizontal_rule<'a>(height: u16) -> widget::Rule<'a> {
widget::Rule::horizontal(height)
}
/// Creates a vertical [`Rule`] with the given width.
+///
+/// [`Rule`]: widget::Rule
pub fn vertical_rule<'a>(width: u16) -> widget::Rule<'a> {
widget::Rule::horizontal(width)
}
@@ -154,8 +208,10 @@ pub fn vertical_rule<'a>(width: u16) -> widget::Rule<'a> {
/// Creates a new [`ProgressBar`].
///
/// It expects:
-/// * an inclusive range of possible values
-/// * the current value of the [`ProgressBar`]
+/// * an inclusive range of possible values, and
+/// * the current value of the [`ProgressBar`].
+///
+/// [`ProgressBar`]: widget::ProgressBar
pub fn progress_bar<'a>(
range: RangeInclusive<f32>,
value: f32,
diff --git a/pure/src/lib.rs b/pure/src/lib.rs
index f9f0ae2d..6af74771 100644
--- a/pure/src/lib.rs
+++ b/pure/src/lib.rs
@@ -1,3 +1,92 @@
+//! Stateless, pure widgets for iced.
+//!
+//! # The Elm Architecture, purity, and continuity
+//! As you may know, applications made with `iced` use [The Elm Architecture].
+//!
+//! In a nutshell, this architecture defines the initial state of the application, a way to `view` it, and a way to `update` it after a user interaction. The `update` logic is called after a meaningful user interaction, which in turn updates the state of the application. Then, the `view` logic is executed to redisplay the application.
+//!
+//! Since `view` logic is only run after an `update`, all of the mutations to the application state must only happen in the `update` logic. If the application state changes anywhere else, the `view` logic will not be rerun and, therefore, the previously generated `view` may stay outdated.
+//!
+//! However, the `Application` trait in `iced` defines `view` as:
+//!
+//! ```ignore
+//! pub trait Application {
+//! fn view(&mut self) -> Element<Self::Message>;
+//! }
+//! ```
+//!
+//! As a consequence, the application state can be mutated in `view` logic. The `view` logic in `iced` is __impure__.
+//!
+//! This impurity is necessary because `iced` puts the burden of widget __continuity__ on its users. In other words, it's up to you to provide `iced` with the internal state of each widget every time `view` is called.
+//!
+//! If we take a look at the classic `counter` example:
+//!
+//! ```ignore
+//! struct Counter {
+//! value: i32,
+//! increment_button: button::State,
+//! decrement_button: button::State,
+//! }
+//!
+//! // ...
+//!
+//! impl Counter {
+//! pub fn view(&mut self) -> Column<Message> {
+//! Column::new()
+//! .push(
+//! Button::new(&mut self.increment_button, Text::new("+"))
+//! .on_press(Message::IncrementPressed),
+//! )
+//! .push(Text::new(self.value.to_string()).size(50))
+//! .push(
+//! Button::new(&mut self.decrement_button, Text::new("-"))
+//! .on_press(Message::DecrementPressed),
+//! )
+//! }
+//! }
+//! ```
+//!
+//! We can see how we need to keep track of the `button::State` of each `Button` in our `Counter` state and provide a mutable reference to the widgets in our `view` logic. The widgets produced by `view` are __stateful__.
+//!
+//! While this approach forces users to keep track of widget state and causes impurity, I originally chose it because it allows `iced` to directly consume the widget tree produced by `view`. Since there is no internal state decoupled from `view` maintained by the runtime, `iced` does not need to compare (e.g. reconciliate) widget trees in order to ensure continuity.
+//!
+//! # Stateless widgets
+//! As the library matures, the need for some kind of persistent widget data (see #553) between `view` calls becomes more apparent (e.g. incremental rendering, animations, accessibility, etc.).
+//!
+//! If we are going to end up having persistent widget data anyways... There is no reason to have impure, stateful widgets anymore!
+//!
+//! And so I started exploring and ended up creating a new subcrate called `iced_pure`, which introduces a completely stateless implementation for every widget in `iced`.
+//!
+//! With the help of this crate, we can now write a pure `counter` example:
+//!
+//! ```ignore
+//! struct Counter {
+//! value: i32,
+//! }
+//!
+//! // ...
+//!
+//! impl Counter {
+//! fn view(&self) -> Column<Message> {
+//! Column::new()
+//! .push(Button::new("Increment").on_press(Message::IncrementPressed))
+//! .push(Text::new(self.value.to_string()).size(50))
+//! .push(Button::new("Decrement").on_press(Message::DecrementPressed))
+//! }
+//! }
+//! ```
+//!
+//! Notice how we no longer need to keep track of the `button::State`! The widgets in `iced_pure` do not take any mutable application state in `view`. They are __stateless__ widgets. As a consequence, we do not need mutable access to `self` in `view` anymore. `view` becomes __pure__.
+//!
+//! [The Elm Architecture]: https://guide.elm-lang.org/architecture/
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg"
+)]
+#![deny(missing_docs)]
+#![deny(unused_results)]
+#![forbid(unsafe_code)]
+#![forbid(rust_2018_idioms)]
+
pub mod helpers;
pub mod overlay;
pub mod widget;
@@ -16,6 +105,32 @@ use iced_native::mouse;
use iced_native::renderer;
use iced_native::{Clipboard, Length, Point, Rectangle, Shell};
+/// A bridge between impure and pure widgets.
+///
+/// If you already have an existing `iced` application, you do not need to switch completely to the new traits in order to benefit from the `pure` module. Instead, you can leverage the new `Pure` widget to include `pure` widgets in your impure `Application`.
+///
+/// For instance, let's say we want to use our pure `Counter` in an impure application:
+///
+/// ```ignore
+/// use iced_pure::{self, Pure};
+///
+/// struct Impure {
+/// state: pure::State,
+/// counter: Counter,
+/// }
+///
+/// impl Sandbox for Impure {
+/// // ...
+///
+/// pub fn view(&mut self) -> Element<Self::Message> {
+/// Pure::new(&mut self.state, self.counter.view()).into()
+/// }
+/// }
+/// ```
+///
+/// [`Pure`] acts as a bridge between pure and impure widgets. It is completely opt-in and can be used to slowly migrate your application to the new architecture.
+///
+/// The purification of your application may trigger a bunch of important refactors, since it's far easier to keep your data decoupled from the GUI state with stateless widgets. For this reason, I recommend starting small in the most nested views of your application and slowly expand the purity upwards.
pub struct Pure<'a, Message, Renderer> {
state: &'a mut State,
element: Element<'a, Message, Renderer>,
@@ -26,6 +141,7 @@ where
Message: 'a,
Renderer: iced_native::Renderer + 'a,
{
+ /// Creates a new [`Pure`] widget with the given [`State`] and impure [`Element`].
pub fn new(
state: &'a mut State,
content: impl Into<Element<'a, Message, Renderer>>,
@@ -37,6 +153,7 @@ where
}
}
+/// The internal state of a [`Pure`] widget.
pub struct State {
state_tree: widget::Tree,
}
@@ -48,6 +165,7 @@ impl Default for State {
}
impl State {
+ /// Creates a new [`State`] for a [`Pure`] widget.
pub fn new() -> Self {
Self {
state_tree: widget::Tree::empty(),
@@ -56,7 +174,7 @@ impl State {
fn diff<Message, Renderer>(
&mut self,
- new_element: &Element<Message, Renderer>,
+ new_element: &Element<'_, Message, Renderer>,
) {
self.state_tree.diff(new_element);
}
diff --git a/pure/src/overlay.rs b/pure/src/overlay.rs
index c87dfce8..fecaa2ac 100644
--- a/pure/src/overlay.rs
+++ b/pure/src/overlay.rs
@@ -1,9 +1,14 @@
+//! Display interactive elements on top of other widgets.
use crate::widget::Tree;
use iced_native::Layout;
pub use iced_native::overlay::*;
+/// Obtains the first overlay [`Element`] found in the given children.
+///
+/// This method will generally only be used by advanced users that are
+/// implementing the [`Widget`](crate::Widget) trait.
pub fn from_children<'a, Message, Renderer>(
children: &'a [crate::Element<'_, Message, Renderer>],
tree: &'a mut Tree,
diff --git a/pure/src/widget.rs b/pure/src/widget.rs
index adce17ea..cc04cc96 100644
--- a/pure/src/widget.rs
+++ b/pure/src/widget.rs
@@ -1,3 +1,4 @@
+//! Use the built-in widgets or create your own.
pub mod button;
pub mod checkbox;
pub mod container;
@@ -48,17 +49,28 @@ use iced_native::overlay;
use iced_native::renderer;
use iced_native::{Clipboard, Length, Point, Rectangle, Shell};
+/// A component that displays information and allows interaction.
+///
+/// If you want to build your own widgets, you will need to implement this
+/// trait.
pub trait Widget<Message, Renderer> {
+ /// Returns the width of the [`Widget`].
fn width(&self) -> Length;
+ /// Returns the height of the [`Widget`].
fn height(&self) -> Length;
+ /// Returns the [`layout::Node`] of the [`Widget`].
+ ///
+ /// This [`layout::Node`] is used by the runtime to compute the [`Layout`] of the
+ /// user interface.
fn layout(
&self,
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node;
+ /// Draws the [`Widget`] using the associated `Renderer`.
fn draw(
&self,
state: &Tree,
@@ -69,31 +81,31 @@ pub trait Widget<Message, Renderer> {
viewport: &Rectangle,
);
+ /// Returns the [`Tag`] of the [`Widget`].
+ ///
+ /// [`Tag`]: tree::Tag
fn tag(&self) -> tree::Tag {
tree::Tag::stateless()
}
+ /// Returns the [`State`] of the [`Widget`].
+ ///
+ /// [`State`]: tree::State
fn state(&self) -> tree::State {
tree::State::None
}
+ /// Returns the state [`Tree`] of the children of the [`Widget`].
fn children(&self) -> Vec<Tree> {
Vec::new()
}
+ /// Reconciliates the [`Widget`] with the provided [`Tree`].
fn diff(&self, _tree: &mut Tree) {}
- fn mouse_interaction(
- &self,
- _state: &Tree,
- _layout: Layout<'_>,
- _cursor_position: Point,
- _viewport: &Rectangle,
- _renderer: &Renderer,
- ) -> mouse::Interaction {
- mouse::Interaction::Idle
- }
-
+ /// Processes a runtime [`Event`].
+ ///
+ /// By default, it does nothing.
fn on_event(
&mut self,
_state: &mut Tree,
@@ -107,6 +119,21 @@ pub trait Widget<Message, Renderer> {
event::Status::Ignored
}
+ /// Returns the current [`mouse::Interaction`] of the [`Widget`].
+ ///
+ /// By default, it returns [`mouse::Interaction::Idle`].
+ fn mouse_interaction(
+ &self,
+ _state: &Tree,
+ _layout: Layout<'_>,
+ _cursor_position: Point,
+ _viewport: &Rectangle,
+ _renderer: &Renderer,
+ ) -> mouse::Interaction {
+ mouse::Interaction::Idle
+ }
+
+ /// Returns the overlay of the [`Widget`], if there is any.
fn overlay<'a>(
&'a self,
_state: &'a mut Tree,
diff --git a/pure/src/widget/button.rs b/pure/src/widget/button.rs
index e083ea73..456c2509 100644
--- a/pure/src/widget/button.rs
+++ b/pure/src/widget/button.rs
@@ -1,3 +1,4 @@
+//! Allow your users to perform actions by pressing a button.
use crate::overlay;
use crate::widget::tree::{self, Tree};
use crate::{Element, Widget};
@@ -15,6 +16,40 @@ pub use iced_style::button::{Style, StyleSheet};
use button::State;
+/// A generic widget that produces a message when pressed.
+///
+/// ```
+/// # type Button<'a, Message> =
+/// # iced_pure::widget::Button<'a, Message, iced_native::renderer::Null>;
+/// #
+/// #[derive(Clone)]
+/// enum Message {
+/// ButtonPressed,
+/// }
+///
+/// let button = Button::new("Press me!").on_press(Message::ButtonPressed);
+/// ```
+///
+/// If a [`Button::on_press`] handler is not set, the resulting [`Button`] will
+/// be disabled:
+///
+/// ```
+/// # type Button<'a, Message> =
+/// # iced_pure::widget::Button<'a, Message, iced_native::renderer::Null>;
+/// #
+/// #[derive(Clone)]
+/// enum Message {
+/// ButtonPressed,
+/// }
+///
+/// fn disabled_button<'a>() -> Button<'a, Message> {
+/// Button::new("I'm disabled!")
+/// }
+///
+/// fn enabled_button<'a>() -> Button<'a, Message> {
+/// disabled_button().on_press(Message::ButtonPressed)
+/// }
+/// ```
pub struct Button<'a, Message, Renderer> {
content: Element<'a, Message, Renderer>,
on_press: Option<Message>,
@@ -25,6 +60,7 @@ pub struct Button<'a, Message, Renderer> {
}
impl<'a, Message, Renderer> Button<'a, Message, Renderer> {
+ /// Creates a new [`Button`] with the given content.
pub fn new(content: impl Into<Element<'a, Message, Renderer>>) -> Self {
Button {
content: content.into(),
diff --git a/pure/src/widget/checkbox.rs b/pure/src/widget/checkbox.rs
index 971980e3..98f55a56 100644
--- a/pure/src/widget/checkbox.rs
+++ b/pure/src/widget/checkbox.rs
@@ -1,3 +1,4 @@
+//! Show toggle controls using checkboxes.
use crate::widget::Tree;
use crate::{Element, Widget};
diff --git a/pure/src/widget/column.rs b/pure/src/widget/column.rs
index a4c0987b..7256f474 100644
--- a/pure/src/widget/column.rs
+++ b/pure/src/widget/column.rs
@@ -13,6 +13,7 @@ use iced_native::{
use std::u32;
+/// A container that distributes its contents vertically.
pub struct Column<'a, Message, Renderer> {
spacing: u16,
padding: Padding,
@@ -24,10 +25,12 @@ pub struct Column<'a, Message, Renderer> {
}
impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
+ /// Creates an empty [`Column`].
pub fn new() -> Self {
Self::with_children(Vec::new())
}
+ /// Creates a [`Column`] with the given elements.
pub fn with_children(
children: Vec<Element<'a, Message, Renderer>>,
) -> Self {
@@ -42,21 +45,29 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
}
}
+ /// Sets the vertical spacing _between_ elements.
+ ///
+ /// Custom margins per element do not exist in iced. You should use this
+ /// method instead! While less flexible, it helps you keep spacing between
+ /// elements consistent.
pub fn spacing(mut self, units: u16) -> Self {
self.spacing = units;
self
}
+ /// Sets the [`Padding`] of the [`Column`].
pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
self.padding = padding.into();
self
}
+ /// Sets the width of the [`Column`].
pub fn width(mut self, width: Length) -> Self {
self.width = width;
self
}
+ /// Sets the height of the [`Column`].
pub fn height(mut self, height: Length) -> Self {
self.height = height;
self
@@ -68,11 +79,13 @@ impl<'a, Message, Renderer> Column<'a, Message, Renderer> {
self
}
+ /// Sets the horizontal alignment of the contents of the [`Column`] .
pub fn align_items(mut self, align: Alignment) -> Self {
self.align_items = align;
self
}
+ /// Adds an element to the [`Column`].
pub fn push(
mut self,
child: impl Into<Element<'a, Message, Renderer>>,
diff --git a/pure/src/widget/image.rs b/pure/src/widget/image.rs
index a5bca5a0..ef764ec2 100644
--- a/pure/src/widget/image.rs
+++ b/pure/src/widget/image.rs
@@ -1,3 +1,4 @@
+//! Display images in your user interface.
use crate::widget::{Tree, Widget};
use crate::Element;
diff --git a/pure/src/widget/pane_grid.rs b/pure/src/widget/pane_grid.rs
index 34a56bcc..c532a6de 100644
--- a/pure/src/widget/pane_grid.rs
+++ b/pure/src/widget/pane_grid.rs
@@ -6,7 +6,7 @@
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
//! drag and drop, and hotkey support.
//!
-//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.3/examples/pane_grid
+//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid
mod content;
mod title_bar;
@@ -213,7 +213,7 @@ where
fn diff(&self, tree: &mut Tree) {
tree.diff_children_custom(
&self.elements,
- |(_, content), state| content.diff(state),
+ |state, (_, content)| content.diff(state),
|(_, content)| content.state(),
)
}
diff --git a/pure/src/widget/pane_grid/content.rs b/pure/src/widget/pane_grid/content.rs
index a928b28c..e66ac40b 100644
--- a/pure/src/widget/pane_grid/content.rs
+++ b/pure/src/widget/pane_grid/content.rs
@@ -57,7 +57,7 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer>
where
Renderer: iced_native::Renderer,
{
- pub fn state(&self) -> Tree {
+ pub(super) fn state(&self) -> Tree {
let children = if let Some(title_bar) = self.title_bar.as_ref() {
vec![Tree::new(&self.body), title_bar.state()]
} else {
@@ -70,7 +70,7 @@ where
}
}
- pub fn diff(&self, tree: &mut Tree) {
+ pub(super) fn diff(&self, tree: &mut Tree) {
if tree.children.len() == 2 {
if let Some(title_bar) = self.title_bar.as_ref() {
title_bar.diff(&mut tree.children[1]);
@@ -84,7 +84,7 @@ where
/// Draws the [`Content`] with the provided [`Renderer`] and [`Layout`].
///
- /// [`Renderer`]: crate::widget::pane_grid::Renderer
+ /// [`Renderer`]: iced_native::Renderer
pub fn draw(
&self,
tree: &Tree,
diff --git a/pure/src/widget/pane_grid/title_bar.rs b/pure/src/widget/pane_grid/title_bar.rs
index dd68b073..4a7c8c17 100644
--- a/pure/src/widget/pane_grid/title_bar.rs
+++ b/pure/src/widget/pane_grid/title_bar.rs
@@ -81,7 +81,7 @@ impl<'a, Message, Renderer> TitleBar<'a, Message, Renderer>
where
Renderer: iced_native::Renderer,
{
- pub fn state(&self) -> Tree {
+ pub(super) fn state(&self) -> Tree {
let children = if let Some(controls) = self.controls.as_ref() {
vec![Tree::new(&self.content), Tree::new(controls)]
} else {
@@ -94,7 +94,7 @@ where
}
}
- pub fn diff(&self, tree: &mut Tree) {
+ pub(super) fn diff(&self, tree: &mut Tree) {
if tree.children.len() == 2 {
if let Some(controls) = self.controls.as_ref() {
tree.children[1].diff(controls);
@@ -108,7 +108,7 @@ where
/// Draws the [`TitleBar`] with the provided [`Renderer`] and [`Layout`].
///
- /// [`Renderer`]: crate::widget::pane_grid::Renderer
+ /// [`Renderer`]: iced_native::Renderer
pub fn draw(
&self,
tree: &Tree,
diff --git a/pure/src/widget/pick_list.rs b/pure/src/widget/pick_list.rs
index 45bb289e..255e3681 100644
--- a/pure/src/widget/pick_list.rs
+++ b/pure/src/widget/pick_list.rs
@@ -43,9 +43,8 @@ where
/// The default padding of a [`PickList`].
pub const DEFAULT_PADDING: Padding = Padding::new(5);
- /// Creates a new [`PickList`] with the given [`State`], a list of options,
- /// the current selected value, and the message to produce when an option is
- /// selected.
+ /// Creates a new [`PickList`] with the given list of options, the current
+ /// selected value, and the message to produce when an option is selected.
pub fn new(
options: impl Into<Cow<'a, [T]>>,
selected: Option<T>,
diff --git a/pure/src/widget/progress_bar.rs b/pure/src/widget/progress_bar.rs
index 3f4ffd55..3016a81a 100644
--- a/pure/src/widget/progress_bar.rs
+++ b/pure/src/widget/progress_bar.rs
@@ -1,3 +1,4 @@
+//! Provide progress feedback to your users.
use crate::widget::Tree;
use crate::{Element, Widget};
diff --git a/pure/src/widget/radio.rs b/pure/src/widget/radio.rs
index c20f8f3e..7c98c937 100644
--- a/pure/src/widget/radio.rs
+++ b/pure/src/widget/radio.rs
@@ -1,3 +1,4 @@
+//! Create choices using radio buttons.
use crate::widget::Tree;
use crate::{Element, Widget};
diff --git a/pure/src/widget/row.rs b/pure/src/widget/row.rs
index 92812d27..0385b8bd 100644
--- a/pure/src/widget/row.rs
+++ b/pure/src/widget/row.rs
@@ -11,6 +11,7 @@ use iced_native::{
Alignment, Clipboard, Length, Padding, Point, Rectangle, Shell,
};
+/// A container that distributes its contents horizontally.
pub struct Row<'a, Message, Renderer> {
spacing: u16,
padding: Padding,
@@ -21,10 +22,12 @@ pub struct Row<'a, Message, Renderer> {
}
impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
+ /// Creates an empty [`Row`].
pub fn new() -> Self {
Self::with_children(Vec::new())
}
+ /// Creates a [`Row`] with the given elements.
pub fn with_children(
children: Vec<Element<'a, Message, Renderer>>,
) -> Self {
@@ -38,31 +41,41 @@ impl<'a, Message, Renderer> Row<'a, Message, Renderer> {
}
}
+ /// Sets the horizontal spacing _between_ elements.
+ ///
+ /// Custom margins per element do not exist in iced. You should use this
+ /// method instead! While less flexible, it helps you keep spacing between
+ /// elements consistent.
pub fn spacing(mut self, units: u16) -> Self {
self.spacing = units;
self
}
+ /// Sets the [`Padding`] of the [`Row`].
pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
self.padding = padding.into();
self
}
+ /// Sets the width of the [`Row`].
pub fn width(mut self, width: Length) -> Self {
self.width = width;
self
}
+ /// Sets the height of the [`Row`].
pub fn height(mut self, height: Length) -> Self {
self.height = height;
self
}
+ /// Sets the vertical alignment of the contents of the [`Row`] .
pub fn align_items(mut self, align: Alignment) -> Self {
self.align_items = align;
self
}
+ /// Adds an [`Element`] to the [`Row`].
pub fn push(
mut self,
child: impl Into<Element<'a, Message, Renderer>>,
diff --git a/pure/src/widget/rule.rs b/pure/src/widget/rule.rs
index 40b1fc90..ab8537ae 100644
--- a/pure/src/widget/rule.rs
+++ b/pure/src/widget/rule.rs
@@ -1,3 +1,4 @@
+//! Display a horizontal or vertical rule for dividing content.
use crate::widget::Tree;
use crate::{Element, Widget};
diff --git a/pure/src/widget/scrollable.rs b/pure/src/widget/scrollable.rs
index 24263c95..70e951ef 100644
--- a/pure/src/widget/scrollable.rs
+++ b/pure/src/widget/scrollable.rs
@@ -1,3 +1,4 @@
+//! Navigate an endless amount of content with a scrollbar.
use crate::overlay;
use crate::widget::tree::{self, Tree};
use crate::{Element, Widget};
diff --git a/pure/src/widget/slider.rs b/pure/src/widget/slider.rs
index 1107bdc1..4d8bbce4 100644
--- a/pure/src/widget/slider.rs
+++ b/pure/src/widget/slider.rs
@@ -1,6 +1,4 @@
//! Display an interactive selector of a single value from a range of values.
-//!
-//! A [`Slider`] has some local [`State`].
use crate::widget::tree::{self, Tree};
use crate::{Element, Widget};
@@ -25,17 +23,16 @@ pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet};
///
/// # Example
/// ```
-/// # use iced_native::widget::slider::{self, Slider};
+/// # use iced_pure::widget::Slider;
/// #
/// #[derive(Clone)]
/// pub enum Message {
/// SliderChanged(f32),
/// }
///
-/// let state = &mut slider::State::new();
/// let value = 50.0;
///
-/// Slider::new(state, 0.0..=100.0, value, Message::SliderChanged);
+/// Slider::new(0.0..=100.0, value, Message::SliderChanged);
/// ```
///
/// ![Slider drawn by Coffee's renderer](https://github.com/hecrj/coffee/blob/bda9818f823dfcb8a7ad0ff4940b4d4b387b5208/images/ui/slider.png?raw=true)
diff --git a/pure/src/widget/svg.rs b/pure/src/widget/svg.rs
index 2758c5b1..14180097 100644
--- a/pure/src/widget/svg.rs
+++ b/pure/src/widget/svg.rs
@@ -1,3 +1,4 @@
+//! Display vector graphics in your application.
use crate::widget::{Tree, Widget};
use crate::Element;
diff --git a/pure/src/widget/text_input.rs b/pure/src/widget/text_input.rs
index d6041d7f..57ad26d9 100644
--- a/pure/src/widget/text_input.rs
+++ b/pure/src/widget/text_input.rs
@@ -1,3 +1,4 @@
+//! Display fields that can be filled with text.
use crate::widget::tree::{self, Tree};
use crate::{Element, Widget};
@@ -15,20 +16,15 @@ pub use iced_style::text_input::{Style, StyleSheet};
///
/// # Example
/// ```
-/// # use iced_native::renderer::Null;
-/// # use iced_native::widget::text_input;
-/// #
-/// # pub type TextInput<'a, Message> = iced_native::widget::TextInput<'a, Message, Null>;
+/// # pub type TextInput<'a, Message> = iced_pure::widget::TextInput<'a, Message, iced_native::renderer::Null>;
/// #[derive(Debug, Clone)]
/// enum Message {
/// TextInputChanged(String),
/// }
///
-/// let mut state = text_input::State::new();
/// let value = "Some text";
///
/// let input = TextInput::new(
-/// &mut state,
/// "This is the placeholder...",
/// value,
/// Message::TextInputChanged,
@@ -58,10 +54,9 @@ where
/// Creates a new [`TextInput`].
///
/// It expects:
- /// - some [`State`]
- /// - a placeholder
- /// - the current value
- /// - a function that produces a message when the [`TextInput`] changes
+ /// - a placeholder,
+ /// - the current value, and
+ /// - a function that produces a message when the [`TextInput`] changes.
pub fn new<F>(placeholder: &str, value: &str, on_change: F) -> Self
where
F: 'a + Fn(String) -> Message,
@@ -86,10 +81,9 @@ where
self
}
- /// Sets the [`Font`] of the [`Text`].
+ /// Sets the [`Font`] of the [`TextInput`].
///
- /// [`Font`]: crate::widget::text::Renderer::Font
- /// [`Text`]: crate::widget::Text
+ /// [`Font`]: iced_native::text::Renderer::Font
pub fn font(mut self, font: Renderer::Font) -> Self {
self.font = font;
self
diff --git a/pure/src/widget/toggler.rs b/pure/src/widget/toggler.rs
index 1b3367a4..b9c5ec02 100644
--- a/pure/src/widget/toggler.rs
+++ b/pure/src/widget/toggler.rs
@@ -1,3 +1,4 @@
+//! Show toggle controls using togglers.
use crate::widget::{Tree, Widget};
use crate::Element;
diff --git a/pure/src/widget/tooltip.rs b/pure/src/widget/tooltip.rs
index 75c4d856..3887732a 100644
--- a/pure/src/widget/tooltip.rs
+++ b/pure/src/widget/tooltip.rs
@@ -32,7 +32,7 @@ where
/// The default padding of a [`Tooltip`] drawn by this renderer.
const DEFAULT_PADDING: u16 = 5;
- /// Creates an empty [`Tooltip`].
+ /// Creates a new [`Tooltip`].
///
/// [`Tooltip`]: struct.Tooltip.html
pub fn new(
diff --git a/pure/src/widget/tree.rs b/pure/src/widget/tree.rs
index bd7c259c..d81dd02c 100644
--- a/pure/src/widget/tree.rs
+++ b/pure/src/widget/tree.rs
@@ -1,14 +1,24 @@
+//! Store internal widget state in a state tree to ensure continuity.
use crate::Element;
use std::any::{self, Any};
+/// A persistent state widget tree.
+///
+/// A [`Tree`] is normally associated with a specific widget in the widget tree.
pub struct Tree {
+ /// The tag of the [`Tree`].
pub tag: Tag,
+
+ /// The [`State`] of the [`Tree`].
pub state: State,
+
+ /// The children of the root widget of the [`Tree`].
pub children: Vec<Tree>,
}
impl Tree {
+ /// Creates an empty, stateless [`Tree`] with no children.
pub fn empty() -> Self {
Self {
tag: Tag::stateless(),
@@ -17,6 +27,7 @@ impl Tree {
}
}
+ /// Creates a new [`Tree`] for the provided [`Element`].
pub fn new<Message, Renderer>(
element: &Element<'_, Message, Renderer>,
) -> Self {
@@ -27,6 +38,14 @@ impl Tree {
}
}
+ /// Reconciliates the current tree with the provided [`Element`].
+ ///
+ /// If the tag of the [`Element`] matches the tag of the [`Tree`], then the
+ /// [`Element`] proceeds with the reconciliation (i.e. [`Widget::diff`] is called).
+ ///
+ /// Otherwise, the whole [`Tree`] is recreated.
+ ///
+ /// [`Widget::diff`]: crate::Widget::diff
pub fn diff<Message, Renderer>(
&mut self,
new: &Element<'_, Message, Renderer>,
@@ -38,21 +57,20 @@ impl Tree {
}
}
+ /// Reconciliates the children of the tree with the provided list of [`Element`].
pub fn diff_children<Message, Renderer>(
&mut self,
new_children: &[Element<'_, Message, Renderer>],
) {
- self.diff_children_custom(
- new_children,
- |new, child_state| child_state.diff(new),
- Self::new,
- )
+ self.diff_children_custom(new_children, Self::diff, Self::new)
}
+ /// Reconciliates the children of the tree with the provided list of [`Element`] using custom
+ /// logic both for diffing and creating new widget state.
pub fn diff_children_custom<T>(
&mut self,
new_children: &[T],
- diff: impl Fn(&T, &mut Tree),
+ diff: impl Fn(&mut Tree, &T),
new_state: impl Fn(&T) -> Self,
) {
if self.children.len() > new_children.len() {
@@ -62,7 +80,7 @@ impl Tree {
for (child_state, new) in
self.children.iter_mut().zip(new_children.iter())
{
- diff(new, child_state);
+ diff(child_state, new);
}
if self.children.len() < new_children.len() {
@@ -73,10 +91,12 @@ impl Tree {
}
}
+/// The identifier of some widget state.
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct Tag(any::TypeId);
impl Tag {
+ /// Creates a [`Tag`] for a state of type `T`.
pub fn of<T>() -> Self
where
T: 'static,
@@ -84,17 +104,23 @@ impl Tag {
Self(any::TypeId::of::<T>())
}
+ /// Creates a [`Tag`] for a stateless widget.
pub fn stateless() -> Self {
Self::of::<()>()
}
}
+/// The internal [`State`] of a widget.
pub enum State {
+ /// No meaningful internal state.
None,
+
+ /// Some meaningful internal state.
Some(Box<dyn Any>),
}
impl State {
+ /// Creates a new [`State`].
pub fn new<T>(state: T) -> Self
where
T: 'static,
@@ -102,6 +128,10 @@ impl State {
State::Some(Box::new(state))
}
+ /// Downcasts the [`State`] to `T` and returns a reference to it.
+ ///
+ /// # Panics
+ /// This method will panic if the downcast fails or the [`State`] is [`State::None`].
pub fn downcast_ref<T>(&self) -> &T
where
T: 'static,
@@ -114,6 +144,10 @@ impl State {
}
}
+ /// Downcasts the [`State`] to `T` and returns a mutable reference to it.
+ ///
+ /// # Panics
+ /// This method will panic if the downcast fails or the [`State`] is [`State::None`].
pub fn downcast_mut<T>(&mut self) -> &mut T
where
T: 'static,
diff --git a/src/application.rs b/src/application.rs
index 14a16d61..11735b93 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -37,15 +37,15 @@ use crate::{Color, Command, Element, Executor, Settings, Subscription};
/// to listen to time.
/// - [`todos`], a todos tracker inspired by [TodoMVC].
///
-/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.3/examples
-/// [`clock`]: https://github.com/hecrj/iced/tree/0.3/examples/clock
-/// [`download_progress`]: https://github.com/hecrj/iced/tree/0.3/examples/download_progress
-/// [`events`]: https://github.com/hecrj/iced/tree/0.3/examples/events
-/// [`game_of_life`]: https://github.com/hecrj/iced/tree/0.3/examples/game_of_life
-/// [`pokedex`]: https://github.com/hecrj/iced/tree/0.3/examples/pokedex
-/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.3/examples/solar_system
-/// [`stopwatch`]: https://github.com/hecrj/iced/tree/0.3/examples/stopwatch
-/// [`todos`]: https://github.com/hecrj/iced/tree/0.3/examples/todos
+/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.4/examples
+/// [`clock`]: https://github.com/iced-rs/iced/tree/0.4/examples/clock
+/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.4/examples/download_progress
+/// [`events`]: https://github.com/iced-rs/iced/tree/0.4/examples/events
+/// [`game_of_life`]: https://github.com/iced-rs/iced/tree/0.4/examples/game_of_life
+/// [`pokedex`]: https://github.com/iced-rs/iced/tree/0.4/examples/pokedex
+/// [`solar_system`]: https://github.com/iced-rs/iced/tree/0.4/examples/solar_system
+/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.4/examples/stopwatch
+/// [`todos`]: https://github.com/iced-rs/iced/tree/0.4/examples/todos
/// [`Sandbox`]: crate::Sandbox
/// [`Canvas`]: crate::widget::Canvas
/// [PokéAPI]: https://pokeapi.co/
diff --git a/src/lib.rs b/src/lib.rs
index 84e872c7..bbc60746 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,19 +19,19 @@
//!
//! Check out the [repository] and the [examples] for more details!
//!
-//! [Cross-platform support]: https://github.com/hecrj/iced/blob/master/docs/images/todos_desktop.jpg?raw=true
+//! [Cross-platform support]: https://github.com/iced-rs/iced/blob/master/docs/images/todos_desktop.jpg?raw=true
//! [text inputs]: https://gfycat.com/alertcalmcrow-rust-gui
//! [scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui
//! [Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee
-//! [Modular ecosystem]: https://github.com/hecrj/iced/blob/master/ECOSYSTEM.md
-//! [renderer-agnostic native runtime]: https://github.com/hecrj/iced/tree/master/native
+//! [Modular ecosystem]: https://github.com/iced-rs/iced/blob/master/ECOSYSTEM.md
+//! [renderer-agnostic native runtime]: https://github.com/iced-rs/iced/0.4/master/native
//! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs
-//! [built-in renderer]: https://github.com/hecrj/iced/tree/master/wgpu
-//! [windowing shell]: https://github.com/hecrj/iced/tree/master/winit
+//! [built-in renderer]: https://github.com/iced-rs/iced/tree/0.4/wgpu
+//! [windowing shell]: https://github.com/iced-rs/iced/tree/0.4/winit
//! [`dodrio`]: https://github.com/fitzgen/dodrio
-//! [web runtime]: https://github.com/hecrj/iced/tree/master/web
-//! [examples]: https://github.com/hecrj/iced/tree/0.3/examples
-//! [repository]: https://github.com/hecrj/iced
+//! [web runtime]: https://github.com/iced-rs/iced_web
+//! [examples]: https://github.com/iced-rs/iced/tree/0.4/examples
+//! [repository]: https://github.com/iced-rs/iced
//!
//! # Overview
//! Inspired by [The Elm Architecture], Iced expects you to split user
@@ -196,6 +196,7 @@ pub mod widget;
pub mod window;
#[cfg(feature = "pure")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pure")))]
pub mod pure;
#[cfg(all(not(feature = "glow"), feature = "wgpu"))]
diff --git a/src/pure.rs b/src/pure.rs
index 948183f1..7785a104 100644
--- a/src/pure.rs
+++ b/src/pure.rs
@@ -14,6 +14,84 @@
//! offers an alternate [`Application`] trait with a completely pure `view`
//! method.
//!
+//! # The Elm Architecture, purity, and continuity
+//! As you may know, applications made with `iced` use [The Elm Architecture].
+//!
+//! In a nutshell, this architecture defines the initial state of the application, a way to `view` it, and a way to `update` it after a user interaction. The `update` logic is called after a meaningful user interaction, which in turn updates the state of the application. Then, the `view` logic is executed to redisplay the application.
+//!
+//! Since `view` logic is only run after an `update`, all of the mutations to the application state must only happen in the `update` logic. If the application state changes anywhere else, the `view` logic will not be rerun and, therefore, the previously generated `view` may stay outdated.
+//!
+//! However, the `Application` trait in `iced` defines `view` as:
+//!
+//! ```ignore
+//! pub trait Application {
+//! fn view(&mut self) -> Element<Self::Message>;
+//! }
+//! ```
+//!
+//! As a consequence, the application state can be mutated in `view` logic. The `view` logic in `iced` is __impure__.
+//!
+//! This impurity is necessary because `iced` puts the burden of widget __continuity__ on its users. In other words, it's up to you to provide `iced` with the internal state of each widget every time `view` is called.
+//!
+//! If we take a look at the classic `counter` example:
+//!
+//! ```ignore
+//! struct Counter {
+//! value: i32,
+//! increment_button: button::State,
+//! decrement_button: button::State,
+//! }
+//!
+//! // ...
+//!
+//! impl Counter {
+//! pub fn view(&mut self) -> Column<Message> {
+//! Column::new()
+//! .push(
+//! Button::new(&mut self.increment_button, Text::new("+"))
+//! .on_press(Message::IncrementPressed),
+//! )
+//! .push(Text::new(self.value.to_string()).size(50))
+//! .push(
+//! Button::new(&mut self.decrement_button, Text::new("-"))
+//! .on_press(Message::DecrementPressed),
+//! )
+//! }
+//! }
+//! ```
+//!
+//! We can see how we need to keep track of the `button::State` of each `Button` in our `Counter` state and provide a mutable reference to the widgets in our `view` logic. The widgets produced by `view` are __stateful__.
+//!
+//! While this approach forces users to keep track of widget state and causes impurity, I originally chose it because it allows `iced` to directly consume the widget tree produced by `view`. Since there is no internal state decoupled from `view` maintained by the runtime, `iced` does not need to compare (e.g. reconciliate) widget trees in order to ensure continuity.
+//!
+//! # Stateless widgets
+//! As the library matures, the need for some kind of persistent widget data (see #553) between `view` calls becomes more apparent (e.g. incremental rendering, animations, accessibility, etc.).
+//!
+//! If we are going to end up having persistent widget data anyways... There is no reason to have impure, stateful widgets anymore!
+//!
+//! With the help of this module, we can now write a pure `counter` example:
+//!
+//! ```ignore
+//! struct Counter {
+//! value: i32,
+//! }
+//!
+//! // ...
+//!
+//! impl Counter {
+//! fn view(&self) -> Column<Message> {
+//! Column::new()
+//! .push(Button::new("Increment").on_press(Message::IncrementPressed))
+//! .push(Text::new(self.value.to_string()).size(50))
+//! .push(Button::new("Decrement").on_press(Message::DecrementPressed))
+//! }
+//! }
+//! ```
+//!
+//! Notice how we no longer need to keep track of the `button::State`! The widgets in `iced_pure` do not take any mutable application state in `view`. They are __stateless__ widgets. As a consequence, we do not need mutable access to `self` in `view` anymore. `view` becomes __pure__.
+//!
+//! [The Elm Architecture]: https://guide.elm-lang.org/architecture/
+//!
//! [the original widgets]: crate::widget
//! [`button::State`]: crate::widget::button::State
//! [impure `Application`]: crate::Application
@@ -26,6 +104,7 @@ pub use application::Application;
pub use sandbox::Sandbox;
pub use iced_pure::helpers::*;
+pub use iced_pure::Widget;
pub use iced_pure::{Pure, State};
/// A generic, pure [`Widget`].
diff --git a/src/pure/widget.rs b/src/pure/widget.rs
index 2a506f73..c84edde3 100644
--- a/src/pure/widget.rs
+++ b/src/pure/widget.rs
@@ -47,7 +47,7 @@ pub mod pane_grid {
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
//! drag and drop, and hotkey support.
//!
- //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.3/examples/pane_grid
+ //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid
pub use iced_pure::widget::pane_grid::{
Axis, Configuration, Direction, DragEvent, Line, Node, Pane,
ResizeEvent, Split, State, StyleSheet,
diff --git a/src/sandbox.rs b/src/sandbox.rs
index 2306c650..e7e97920 100644
--- a/src/sandbox.rs
+++ b/src/sandbox.rs
@@ -35,19 +35,19 @@ use crate::{
/// - [`tour`], a simple UI tour that can run both on native platforms and the
/// web!
///
-/// [The repository has a bunch of examples]: https://github.com/hecrj/iced/tree/0.3/examples
-/// [`bezier_tool`]: https://github.com/hecrj/iced/tree/0.3/examples/bezier_tool
-/// [`counter`]: https://github.com/hecrj/iced/tree/0.3/examples/counter
-/// [`custom_widget`]: https://github.com/hecrj/iced/tree/0.3/examples/custom_widget
-/// [`geometry`]: https://github.com/hecrj/iced/tree/0.3/examples/geometry
-/// [`pane_grid`]: https://github.com/hecrj/iced/tree/0.3/examples/pane_grid
-/// [`progress_bar`]: https://github.com/hecrj/iced/tree/0.3/examples/progress_bar
-/// [`styling`]: https://github.com/hecrj/iced/tree/0.3/examples/styling
-/// [`svg`]: https://github.com/hecrj/iced/tree/0.3/examples/svg
-/// [`tour`]: https://github.com/hecrj/iced/tree/0.3/examples/tour
+/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.4/examples
+/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.4/examples/bezier_tool
+/// [`counter`]: https://github.com/iced-rs/iced/tree/0.4/examples/counter
+/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.4/examples/custom_widget
+/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.4/examples/geometry
+/// [`pane_grid`]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid
+/// [`progress_bar`]: https://github.com/iced-rs/iced/tree/0.4/examples/progress_bar
+/// [`styling`]: https://github.com/iced-rs/iced/tree/0.4/examples/styling
+/// [`svg`]: https://github.com/iced-rs/iced/tree/0.4/examples/svg
+/// [`tour`]: https://github.com/iced-rs/iced/tree/0.4/examples/tour
/// [`Canvas widget`]: crate::widget::Canvas
/// [the overview]: index.html#overview
-/// [`iced_wgpu`]: https://github.com/hecrj/iced/tree/0.3/wgpu
+/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.4/wgpu
/// [`Svg` widget]: crate::widget::Svg
/// [Ghostscript Tiger]: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg
///
diff --git a/src/widget.rs b/src/widget.rs
index 9cc0832f..5e2b63fc 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -63,7 +63,7 @@ pub mod pane_grid {
//! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing,
//! drag and drop, and hotkey support.
//!
- //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.3/examples/pane_grid
+ //! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.4/examples/pane_grid
pub use iced_native::widget::pane_grid::{
Axis, Configuration, Direction, DragEvent, Line, Node, Pane,
ResizeEvent, Split, State, StyleSheet,
@@ -167,9 +167,11 @@ pub use toggler::Toggler;
pub use tooltip::Tooltip;
#[cfg(feature = "canvas")]
+#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))]
pub use iced_graphics::widget::canvas;
#[cfg(feature = "image")]
+#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
pub mod image {
//! Display images in your user interface.
pub use iced_native::image::Handle;
@@ -182,9 +184,11 @@ pub mod image {
}
#[cfg(feature = "qr_code")]
+#[cfg_attr(docsrs, doc(cfg(feature = "qr_code")))]
pub use iced_graphics::widget::qr_code;
#[cfg(feature = "svg")]
+#[cfg_attr(docsrs, doc(cfg(feature = "svg")))]
pub mod svg {
//! Display vector graphics in your application.
pub use iced_native::svg::Handle;
@@ -192,13 +196,17 @@ pub mod svg {
}
#[cfg(feature = "canvas")]
+#[cfg_attr(docsrs, doc(cfg(feature = "canvas")))]
pub use canvas::Canvas;
#[cfg(feature = "image")]
+#[cfg_attr(docsrs, doc(cfg(feature = "image")))]
pub use image::Image;
#[cfg(feature = "qr_code")]
+#[cfg_attr(docsrs, doc(cfg(feature = "qr_code")))]
pub use qr_code::QRCode;
#[cfg(feature = "svg")]
+#[cfg_attr(docsrs, doc(cfg(feature = "svg")))]
pub use svg::Svg;
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index 5d4f5edd..ebe48510 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -16,7 +16,7 @@
//! - Meshes of triangles, useful to draw geometry freely.
//!
//! [Iced]: https://github.com/iced-rs/iced
-//! [`iced_native`]: https://github.com/iced-rs/iced/tree/master/native
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
//! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs
//! [WebGPU API]: https://gpuweb.github.io/gpuweb/
//! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
diff --git a/winit/README.md b/winit/README.md
index 5a94cd92..3ca46fff 100644
--- a/winit/README.md
+++ b/winit/README.md
@@ -1,7 +1,7 @@
# `iced_winit`
[![Documentation](https://docs.rs/iced_winit/badge.svg)][documentation]
[![Crates.io](https://img.shields.io/crates/v/iced_winit.svg)](https://crates.io/crates/iced_winit)
-[![License](https://img.shields.io/crates/l/iced_winit.svg)](https://github.com/hecrj/iced/blob/master/LICENSE)
+[![License](https://img.shields.io/crates/l/iced_winit.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE)
[![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd)
`iced_winit` offers some convenient abstractions on top of [`iced_native`] to quickstart development when using [`winit`].
diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs
index b00a095d..8e6c0b37 100644
--- a/winit/src/conversion.rs
+++ b/winit/src/conversion.rs
@@ -1,7 +1,7 @@
//! Convert [`winit`] types into [`iced_native`] types, and viceversa.
//!
//! [`winit`]: https://github.com/rust-windowing/winit
-//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
use crate::keyboard;
use crate::mouse;
use crate::touch;
@@ -208,7 +208,7 @@ pub fn visible(mode: Mode) -> bool {
/// Converts a `MouseCursor` from [`iced_native`] to a [`winit`] cursor icon.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn mouse_interaction(
interaction: mouse::Interaction,
) -> winit::window::CursorIcon {
@@ -232,7 +232,7 @@ pub fn mouse_interaction(
/// Converts a `MouseButton` from [`winit`] to an [`iced_native`] mouse button.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
match mouse_button {
winit::event::MouseButton::Left => mouse::Button::Left,
@@ -248,7 +248,7 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button {
/// modifiers state.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn modifiers(
modifiers: winit::event::ModifiersState,
) -> keyboard::Modifiers {
@@ -275,7 +275,7 @@ pub fn cursor_position(
/// Converts a `Touch` from [`winit`] to an [`iced_native`] touch event.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn touch_event(
touch: winit::event::Touch,
scale_factor: f64,
@@ -306,7 +306,7 @@ pub fn touch_event(
/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code.
///
/// [`winit`]: https://github.com/rust-windowing/winit
-/// [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
pub fn key_code(
virtual_keycode: winit::event::VirtualKeyCode,
) -> keyboard::KeyCode {
diff --git a/winit/src/lib.rs b/winit/src/lib.rs
index b31adf6e..2bb30caa 100644
--- a/winit/src/lib.rs
+++ b/winit/src/lib.rs
@@ -1,6 +1,6 @@
//! A windowing shell for Iced, on top of [`winit`].
//!
-//! ![The native path of the Iced ecosystem](https://github.com/hecrj/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
+//! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
//!
//! `iced_winit` offers some convenient abstractions on top of [`iced_native`]
//! to quickstart development when using [`winit`].
@@ -11,7 +11,7 @@
//! Additionally, a [`conversion`] module is available for users that decide to
//! implement a custom event loop.
//!
-//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
+//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native
//! [`winit`]: https://github.com/rust-windowing/winit
//! [`conversion`]: crate::conversion
#![doc(
diff --git a/winit/src/settings.rs b/winit/src/settings.rs
index 9a93824a..213ef47f 100644
--- a/winit/src/settings.rs
+++ b/winit/src/settings.rs
@@ -37,12 +37,16 @@ pub struct Settings<Flags> {
/// Whether the [`Application`] should exit when the user requests the
/// window to close (e.g. the user presses the close button).
+ ///
+ /// [`Application`]: crate::Application
pub exit_on_close_request: bool,
/// Whether the [`Application`] should try to build the context
/// using OpenGL ES first then OpenGL.
///
/// NOTE: Only works for the `glow` backend.
+ ///
+ /// [`Application`]: crate::Application
pub try_opengles_first: bool,
}