diff options
author | 2019-11-22 19:36:57 +0100 | |
---|---|---|
committer | 2019-11-22 19:36:57 +0100 | |
commit | a7dba612f03e58d7bd9527499d893987986b347c (patch) | |
tree | b8c3d8f997b714aa368bd6eaecf14065f7645c77 /native/src | |
parent | ba56a561b254c9a5f3d23cb54d23dc311759ab4c (diff) | |
download | iced-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.rs | 64 | ||||
-rw-r--r-- | native/src/input/mouse/event.rs | 8 | ||||
-rw-r--r-- | native/src/layout.rs | 16 | ||||
-rw-r--r-- | native/src/layout/flex.rs | 24 | ||||
-rw-r--r-- | native/src/layout/limits.rs | 53 | ||||
-rw-r--r-- | native/src/layout/node.rs | 23 | ||||
-rw-r--r-- | native/src/lib.rs | 172 | ||||
-rw-r--r-- | native/src/renderer.rs | 12 | ||||
-rw-r--r-- | native/src/renderer/null.rs | 1 | ||||
-rw-r--r-- | native/src/renderer/windowed.rs | 19 | ||||
-rw-r--r-- | native/src/size.rs | 14 | ||||
-rw-r--r-- | native/src/widget.rs | 9 | ||||
-rw-r--r-- | native/src/widget/checkbox.rs | 9 | ||||
-rw-r--r-- | native/src/widget/column.rs | 17 | ||||
-rw-r--r-- | native/src/widget/container.rs | 1 | ||||
-rw-r--r-- | native/src/widget/image.rs | 3 | ||||
-rw-r--r-- | native/src/widget/radio.rs | 7 | ||||
-rw-r--r-- | native/src/widget/row.rs | 17 | ||||
-rw-r--r-- | native/src/widget/scrollable.rs | 24 | ||||
-rw-r--r-- | native/src/widget/slider.rs | 25 | ||||
-rw-r--r-- | native/src/widget/text.rs | 11 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 60 |
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 +//!  //! -//! 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); +/// ``` +/// +///  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(); } } |