diff --git a/core/src/background.rs b/core/src/background.rs index 59b67a2c..98047172 100644 --- a/core/src/background.rs +++ b/core/src/background.rs @@ -1,7 +1,9 @@ use crate::Color; +/// The background of some element. #[derive(Debug, Clone, Copy, PartialEq)] pub enum Background { + /// A solid color Color(Color), // TODO: Add gradient and image variants } diff --git a/core/src/color.rs b/core/src/color.rs index 150bd05b..ec48c185 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -25,6 +25,9 @@ impl Color { a: 1.0, }; + /// Converts the [`Color`] into its linear values. + /// + /// [`Color`]: struct.Color.html pub fn into_linear(self) -> [f32; 4] { // As described in: // https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation diff --git a/core/src/command.rs b/core/src/command.rs index e1c865dd..698105aa 100644 --- a/core/src/command.rs +++ b/core/src/command.rs @@ -1,16 +1,30 @@ use futures::future::{BoxFuture, Future, FutureExt}; +/// A collection of async operations. +/// +/// You should be able to turn a future easily into a [`Command`], eiter by +/// using the `From` trait or [`Command::perform`]. +/// +/// [`Command`]: struct.Command.html pub struct Command { futures: Vec>, } impl Command { + /// Creates an empty [`Command`]. + /// + /// In other words, a [`Command`] that does nothing. + /// + /// [`Command`]: struct.Command.html pub fn none() -> Self { Self { futures: Vec::new(), } } + /// Creates a [`Command`] that performs the action of the given future. + /// + /// [`Command`]: struct.Command.html pub fn perform( future: impl Future + 'static + Send, f: impl Fn(T) -> A + 'static + Send, @@ -20,12 +34,21 @@ impl Command { } } + /// Creates a [`Command`] that performs the actions of all the givens + /// futures. + /// + /// Once this command is run, all the futures will be exectued at once. + /// + /// [`Command`]: struct.Command.html pub fn batch(commands: impl Iterator>) -> Self { Self { futures: commands.flat_map(|command| command.futures).collect(), } } + /// Converts a [`Command`] into its underlying list of futures. + /// + /// [`Command`]: struct.Command.html pub fn futures(self) -> Vec> { self.futures } diff --git a/core/src/font.rs b/core/src/font.rs index 75ba6a72..be49c825 100644 --- a/core/src/font.rs +++ b/core/src/font.rs @@ -1,8 +1,18 @@ +/// A font. #[derive(Debug, Clone, Copy)] pub enum Font { + /// The default font. + /// + /// This is normally a font configured in a renderer or loaded from the + /// system. Default, + + /// An external font. External { + /// The name of the external font name: &'static str, + + /// The bytes of the external font bytes: &'static [u8], }, } diff --git a/core/src/length.rs b/core/src/length.rs index 73c227d8..63ba6207 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -1,12 +1,24 @@ /// The strategy used to fill space in a specific dimension. #[derive(Debug, Clone, Copy, PartialEq, Hash)] pub enum Length { + /// Fill all the remaining space Fill, + + /// Fill the least amount of space Shrink, + + /// Fill a fixed amount of space Units(u16), } impl Length { + /// Returns the _fill factor_ of the [`Length`]. + /// + /// The _fill factor_ is a relative unit describing how much of the + /// remaining space should be filled when compared to other elements. It + /// is only meant to be used by layout engines. + /// + /// [`Length`]: enum.Length.html pub fn fill_factor(&self) -> u16 { match self { Length::Fill => 1, diff --git a/core/src/lib.rs b/core/src/lib.rs index 3816f8a2..692e40d4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,10 +1,22 @@ +//! The core library of [Iced]. +//! +//! This library holds basic types that can be reused and re-exported in +//! different runtime implementations. For instance, both [`iced_native`] and +//! [`iced_web`] are built on top of `iced_core`. +//! +//! [Iced]: https://github.com/hecrj/iced +//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native +//! [`iced_web`]: https://github.com/hecrj/iced/tree/master/web +#![deny(missing_docs)] +#![deny(missing_debug_implementations)] +#![deny(unused_results)] +#![deny(unsafe_code)] +#![deny(rust_2018_idioms)] pub mod widget; mod align; mod background; mod color; -#[cfg(feature = "command")] -mod command; mod font; mod length; mod point; @@ -14,11 +26,15 @@ mod vector; pub use align::Align; pub use background::Background; pub use color::Color; -#[cfg(feature = "command")] -pub use command::Command; pub use font::Font; pub use length::Length; pub use point::Point; pub use rectangle::Rectangle; pub use vector::Vector; pub use widget::*; + +#[cfg(feature = "command")] +mod command; + +#[cfg(feature = "command")] +pub use command::Command; diff --git a/core/src/vector.rs b/core/src/vector.rs index 92bf64ff..7d87343a 100644 --- a/core/src/vector.rs +++ b/core/src/vector.rs @@ -1,7 +1,14 @@ /// A 2D vector. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Vector { + /// The X component of the [`Vector`] + /// + /// [`Vector`]: struct.Vector.html pub x: T, + + /// The Y component of the [`Vector`] + /// + /// [`Vector`]: struct.Vector.html pub y: T, } diff --git a/core/src/widget/button.rs b/core/src/widget/button.rs index e7961284..0ac88671 100644 --- a/core/src/widget/button.rs +++ b/core/src/widget/button.rs @@ -8,40 +8,22 @@ use crate::{Background, Length}; /// A generic widget that produces a message when clicked. +#[allow(missing_docs)] +#[derive(Debug)] pub struct Button<'a, Message, Element> { - /// The current state of the button pub state: &'a mut State, - pub content: Element, - - /// The message to produce when the button is pressed pub on_press: Option, - pub width: Length, - pub min_width: u32, - pub padding: u16, - pub background: Option, - pub border_radius: u16, } -impl<'a, Message, Element> std::fmt::Debug for Button<'a, Message, Element> -where - Message: std::fmt::Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Button") - .field("state", &self.state) - .field("on_press", &self.on_press) - .finish() - } -} - impl<'a, Message, Element> Button<'a, Message, Element> { - /// Creates a new [`Button`] with some local [`State`] and the given label. + /// Creates a new [`Button`] with some local [`State`] and the given + /// content. /// /// [`Button`]: struct.Button.html /// [`State`]: struct.State.html @@ -69,21 +51,34 @@ impl<'a, Message, Element> Button<'a, Message, Element> { self } + /// Sets the minimum width of the [`Button`]. + /// + /// [`Button`]: struct.Button.html pub fn min_width(mut self, min_width: u32) -> Self { self.min_width = min_width; self } + /// Sets the padding of the [`Button`]. + /// + /// [`Button`]: struct.Button.html pub fn padding(mut self, padding: u16) -> Self { self.padding = padding; self } + /// Sets the [`Background`] of the [`Button`]. + /// + /// [`Button`]: struct.Button.html + /// [`Background`]: ../../struct.Background.html pub fn background(mut self, background: Background) -> Self { self.background = Some(background); self } + /// Sets the border radius of the [`Button`]. + /// + /// [`Button`]: struct.Button.html pub fn border_radius(mut self, border_radius: u16) -> Self { self.border_radius = border_radius; self @@ -103,6 +98,9 @@ impl<'a, Message, Element> Button<'a, Message, Element> { /// [`Button`]: struct.Button.html #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct State { + /// Whether the [`Button`] is currently being pressed. + /// + /// [`Button`]: struct.Button.html pub is_pressed: bool, } @@ -113,12 +111,4 @@ impl State { pub fn new() -> State { State::default() } - - /// Returns whether the associated [`Button`] is currently being pressed or - /// not. - /// - /// [`Button`]: struct.Button.html - pub fn is_pressed(&self) -> bool { - self.is_pressed - } } diff --git a/core/src/widget/column.rs b/core/src/widget/column.rs index 4a97ad98..34dbecf7 100644 --- a/core/src/widget/column.rs +++ b/core/src/widget/column.rs @@ -7,6 +7,7 @@ use std::u32; /// A [`Column`] will try to fill the horizontal space of its container. /// /// [`Column`]: struct.Column.html +#[allow(missing_docs)] pub struct Column { pub spacing: u16, pub padding: u16, diff --git a/core/src/widget/container.rs b/core/src/widget/container.rs index 9bc92fe0..3fe340d1 100644 --- a/core/src/widget/container.rs +++ b/core/src/widget/container.rs @@ -2,7 +2,11 @@ use crate::{Align, Length}; use std::u32; +/// An element decorating some content. +/// +/// It is normally used for alignment purposes. #[derive(Debug)] +#[allow(missing_docs)] pub struct Container { pub width: Length, pub height: Length, diff --git a/core/src/widget/row.rs b/core/src/widget/row.rs index 3d882b47..d2b23bdb 100644 --- a/core/src/widget/row.rs +++ b/core/src/widget/row.rs @@ -7,6 +7,7 @@ use std::u32; /// A [`Row`] will try to fill the horizontal space of its container. /// /// [`Row`]: struct.Row.html +#[allow(missing_docs)] pub struct Row { pub spacing: u16, pub padding: u16, diff --git a/core/src/widget/scrollable.rs b/core/src/widget/scrollable.rs index 7f2f0e99..da03cd93 100644 --- a/core/src/widget/scrollable.rs +++ b/core/src/widget/scrollable.rs @@ -1,7 +1,11 @@ +//! Navigate an endless amount of content with a scrollbar. use crate::{Align, Column, Length, Point, Rectangle}; use std::u32; +/// A widget that can vertically display an infinite amount of content with a +/// scrollbar. +#[allow(missing_docs)] #[derive(Debug)] pub struct Scrollable<'a, Element> { pub state: &'a mut State, @@ -11,6 +15,10 @@ pub struct Scrollable<'a, Element> { } impl<'a, Element> Scrollable<'a, Element> { + /// Creates a new [`Scrollable`] with the given [`State`]. + /// + /// [`Scrollable`]: struct.Scrollable.html + /// [`State`]: struct.State.html pub fn new(state: &'a mut State) -> Self { Scrollable { state, @@ -90,17 +98,30 @@ impl<'a, Element> Scrollable<'a, Element> { } } +/// The local state of a [`Scrollable`]. +/// +/// [`Scrollable`]: struct.Scrollable.html #[derive(Debug, Clone, Copy, Default)] pub struct State { + /// The position where the scrollbar was grabbed at, if it's currently + /// grabbed. pub scrollbar_grabbed_at: Option, offset: u32, } impl State { + /// Creates a new [`State`] with the scrollbar located at the top. + /// + /// [`State`]: struct.State.html pub fn new() -> Self { State::default() } + /// Apply a scrolling offset to the current [`State`], given the bounds of + /// the [`Scrollable`] and its contents. + /// + /// [`Scrollable`]: struct.Scrollable.html + /// [`State`]: struct.State.html pub fn scroll( &mut self, delta_y: f32, @@ -117,6 +138,14 @@ impl State { as u32; } + /// Moves the scroll position to a relative amount, given the bounds of + /// the [`Scrollable`] and its contents. + /// + /// `0` represents scrollbar at the top, while `1` represents scrollbar at + /// the bottom. + /// + /// [`Scrollable`]: struct.Scrollable.html + /// [`State`]: struct.State.html pub fn scroll_to( &mut self, percentage: f32, @@ -127,6 +156,11 @@ impl State { .max(0.0) as u32; } + /// Returns the current scrolling offset of the [`State`], given the bounds + /// of the [`Scrollable`] and its contents. + /// + /// [`Scrollable`]: struct.Scrollable.html + /// [`State`]: struct.State.html pub fn offset(&self, bounds: Rectangle, content_bounds: Rectangle) -> u32 { let hidden_content = (content_bounds.height - bounds.height).max(0.0).round() as u32; @@ -134,6 +168,7 @@ impl State { self.offset.min(hidden_content) } + /// Returns whether the scrollbar is currently grabbed or not. pub fn is_scrollbar_grabbed(&self) -> bool { self.scrollbar_grabbed_at.is_some() } diff --git a/core/src/widget/slider.rs b/core/src/widget/slider.rs index b65e3991..d6fe8ade 100644 --- a/core/src/widget/slider.rs +++ b/core/src/widget/slider.rs @@ -31,19 +31,12 @@ use std::rc::Rc; /// ``` /// /// ![Slider drawn by Coffee's renderer](https://github.com/hecrj/coffee/blob/bda9818f823dfcb8a7ad0ff4940b4d4b387b5208/images/ui/slider.png?raw=true) +#[allow(missing_docs)] pub struct Slider<'a, Message> { - /// The state of the slider pub state: &'a mut State, - - /// The range of the slider pub range: RangeInclusive, - - /// The current value of the slider pub value: f32, - - /// The function to produce messages on change pub on_change: Rc Message>>, - pub width: Length, } @@ -53,6 +46,7 @@ impl<'a, Message> std::fmt::Debug for Slider<'a, Message> { .field("state", &self.state) .field("range", &self.range) .field("value", &self.value) + .field("width", &self.width) .finish() } } @@ -102,6 +96,9 @@ impl<'a, Message> Slider<'a, Message> { /// [`Slider`]: struct.Slider.html #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct State { + /// Whether the [`Slider`] is currently being dragged or not. + /// + /// [`Slider`]: struct.Slider.html pub is_dragging: bool, } diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 0996e7ff..1746160e 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -12,6 +12,7 @@ use crate::{Color, Font, Length}; /// .size(40); /// ``` #[derive(Debug, Clone)] +#[allow(missing_docs)] pub struct Text { pub content: String, pub size: Option, @@ -48,14 +49,19 @@ impl Text { self } - /// Sets the `Color` of the [`Text`]. + /// Sets the [`Color`] of the [`Text`]. /// /// [`Text`]: struct.Text.html + /// [`Color`]: ../../struct.Color.html pub fn color>(mut self, color: C) -> Self { self.color = Some(color.into()); self } + /// Sets the [`Font`] of the [`Text`]. + /// + /// [`Text`]: struct.Text.html + /// [`Font`]: ../../struct.Font.html pub fn font(mut self, font: Font) -> Self { self.font = font; self diff --git a/core/src/widget/text_input.rs b/core/src/widget/text_input.rs index 16c67954..df933380 100644 --- a/core/src/widget/text_input.rs +++ b/core/src/widget/text_input.rs @@ -1,5 +1,13 @@ +//! Display fields that can be filled with text. +//! +//! A [`TextInput`] has some local [`State`]. +//! +//! [`TextInput`]: struct.TextInput.html +//! [`State`]: struct.State.html use crate::Length; +/// A widget that can be filled with text by using a keyboard. +#[allow(missing_docs)] pub struct TextInput<'a, Message> { pub state: &'a mut State, pub placeholder: String, @@ -13,6 +21,9 @@ pub struct TextInput<'a, Message> { } impl<'a, Message> TextInput<'a, Message> { + /// Creates a new [`TextInput`]. + /// + /// [`TextInput`]: struct.TextInput.html pub fn new( state: &'a mut State, placeholder: &str, @@ -59,11 +70,18 @@ impl<'a, Message> TextInput<'a, Message> { self } + /// Sets the text size of the [`TextInput`]. + /// + /// [`TextInput`]: struct.TextInput.html pub fn size(mut self, size: u16) -> Self { self.size = Some(size); self } + /// Sets the message that should be produced when the [`TextInput`] is + /// focused and the enter key is pressed. + /// + /// [`TextInput`]: struct.TextInput.html pub fn on_submit(mut self, message: Message) -> Self { self.on_submit = Some(message); self @@ -80,17 +98,29 @@ where } } +/// The state of a [`TextInput`]. +/// +/// [`TextInput`]: struct.TextInput.html #[derive(Debug, Default, Clone)] pub struct State { + /// Whether the [`TextInput`] is focused or not. + /// + /// [`TextInput`]: struct.TextInput.html pub is_focused: bool, cursor_position: usize, } impl State { + /// Creates a new [`State`], representing an unfocused [`TextInput`]. + /// + /// [`State`]: struct.State.html pub fn new() -> Self { Self::default() } + /// Creates a new [`State`], representing a focused [`TextInput`]. + /// + /// [`State`]: struct.State.html pub fn focused() -> Self { use std::usize; @@ -100,6 +130,9 @@ impl State { } } + /// Moves the cursor of a [`TextInput`] to the right. + /// + /// [`TextInput`]: struct.TextInput.html pub fn move_cursor_right(&mut self, value: &Value) { let current = self.cursor_position(value); @@ -108,6 +141,9 @@ impl State { } } + /// Moves the cursor of a [`TextInput`] to the left. + /// + /// [`TextInput`]: struct.TextInput.html pub fn move_cursor_left(&mut self, value: &Value) { let current = self.cursor_position(value); @@ -116,41 +152,69 @@ 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) { self.cursor_position = value.len(); } + /// Returns the cursor position of a [`TextInput`]. + /// + /// [`TextInput`]: struct.TextInput.html pub fn cursor_position(&self, value: &Value) -> usize { self.cursor_position.min(value.len()) } } +/// The value of a [`TextInput`]. +/// +/// [`TextInput`]: struct.TextInput.html // TODO: Use `unicode-segmentation` +#[derive(Debug)] pub struct Value(Vec); impl Value { + /// Creates a new [`Value`] from a string slice. + /// + /// [`Value`]: struct.Value.html pub fn new(string: &str) -> Self { Self(string.chars().collect()) } + /// Returns the total amount of `char` in the [`Value`]. + /// + /// [`Value`]: struct.Value.html pub fn len(&self) -> usize { self.0.len() } + /// Returns a new [`Value`] containing the `char` until the given `index`. + /// + /// [`Value`]: struct.Value.html pub fn until(&self, index: usize) -> Self { Self(self.0[..index.min(self.len())].to_vec()) } + /// Converts the [`Value`] into a `String`. + /// + /// [`Value`]: struct.Value.html pub fn to_string(&self) -> String { use std::iter::FromIterator; String::from_iter(self.0.iter()) } + /// Inserts a new `char` at the given `index`. + /// + /// [`Value`]: struct.Value.html pub fn insert(&mut self, index: usize, c: char) { self.0.insert(index, c); } + /// Removes the `char` at the given `index`. + /// + /// [`Value`]: struct.Value.html pub fn remove(&mut self, index: usize) { - self.0.remove(index); + let _ = self.0.remove(index); } } diff --git a/rustfmt.toml b/rustfmt.toml index d979d317..7678b63c 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,2 @@ max_width=80 +wrap_comments=true