summaryrefslogtreecommitdiffstats
path: root/native/src
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-11-22 19:36:57 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-11-22 19:36:57 +0100
commita7dba612f03e58d7bd9527499d893987986b347c (patch)
treeb8c3d8f997b714aa368bd6eaecf14065f7645c77 /native/src
parentba56a561b254c9a5f3d23cb54d23dc311759ab4c (diff)
downloadiced-a7dba612f03e58d7bd9527499d893987986b347c.tar.gz
iced-a7dba612f03e58d7bd9527499d893987986b347c.tar.bz2
iced-a7dba612f03e58d7bd9527499d893987986b347c.zip
Write docs for `iced` and `iced_native`
Diffstat (limited to 'native/src')
-rw-r--r--native/src/element.rs64
-rw-r--r--native/src/input/mouse/event.rs8
-rw-r--r--native/src/layout.rs16
-rw-r--r--native/src/layout/flex.rs24
-rw-r--r--native/src/layout/limits.rs53
-rw-r--r--native/src/layout/node.rs23
-rw-r--r--native/src/lib.rs172
-rw-r--r--native/src/renderer.rs12
-rw-r--r--native/src/renderer/null.rs1
-rw-r--r--native/src/renderer/windowed.rs19
-rw-r--r--native/src/size.rs14
-rw-r--r--native/src/widget.rs9
-rw-r--r--native/src/widget/checkbox.rs9
-rw-r--r--native/src/widget/column.rs17
-rw-r--r--native/src/widget/container.rs1
-rw-r--r--native/src/widget/image.rs3
-rw-r--r--native/src/widget/radio.rs7
-rw-r--r--native/src/widget/row.rs17
-rw-r--r--native/src/widget/scrollable.rs24
-rw-r--r--native/src/widget/slider.rs25
-rw-r--r--native/src/widget/text.rs11
-rw-r--r--native/src/widget/text_input.rs60
22 files changed, 391 insertions, 198 deletions
diff --git a/native/src/element.rs b/native/src/element.rs
index 3bf24317..5335fdc1 100644
--- a/native/src/element.rs
+++ b/native/src/element.rs
@@ -33,31 +33,6 @@ where
}
}
- pub fn width(&self) -> Length {
- self.widget.width()
- }
-
- pub fn height(&self) -> Length {
- self.widget.height()
- }
-
- pub fn layout(
- &self,
- renderer: &Renderer,
- limits: &layout::Limits,
- ) -> layout::Node {
- self.widget.layout(renderer, limits)
- }
-
- pub fn draw(
- &self,
- renderer: &mut Renderer,
- layout: Layout<'_>,
- cursor_position: Point,
- ) -> Renderer::Output {
- self.widget.draw(renderer, layout, cursor_position)
- }
-
/// Applies a transformation to the produced message of the [`Element`].
///
/// This method is useful when you want to decouple different parts of your
@@ -225,6 +200,45 @@ where
}
}
+ /// Returns the width of the [`Element`].
+ ///
+ /// [`Element`]: struct.Element.html
+ pub fn width(&self) -> Length {
+ self.widget.width()
+ }
+
+ /// Returns the height of the [`Element`].
+ ///
+ /// [`Element`]: struct.Element.html
+ pub fn height(&self) -> Length {
+ self.widget.height()
+ }
+
+ /// Computes the layout of the [`Element`] in the given [`Limits`].
+ ///
+ /// [`Element`]: struct.Element.html
+ /// [`Limits`]: layout/struct.Limits.html
+ pub fn layout(
+ &self,
+ renderer: &Renderer,
+ limits: &layout::Limits,
+ ) -> layout::Node {
+ self.widget.layout(renderer, limits)
+ }
+
+ /// Draws the [`Element`] and its children using the given [`Layout`].
+ ///
+ /// [`Element`]: struct.Element.html
+ /// [`Layout`]: layout/struct.Layout.html
+ pub fn draw(
+ &self,
+ renderer: &mut Renderer,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ ) -> Renderer::Output {
+ self.widget.draw(renderer, layout, cursor_position)
+ }
+
pub(crate) fn hash_layout(&self, state: &mut Hasher) {
self.widget.hash_layout(state);
}
diff --git a/native/src/input/mouse/event.rs b/native/src/input/mouse/event.rs
index 478f9b4d..aafc4fe3 100644
--- a/native/src/input/mouse/event.rs
+++ b/native/src/input/mouse/event.rs
@@ -34,11 +34,16 @@ pub enum Event {
},
/// The mouse wheel was scrolled.
- WheelScrolled { delta: ScrollDelta },
+ WheelScrolled {
+ /// The scroll movement.
+ delta: ScrollDelta,
+ },
}
+/// A scroll movement.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ScrollDelta {
+ /// A line-based scroll movement
Lines {
/// The number of horizontal lines scrolled
x: f32,
@@ -46,6 +51,7 @@ pub enum ScrollDelta {
/// The number of vertical lines scrolled
y: f32,
},
+ /// A pixel-based scroll movement
Pixels {
/// The number of horizontal pixels scrolled
x: f32,
diff --git a/native/src/layout.rs b/native/src/layout.rs
index 0a744346..e945706b 100644
--- a/native/src/layout.rs
+++ b/native/src/layout.rs
@@ -1,3 +1,4 @@
+//! Position your widgets properly.
mod limits;
mod node;
@@ -8,6 +9,9 @@ pub use node::Node;
use crate::{Point, Rectangle, Vector};
+/// The bounds of a [`Node`] and its children, using absolute coordinates.
+///
+/// [`Node`]: struct.Node.html
#[derive(Debug, Clone, Copy)]
pub struct Layout<'a> {
position: Point,
@@ -28,6 +32,14 @@ impl<'a> Layout<'a> {
}
}
+ /// Gets the bounds of the [`Layout`].
+ ///
+ /// The returned [`Rectangle`] describes the position and size of a
+ /// [`Node`].
+ ///
+ /// [`Layout`]: struct.Layout.html
+ /// [`Rectangle`]: struct.Rectangle.html
+ /// [`Node`]: struct.Node.html
pub fn bounds(&self) -> Rectangle {
let bounds = self.node.bounds();
@@ -39,6 +51,10 @@ impl<'a> Layout<'a> {
}
}
+ /// Returns an iterator over the [`Layout`] of the children of a [`Node`].
+ ///
+ /// [`Layout`]: struct.Layout.html
+ /// [`Node`]: struct.Node.html
pub fn children(&'a self) -> impl Iterator<Item = Layout<'a>> {
self.node.children().iter().map(move |node| {
Layout::with_offset(
diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs
index 7a2b0d70..bc90553e 100644
--- a/native/src/layout/flex.rs
+++ b/native/src/layout/flex.rs
@@ -1,3 +1,4 @@
+//! Distribute elements using a flex-based layout.
// This code is heavily inspired by the [`druid`] codebase.
//
// [`druid`]: https://github.com/xi-editor/druid
@@ -20,9 +21,13 @@ use crate::{
Align, Element, Size,
};
+/// The main axis of a flex layout.
#[derive(Debug)]
pub enum Axis {
+ /// The horizontal axis
Horizontal,
+
+ /// The vertical axis
Vertical,
}
@@ -49,7 +54,12 @@ impl Axis {
}
}
-// TODO: Remove `Message` type parameter
+/// Computes the flex layout with the given axis and limits, applying spacing,
+/// padding and alignment to the items as needed.
+///
+/// It returns a new layout [`Node`].
+///
+/// [`Node`]: ../struct.Node.html
pub fn resolve<Message, Renderer>(
axis: Axis,
renderer: &Renderer,
@@ -57,7 +67,7 @@ pub fn resolve<Message, Renderer>(
padding: f32,
spacing: f32,
align_items: Align,
- children: &[Element<'_, Message, Renderer>],
+ items: &[Element<'_, Message, Renderer>],
) -> Node
where
Renderer: crate::Renderer,
@@ -65,14 +75,14 @@ where
let limits = limits.pad(padding);
let mut total_non_fill =
- spacing as f32 * (children.len() as i32 - 1).max(0) as f32;
+ spacing as f32 * (items.len() as i32 - 1).max(0) as f32;
let mut fill_sum = 0;
let mut cross = axis.cross(limits.min());
- let mut nodes: Vec<Node> = Vec::with_capacity(children.len());
- nodes.resize(children.len(), Node::default());
+ let mut nodes: Vec<Node> = Vec::with_capacity(items.len());
+ nodes.resize(items.len(), Node::default());
- for (i, child) in children.iter().enumerate() {
+ for (i, child) in items.iter().enumerate() {
let fill_factor = match axis {
Axis::Horizontal => child.width(),
Axis::Vertical => child.height(),
@@ -97,7 +107,7 @@ where
let available = axis.main(limits.max());
let remaining = (available - total_non_fill).max(0.0);
- for (i, child) in children.iter().enumerate() {
+ for (i, child) in items.iter().enumerate() {
let fill_factor = match axis {
Axis::Horizontal => child.width(),
Axis::Vertical => child.height(),
diff --git a/native/src/layout/limits.rs b/native/src/layout/limits.rs
index af269acd..2705a47d 100644
--- a/native/src/layout/limits.rs
+++ b/native/src/layout/limits.rs
@@ -1,5 +1,6 @@
use crate::{Length, Size};
+/// A set of size constraints for layouting.
#[derive(Debug, Clone, Copy)]
pub struct Limits {
min: Size,
@@ -8,12 +9,17 @@ pub struct Limits {
}
impl Limits {
+ /// No limits
pub const NONE: Limits = Limits {
min: Size::ZERO,
max: Size::INFINITY,
fill: Size::INFINITY,
};
+ /// Creates new [`Limits`] with the given minimum and maximum [`Size`].
+ ///
+ /// [`Limits`]: struct.Limits.html
+ /// [`Size`]: ../struct.Size.html
pub fn new(min: Size, max: Size) -> Limits {
Limits {
min,
@@ -22,14 +28,25 @@ impl Limits {
}
}
+ /// Returns the minimum [`Size`] of the [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
+ /// [`Size`]: ../struct.Size.html
pub fn min(&self) -> Size {
self.min
}
+ /// Returns the maximum [`Size`] of the [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
+ /// [`Size`]: ../struct.Size.html
pub fn max(&self) -> Size {
self.max
}
+ /// Applies a width constraint to the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn width(mut self, width: Length) -> Limits {
match width {
Length::Shrink => {
@@ -51,6 +68,9 @@ impl Limits {
self
}
+ /// Applies a height constraint to the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn height(mut self, height: Length) -> Limits {
match height {
Length::Shrink => {
@@ -72,6 +92,9 @@ impl Limits {
self
}
+ /// Applies a minimum width constraint to the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn min_width(mut self, min_width: u32) -> Limits {
self.min.width =
self.min.width.max(min_width as f32).min(self.max.width);
@@ -79,6 +102,9 @@ impl Limits {
self
}
+ /// Applies a maximum width constraint to the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn max_width(mut self, max_width: u32) -> Limits {
self.max.width =
self.max.width.min(max_width as f32).max(self.min.width);
@@ -86,6 +112,19 @@ impl Limits {
self
}
+ /// Applies a minimum height constraint to the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
+ pub fn min_height(mut self, min_height: u32) -> Limits {
+ self.min.height =
+ self.min.height.max(min_height as f32).min(self.max.height);
+
+ self
+ }
+
+ /// Applies a maximum height constraint to the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn max_height(mut self, max_height: u32) -> Limits {
self.max.height =
self.max.height.min(max_height as f32).max(self.min.height);
@@ -93,10 +132,17 @@ impl Limits {
self
}
+ /// Shrinks the current [`Limits`] to account for the given padding.
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn pad(&self, padding: f32) -> Limits {
self.shrink(Size::new(padding * 2.0, padding * 2.0))
}
+ /// Shrinks the current [`Limits`] by the given [`Size`].
+ ///
+ /// [`Limits`]: struct.Limits.html
+ /// [`Size`]: ../struct.Size.html
pub fn shrink(&self, size: Size) -> Limits {
let min = Size::new(
(self.min().width - size.width).max(0.0),
@@ -116,6 +162,9 @@ impl Limits {
Limits { min, max, fill }
}
+ /// Removes the minimum width constraint for the current [`Limits`].
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn loose(&self) -> Limits {
Limits {
min: Size::ZERO,
@@ -124,6 +173,10 @@ impl Limits {
}
}
+ /// Computes the resulting [`Size`] that fits the [`Limits`] given the
+ /// intrinsic size of some content.
+ ///
+ /// [`Limits`]: struct.Limits.html
pub fn resolve(&self, intrinsic_size: Size) -> Size {
Size::new(
intrinsic_size
diff --git a/native/src/layout/node.rs b/native/src/layout/node.rs
index 64ebf2d0..ed1cd3da 100644
--- a/native/src/layout/node.rs
+++ b/native/src/layout/node.rs
@@ -1,16 +1,25 @@
use crate::{Align, Rectangle, Size};
+/// The bounds of an element and its children.
#[derive(Debug, Clone, Default)]
pub struct Node {
- pub bounds: Rectangle,
+ pub(crate) bounds: Rectangle,
children: Vec<Node>,
}
impl Node {
+ /// Creates a new [`Node`] with the given [`Size`].
+ ///
+ /// [`Node`]: struct.Node.html
+ /// [`Size`]: ../struct.Size.html
pub fn new(size: Size) -> Self {
Self::with_children(size, Vec::new())
}
+ /// Creates a new [`Node`] with the given [`Size`] and children.
+ ///
+ /// [`Node`]: struct.Node.html
+ /// [`Size`]: ../struct.Size.html
pub fn with_children(size: Size, children: Vec<Node>) -> Self {
Node {
bounds: Rectangle {
@@ -23,19 +32,29 @@ impl Node {
}
}
+ /// Returns the [`Size`] of the [`Node`].
+ ///
+ /// [`Node`]: struct.Node.html
+ /// [`Size`]: ../struct.Size.html
pub fn size(&self) -> Size {
Size::new(self.bounds.width, self.bounds.height)
}
+ /// Returns the bounds of the [`Node`].
+ ///
+ /// [`Node`]: struct.Node.html
pub fn bounds(&self) -> Rectangle {
self.bounds
}
+ /// Returns the children of the [`Node`].
+ ///
+ /// [`Node`]: struct.Node.html
pub fn children(&self) -> &[Node] {
&self.children
}
- pub fn align(
+ pub(crate) fn align(
&mut self,
horizontal_alignment: Align,
vertical_alignment: Align,
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 55331ba5..57d014b6 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -1,162 +1,34 @@
-//! Iced is a renderer-agnostic GUI library focused on simplicity and
-//! type-safety. Inspired by [Elm].
+//! A renderer-agnostic native GUI runtime.
//!
-//! # Features
-//! * Simple, easy-to-use, renderer-agnostic API
-//! * Responsive, flexbox-based layouting
-//! * Type-safe, reactive programming model
-//! * Built-in widgets
-//! * Custom widget support
+//! ![`iced_native` crate graph](https://github.com/hecrj/iced/blob/cae26cb7bc627f4a5b3bcf1cd023a0c552e8c65e/docs/graphs/native.png?raw=true)
//!
-//! Check out the [repository] and the [examples] for more details!
+//! `iced_native` takes [`iced_core`] and builds a native runtime on top of it,
+//! featuring:
//!
-//! [examples]: https://github.com/hecrj/iced/tree/0.1.0/examples
-//! [repository]: https://github.com/hecrj/iced
+//! - A custom layout engine, greatly inspired by [`druid`]
+//! - Event handling for all the built-in widgets
+//! - A renderer-agnostic API
//!
-//! # Usage
-//! Inspired by [The Elm Architecture], Iced expects you to split user
-//! interfaces into four different concepts:
-//!
-//! * __State__ — the state of your application
-//! * __Messages__ — user interactions or meaningful events that you care
-//! about
-//! * __View logic__ — a way to display your __state__ as widgets that
-//! may produce __messages__ on user interaction
-//! * __Update logic__ — a way to react to __messages__ and update your
-//! __state__
-//!
-//! We can build something to see how this works! Let's say we want a simple
-//! counter that can be incremented and decremented using two buttons.
-//!
-//! We start by modelling the __state__ of our application:
-//!
-//! ```
-//! use iced_native::button;
-//!
-//! struct Counter {
-//! // The counter value
-//! value: i32,
-//!
-//! // The local state of the two buttons
-//! increment_button: button::State,
-//! decrement_button: button::State,
-//! }
-//! ```
-//!
-//! Next, we need to define the possible user interactions of our counter:
-//! the button presses. These interactions are our __messages__:
-//!
-//! ```
-//! #[derive(Debug, Clone, Copy)]
-//! pub enum Message {
-//! IncrementPressed,
-//! DecrementPressed,
-//! }
-//! ```
+//! To achieve this, it introduces a bunch of reusable interfaces:
//!
-//! Now, let's show the actual counter by putting it all together in our
-//! __view logic__:
-//!
-//! ```
-//! # use iced_native::button;
-//! #
-//! # struct Counter {
-//! # // The counter value
-//! # value: i32,
-//! #
-//! # // The local state of the two buttons
-//! # increment_button: button::State,
-//! # decrement_button: button::State,
-//! # }
-//! #
-//! # #[derive(Debug, Clone, Copy)]
-//! # pub enum Message {
-//! # IncrementPressed,
-//! # DecrementPressed,
-//! # }
-//! #
-//! # mod iced_wgpu {
-//! # pub use iced_native::renderer::Null as Renderer;
-//! # }
-//! use iced_native::{Button, Column, Text};
-//! use iced_wgpu::Renderer; // Iced does not include a renderer! We need to bring our own!
-//!
-//! impl Counter {
-//! pub fn view(&mut self) -> Column<Message, Renderer> {
-//! // We use a column: a simple vertical layout
-//! Column::new()
-//! .push(
-//! // The increment button. We tell it to produce an
-//! // `IncrementPressed` message when pressed
-//! Button::new(&mut self.increment_button, Text::new("+"))
-//! .on_press(Message::IncrementPressed),
-//! )
-//! .push(
-//! // We show the value of the counter here
-//! Text::new(&self.value.to_string()).size(50),
-//! )
-//! .push(
-//! // The decrement button. We tell it to produce a
-//! // `DecrementPressed` message when pressed
-//! Button::new(&mut self.decrement_button, Text::new("-"))
-//! .on_press(Message::DecrementPressed),
-//! )
-//! }
-//! }
-//! ```
-//!
-//! Finally, we need to be able to react to any produced __messages__ and change
-//! our __state__ accordingly in our __update logic__:
-//!
-//! ```
-//! # use iced_native::button;
-//! #
-//! # struct Counter {
-//! # // The counter value
-//! # value: i32,
-//! #
-//! # // The local state of the two buttons
-//! # increment_button: button::State,
-//! # decrement_button: button::State,
-//! # }
-//! #
-//! # #[derive(Debug, Clone, Copy)]
-//! # pub enum Message {
-//! # IncrementPressed,
-//! # DecrementPressed,
-//! # }
-//! impl Counter {
-//! // ...
-//!
-//! pub fn update(&mut self, message: Message) {
-//! match message {
-//! Message::IncrementPressed => {
-//! self.value += 1;
-//! }
-//! Message::DecrementPressed => {
-//! self.value -= 1;
-//! }
-//! }
-//! }
-//! }
-//! ```
-//!
-//! 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.
-//! 1. Process events from our system and produce __messages__ for our
-//! __update logic__.
-//! 1. Draw the resulting user interface using our chosen __renderer__.
+//! - A [`Widget`] trait, which is used to implement new widgets: from layout
+//! requirements to event and drawing logic.
+//! - A bunch of `Renderer` traits, meant to keep the crate renderer-agnostic.
+//! - A [`Windowed`] trait, leveraging [`raw-window-handle`], which can be
+//! implemented by graphical renderers that target _windows_. Window-based
+//! shells (like [`iced_winit`]) can use this trait to stay renderer-agnostic.
//!
+//! # Usage
//! Check out the [`UserInterface`] type to learn how to wire everything up!
//!
-//! [Elm]: https://elm-lang.org/
-//! [The Elm Architecture]: https://guide.elm-lang.org/architecture/
-//! [documentation]: https://docs.rs/iced
-//! [examples]: https://github.com/hecrj/iced/tree/master/examples
+//! [`iced_core`]: https://github.com/hecrj/iced/tree/master/core
+//! [`iced_winit`]: https://github.com/hecrj/iced/tree/master/winit
+//! [`druid`]: https://github.com/xi-editor/druid
+//! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle
+//! [`Widget`]: widget/trait.Widget.html
+//! [`Windowed`]: renderer/trait.Windowed.html
//! [`UserInterface`]: struct.UserInterface.html
-//#![deny(missing_docs)]
+#![deny(missing_docs)]
//#![deny(missing_debug_implementations)]
#![deny(unused_results)]
#![deny(unsafe_code)]
diff --git a/native/src/renderer.rs b/native/src/renderer.rs
index 3e19be33..7a68ada4 100644
--- a/native/src/renderer.rs
+++ b/native/src/renderer.rs
@@ -32,9 +32,21 @@ pub use windowed::{Target, Windowed};
use crate::{layout, Element};
+/// A component that can take the state of a user interface and produce an
+/// output for its users.
pub trait Renderer: Sized {
+ /// The type of output of the [`Renderer`].
+ ///
+ /// If you are implementing a graphical renderer, your output will most
+ /// likely be a tree of visual primitives.
+ ///
+ /// [`Renderer`]: trait.Renderer.html
type Output;
+ /// Lays out the elements of a user interface.
+ ///
+ /// You should override this if you need to perform any operations before or
+ /// after layouting. For instance, trimming the measurements cache.
fn layout<'a, Message>(
&mut self,
element: &Element<'a, Message, Self>,
diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs
index 8933b09b..3334e6b6 100644
--- a/native/src/renderer/null.rs
+++ b/native/src/renderer/null.rs
@@ -4,6 +4,7 @@ use crate::{
Rectangle, Renderer, Size, VerticalAlignment,
};
+/// A renderer that does nothing.
pub struct Null;
impl Renderer for Null {
diff --git a/native/src/renderer/windowed.rs b/native/src/renderer/windowed.rs
index 6d0419d2..813a03f2 100644
--- a/native/src/renderer/windowed.rs
+++ b/native/src/renderer/windowed.rs
@@ -2,11 +2,21 @@ use crate::MouseCursor;
use raw_window_handle::HasRawWindowHandle;
+/// A renderer that can target windows.
pub trait Windowed: super::Renderer + Sized {
+ /// The type of target.
type Target: Target<Renderer = Self>;
+ /// Creates a new [`Windowed`] renderer.
+ ///
+ /// [`Windowed`]: trait.Windowed.html
fn new() -> Self;
+ /// Performs the drawing operations described in the output on the given
+ /// target.
+ ///
+ /// The overlay can be a bunch of debug text logs. It should be rendered on
+ /// top of the GUI on most scenarios.
fn draw<T: AsRef<str>>(
&mut self,
output: &Self::Output,
@@ -15,9 +25,15 @@ pub trait Windowed: super::Renderer + Sized {
) -> MouseCursor;
}
+/// A rendering target.
pub trait Target {
+ /// The renderer of this target.
type Renderer;
+ /// Creates a new rendering [`Target`] from the given window handle, width,
+ /// height and dpi factor.
+ ///
+ /// [`Target`]: trait.Target.html
fn new<W: HasRawWindowHandle>(
window: &W,
width: u16,
@@ -26,6 +42,9 @@ pub trait Target {
renderer: &Self::Renderer,
) -> Self;
+ /// Resizes the current [`Target`].
+ ///
+ /// [`Target`]: trait.Target.html
fn resize(
&mut self,
width: u16,
diff --git a/native/src/size.rs b/native/src/size.rs
index bd909292..30e2a57e 100644
--- a/native/src/size.rs
+++ b/native/src/size.rs
@@ -1,5 +1,6 @@
use std::f32;
+/// An amount of space in 2 dimensions.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Size {
/// The width.
@@ -9,13 +10,26 @@ pub struct Size {
}
impl Size {
+ /// A [`Size`] with zero width and height.
+ ///
+ /// [`Size`]: struct.Size.html
pub const ZERO: Size = Size::new(0., 0.);
+
+ /// A [`Size`] with infinite width and height.
+ ///
+ /// [`Size`]: struct.Size.html
pub const INFINITY: Size = Size::new(f32::INFINITY, f32::INFINITY);
+ /// A [`Size`] of infinite width and height.
+ ///
+ /// [`Size`]: struct.Size.html
pub const fn new(width: f32, height: f32) -> Self {
Size { width, height }
}
+ /// Increments the [`Size`] to account for the given padding.
+ ///
+ /// [`Size`]: struct.Size.html
pub fn pad(&self, padding: f32) -> Self {
Size {
width: self.width + padding * 2.0,
diff --git a/native/src/widget.rs b/native/src/widget.rs
index 61b66c5b..48605ee3 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -23,6 +23,7 @@
pub mod button;
pub mod checkbox;
pub mod column;
+pub mod container;
pub mod image;
pub mod radio;
pub mod row;
@@ -31,8 +32,6 @@ pub mod slider;
pub mod text;
pub mod text_input;
-mod container;
-
#[doc(no_inline)]
pub use button::Button;
#[doc(no_inline)]
@@ -69,8 +68,14 @@ pub trait Widget<Message, Renderer>
where
Renderer: crate::Renderer,
{
+ /// Returns the width of the [`Widget`].
+ ///
+ /// [`Widget`]: trait.Widget.html
fn width(&self) -> Length;
+ /// Returns the height of the [`Widget`].
+ ///
+ /// [`Widget`]: trait.Widget.html
fn height(&self) -> Length;
/// Returns the [`Node`] of the [`Widget`].
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index f7bda146..8101e6be 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -166,15 +166,18 @@ where
/// [`Checkbox`]: struct.Checkbox.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer {
+ /// Returns the default size of a [`Checkbox`].
+ ///
+ /// [`Checkbox`]: struct.Checkbox.html
fn default_size(&self) -> u32;
/// Draws a [`Checkbox`].
///
/// It receives:
- /// * the current cursor position
/// * the bounds of the [`Checkbox`]
- /// * the bounds of the label of the [`Checkbox`]
- /// * whether the [`Checkbox`] is checked or not
+ /// * whether the [`Checkbox`] is selected or not
+ /// * whether the mouse is over the [`Checkbox`] or not
+ /// * the drawn label of the [`Checkbox`]
///
/// [`Checkbox`]: struct.Checkbox.html
fn draw(
diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs
index 87c51f48..281437fd 100644
--- a/native/src/widget/column.rs
+++ b/native/src/widget/column.rs
@@ -1,3 +1,4 @@
+//! Distribute content vertically.
use std::hash::Hash;
use crate::{
@@ -189,7 +190,23 @@ where
}
}
+/// The renderer of a [`Column`].
+///
+/// Your [renderer] will need to implement this trait before being
+/// able to use a [`Column`] in your user interface.
+///
+/// [`Column`]: struct.Column.html
+/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer + Sized {
+ /// Draws a [`Column`].
+ ///
+ /// It receives:
+ /// - the children of the [`Column`]
+ /// - the [`Layout`] of the [`Column`] and its children
+ /// - the cursor position
+ ///
+ /// [`Column`]: struct.Row.html
+ /// [`Layout`]: ../layout/struct.Layout.html
fn draw<Message>(
&mut self,
content: &[Element<'_, Message, Self>],
diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs
index 2f15573d..64a5f4da 100644
--- a/native/src/widget/container.rs
+++ b/native/src/widget/container.rs
@@ -1,3 +1,4 @@
+//! Decorate content and apply alignment.
use std::hash::Hash;
use crate::{
diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs
index 696de683..c64f07b1 100644
--- a/native/src/widget/image.rs
+++ b/native/src/widget/image.rs
@@ -116,6 +116,9 @@ where
/// [`Image`]: struct.Image.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer {
+ /// Returns the dimensions of an [`Image`] located on the given path.
+ ///
+ /// [`Image`]: struct.Image.html
fn dimensions(&self, path: &str) -> (u32, u32);
/// Draws an [`Image`].
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index 3dc764fe..4e48728f 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -174,15 +174,18 @@ where
/// [`Radio`]: struct.Radio.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer {
+ /// Returns the default size of a [`Radio`] button.
+ ///
+ /// [`Radio`]: struct.Radio.html
fn default_size(&self) -> u32;
/// Draws a [`Radio`] button.
///
/// It receives:
- /// * the current cursor position
/// * the bounds of the [`Radio`]
- /// * the bounds of the label of the [`Radio`]
/// * whether the [`Radio`] is selected or not
+ /// * whether the mouse is over the [`Radio`] or not
+ /// * the drawn label of the [`Radio`]
///
/// [`Radio`]: struct.Radio.html
fn draw(
diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs
index 33222b8a..34c7ca7c 100644
--- a/native/src/widget/row.rs
+++ b/native/src/widget/row.rs
@@ -1,3 +1,4 @@
+//! Distribute content horizontally.
use std::hash::Hash;
use crate::{
@@ -192,7 +193,23 @@ where
}
}
+/// The renderer of a [`Row`].
+///
+/// Your [renderer] will need to implement this trait before being
+/// able to use a [`Row`] in your user interface.
+///
+/// [`Row`]: struct.Row.html
+/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer + Sized {
+ /// Draws a [`Row`].
+ ///
+ /// It receives:
+ /// - the children of the [`Row`]
+ /// - the [`Layout`] of the [`Row`] and its children
+ /// - the cursor position
+ ///
+ /// [`Row`]: struct.Row.html
+ /// [`Layout`]: ../layout/struct.Layout.html
fn draw<Message>(
&mut self,
children: &[Element<'_, Message, Self>],
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs
index 438f04cf..7b231b5f 100644
--- a/native/src/widget/scrollable.rs
+++ b/native/src/widget/scrollable.rs
@@ -1,3 +1,4 @@
+//! Navigate an endless amount of content with a scrollbar.
use crate::{
column,
input::{mouse, ButtonState},
@@ -361,7 +362,18 @@ impl State {
}
}
+/// The renderer of a [`Scrollable`].
+///
+/// Your [renderer] will need to implement this trait before being
+/// able to use a [`Scrollable`] in your user interface.
+///
+/// [`Scrollable`]: struct.Scrollable.html
+/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer + Sized {
+ /// Returns whether the mouse is over the scrollbar given the bounds of
+ /// the [`Scrollable`] and its contents.
+ ///
+ /// [`Scrollable`]: struct.Scrollable.html
fn is_mouse_over_scrollbar(
&self,
bounds: Rectangle,
@@ -369,6 +381,18 @@ pub trait Renderer: crate::Renderer + Sized {
cursor_position: Point,
) -> bool;
+ /// Draws the [`Scrollable`].
+ ///
+ /// It receives:
+ /// - the [`State`] of the [`Scrollable`]
+ /// - the bounds of the [`Scrollable`]
+ /// - whether the mouse is over the [`Scrollable`] or not
+ /// - whether the mouse is over the scrollbar or not
+ /// - the scrolling offset
+ /// - the drawn content
+ ///
+ /// [`Scrollable`]: struct.Scrollable.html
+ /// [`State`]: struct.State.html
fn draw(
&mut self,
scrollable: &State,
diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs
index 113cc2a4..fe503c34 100644
--- a/native/src/widget/slider.rs
+++ b/native/src/widget/slider.rs
@@ -13,6 +13,28 @@ use crate::{
use std::{hash::Hash, ops::RangeInclusive};
+/// An horizontal bar and a handle that selects a single value from a range of
+/// values.
+///
+/// A [`Slider`] will try to fill the horizontal space of its container.
+///
+/// [`Slider`]: struct.Slider.html
+///
+/// # Example
+/// ```
+/// # use iced_native::{slider, Slider};
+/// #
+/// 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 drawn by Coffee's renderer](https://github.com/hecrj/coffee/blob/bda9818f823dfcb8a7ad0ff4940b4d4b387b5208/images/ui/slider.png?raw=true)
pub struct Slider<'a, Message> {
state: &'a mut State,
range: RangeInclusive<f32>,
@@ -180,6 +202,9 @@ where
/// [`Slider`]: struct.Slider.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer {
+ /// Returns the height of the [`Slider`].
+ ///
+ /// [`Slider`]: struct.Slider.html
fn height(&self) -> u32;
/// Draws a [`Slider`].
diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs
index c4ab88d3..cf0701b9 100644
--- a/native/src/widget/text.rs
+++ b/native/src/widget/text.rs
@@ -32,9 +32,9 @@ impl Text {
/// Create a new fragment of [`Text`] with the given contents.
///
/// [`Text`]: struct.Text.html
- pub fn new(label: &str) -> Self {
+ pub fn new<T: Into<String>>(label: T) -> Self {
Text {
- content: String::from(label),
+ content: label.into(),
size: None,
color: None,
font: Font::Default,
@@ -174,8 +174,15 @@ where
/// [renderer]: ../../renderer/index.html
/// [`UserInterface`]: ../../struct.UserInterface.html
pub trait Renderer: crate::Renderer {
+ /// Returns the default size of the [`Text`].
+ ///
+ /// [`Text`]: struct.Text.html
fn default_size(&self) -> u16;
+ /// Measures the [`Text`] in the given bounds and returns the minimum
+ /// boundaries that can fit the contents.
+ ///
+ /// [`Text`]: struct.Text.html
fn measure(
&self,
content: &str,
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index 65306504..c3876b1d 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -10,7 +10,26 @@ use crate::{
Widget,
};
-/// A widget that can be filled with text by using a keyboard.
+/// A field that can be filled with text.
+///
+/// # Example
+/// ```
+/// # use iced_native::{text_input, TextInput};
+/// #
+/// 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,
+/// );
+/// ```
pub struct TextInput<'a, Message> {
state: &'a mut State,
placeholder: String,
@@ -26,7 +45,14 @@ pub struct TextInput<'a, Message> {
impl<'a, Message> TextInput<'a, Message> {
/// Creates a new [`TextInput`].
///
+ /// It expects:
+ /// - some [`State`]
+ /// - a placeholder
+ /// - the current value
+ /// - a function that produces a message when the [`TextInput`] changes
+ ///
/// [`TextInput`]: struct.TextInput.html
+ /// [`State`]: struct.State.html
pub fn new<F>(
state: &'a mut State,
placeholder: &str,
@@ -232,9 +258,32 @@ where
}
}
+/// The renderer of a [`TextInput`].
+///
+/// Your [renderer] will need to implement this trait before being
+/// able to use a [`TextInput`] in your user interface.
+///
+/// [`TextInput`]: struct.TextInput.html
+/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer + Sized {
+ /// Returns the default size of the text of the [`TextInput`].
+ ///
+ /// [`TextInput`]: struct.TextInput.html
fn default_size(&self) -> u16;
+ /// Draws a [`TextInput`].
+ ///
+ /// It receives:
+ /// - its bounds of the [`TextInput`]
+ /// - the bounds of the text (i.e. the current value)
+ /// - the cursor position
+ /// - the placeholder to show when the value is empty
+ /// - the current [`Value`]
+ /// - the current [`State`]
+ ///
+ /// [`TextInput`]: struct.TextInput.html
+ /// [`Value`]: struct.Value.html
+ /// [`State`]: struct.State.html
fn draw(
&mut self,
bounds: Rectangle,
@@ -289,6 +338,9 @@ impl State {
}
}
+ /// Returns whether the [`TextInput`] is currently focused or not.
+ ///
+ /// [`TextInput`]: struct.TextInput.html
pub fn is_focused(&self) -> bool {
self.is_focused
}
@@ -303,7 +355,7 @@ impl State {
/// Moves the cursor of a [`TextInput`] to the right.
///
/// [`TextInput`]: struct.TextInput.html
- pub fn move_cursor_right(&mut self, value: &Value) {
+ pub(crate) fn move_cursor_right(&mut self, value: &Value) {
let current = self.cursor_position(value);
if current < value.len() {
@@ -314,7 +366,7 @@ impl State {
/// Moves the cursor of a [`TextInput`] to the left.
///
/// [`TextInput`]: struct.TextInput.html
- pub fn move_cursor_left(&mut self, value: &Value) {
+ pub(crate) fn move_cursor_left(&mut self, value: &Value) {
let current = self.cursor_position(value);
if current > 0 {
@@ -325,7 +377,7 @@ impl State {
/// Moves the cursor of a [`TextInput`] to the end.
///
/// [`TextInput`]: struct.TextInput.html
- pub fn move_cursor_to_end(&mut self, value: &Value) {
+ pub(crate) fn move_cursor_to_end(&mut self, value: &Value) {
self.cursor_position = value.len();
}
}