From 5d67f9988c14adfca4a7e67dc7a9ddcd860b1c78 Mon Sep 17 00:00:00 2001 From: Casper Rogild Storm <2248455+casperstorm@users.noreply.github.com> Date: Fri, 22 Apr 2022 13:35:53 +0200 Subject: Implemented Tooltip as Pure --- Cargo.toml | 1 + examples/pure/tooltip/Cargo.toml | 9 ++ examples/pure/tooltip/src/main.rs | 93 ++++++++++++ native/src/widget/tooltip.rs | 4 +- pure/src/helpers.rs | 11 ++ pure/src/widget.rs | 2 + pure/src/widget/tooltip.rs | 310 ++++++++++++++++++++++++++++++++++++++ src/pure/widget.rs | 10 ++ 8 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 examples/pure/tooltip/Cargo.toml create mode 100644 examples/pure/tooltip/src/main.rs create mode 100644 pure/src/widget/tooltip.rs diff --git a/Cargo.toml b/Cargo.toml index c6ccc5df..9c4b8181 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,6 +93,7 @@ members = [ "examples/pure/pick_list", "examples/pure/todos", "examples/pure/tour", + "examples/pure/tooltip", "examples/websocket", ] diff --git a/examples/pure/tooltip/Cargo.toml b/examples/pure/tooltip/Cargo.toml new file mode 100644 index 00000000..d84dfb37 --- /dev/null +++ b/examples/pure/tooltip/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "pure_tooltip" +version = "0.1.0" +authors = ["Héctor Ramón Jiménez ", "Casper Rogild Storm"] +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../../..", features = ["pure"] } diff --git a/examples/pure/tooltip/src/main.rs b/examples/pure/tooltip/src/main.rs new file mode 100644 index 00000000..dbd83f5f --- /dev/null +++ b/examples/pure/tooltip/src/main.rs @@ -0,0 +1,93 @@ +use iced::pure::{ + button, container, tooltip, widget::tooltip::Position, Element, Sandbox, +}; +use iced::{Length, Settings}; + +pub fn main() -> iced::Result { + Example::run(Settings::default()) +} + +struct Example { + position: Position, +} + +#[derive(Debug, Clone)] +enum Message { + ChangePosition, +} + +impl Sandbox for Example { + type Message = Message; + + fn new() -> Self { + Self { + position: Position::Bottom, + } + } + + fn title(&self) -> String { + String::from("Tooltip - Iced") + } + + fn update(&mut self, message: Message) { + match message { + Message::ChangePosition => { + let position = match &self.position { + Position::FollowCursor => Position::Top, + Position::Top => Position::Bottom, + Position::Bottom => Position::Left, + Position::Left => Position::Right, + Position::Right => Position::FollowCursor, + }; + + self.position = position + } + } + } + + fn view(&self) -> Element { + let tooltip = tooltip( + button("Press to change position") + .on_press(Message::ChangePosition), + position_to_text(self.position), + self.position, + ) + .gap(10) + .style(style::Tooltip); + + container(tooltip) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } +} + +fn position_to_text<'a>(position: Position) -> &'a str { + match position { + Position::FollowCursor => "Follow Cursor", + Position::Top => "Top", + Position::Bottom => "Bottom", + Position::Left => "Left", + Position::Right => "Right", + } +} + +mod style { + use iced::container; + use iced::Color; + + pub struct Tooltip; + + impl container::StyleSheet for Tooltip { + fn style(&self) -> container::Style { + container::Style { + text_color: Some(Color::from_rgb8(0xEE, 0xEE, 0xEE)), + background: Some(Color::from_rgb(0.11, 0.42, 0.87).into()), + border_radius: 12.0, + ..container::Style::default() + } + } + } +} diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs index 7989c768..253c26a3 100644 --- a/native/src/widget/tooltip.rs +++ b/native/src/widget/tooltip.rs @@ -273,8 +273,8 @@ where Message: 'a, { fn from( - column: Tooltip<'a, Message, Renderer>, + tooltip: Tooltip<'a, Message, Renderer>, ) -> Element<'a, Message, Renderer> { - Element::new(column) + Element::new(tooltip) } } diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs index 24f6dbaa..2ddab3ae 100644 --- a/pure/src/helpers.rs +++ b/pure/src/helpers.rs @@ -38,6 +38,17 @@ pub fn button<'a, Message, Renderer>( widget::Button::new(content) } +pub fn tooltip<'a, Message, Renderer>( + content: impl Into>, + tooltip: impl ToString, + position: widget::tooltip::Position, +) -> widget::Tooltip<'a, Message, Renderer> +where + Renderer: iced_native::text::Renderer, +{ + widget::Tooltip::new(content, tooltip, position) +} + pub fn text(text: impl Into) -> widget::Text where Renderer: iced_native::text::Renderer, diff --git a/pure/src/widget.rs b/pure/src/widget.rs index 8200f9a7..adce17ea 100644 --- a/pure/src/widget.rs +++ b/pure/src/widget.rs @@ -12,6 +12,7 @@ pub mod slider; pub mod svg; pub mod text_input; pub mod toggler; +pub mod tooltip; pub mod tree; mod column; @@ -37,6 +38,7 @@ pub use svg::Svg; pub use text::Text; pub use text_input::TextInput; pub use toggler::Toggler; +pub use tooltip::{Position, Tooltip}; pub use tree::Tree; use iced_native::event::{self, Event}; diff --git a/pure/src/widget/tooltip.rs b/pure/src/widget/tooltip.rs new file mode 100644 index 00000000..f0667e41 --- /dev/null +++ b/pure/src/widget/tooltip.rs @@ -0,0 +1,310 @@ +//! Display a widget over another. +use crate::widget::Tree; +use crate::{Element, Widget}; +use iced_native::event::{self, Event}; +use iced_native::widget::container; +pub use iced_native::widget::Text; +use iced_native::{layout, mouse, overlay}; +use iced_native::{renderer, Size}; +use iced_native::{text, Vector}; +use iced_native::{ + Clipboard, Layout, Length, Padding, Point, Rectangle, Shell, +}; + +pub use iced_style::container::{Style, StyleSheet}; + +/// An element to display a widget over another. +#[allow(missing_debug_implementations)] +pub struct Tooltip<'a, Message, Renderer: text::Renderer> { + content: Element<'a, Message, Renderer>, + tooltip: Text, + position: Position, + style_sheet: Box, + gap: u16, + padding: u16, +} + +impl<'a, Message, Renderer> Tooltip<'a, Message, Renderer> +where + Renderer: text::Renderer, +{ + /// The default padding of a [`Tooltip`] drawn by this renderer. + const DEFAULT_PADDING: u16 = 5; + + /// Creates an empty [`Tooltip`]. + /// + /// [`Tooltip`]: struct.Tooltip.html + pub fn new( + content: impl Into>, + tooltip: impl ToString, + position: Position, + ) -> Self { + Tooltip { + content: content.into(), + tooltip: Text::new(tooltip.to_string()), + position, + style_sheet: Default::default(), + gap: 0, + padding: Self::DEFAULT_PADDING, + } + } + + /// Sets the size of the text of the [`Tooltip`]. + pub fn size(mut self, size: u16) -> Self { + self.tooltip = self.tooltip.size(size); + self + } + + /// Sets the font of the [`Tooltip`]. + /// + /// [`Font`]: Renderer::Font + pub fn font(mut self, font: impl Into) -> Self { + self.tooltip = self.tooltip.font(font); + self + } + + /// Sets the gap between the content and its [`Tooltip`]. + pub fn gap(mut self, gap: u16) -> Self { + self.gap = gap; + self + } + + /// Sets the padding of the [`Tooltip`]. + pub fn padding(mut self, padding: u16) -> Self { + self.padding = padding; + self + } + + /// Sets the style of the [`Tooltip`]. + pub fn style( + mut self, + style_sheet: impl Into>, + ) -> Self { + self.style_sheet = style_sheet.into(); + self + } +} + +/// The position of the tooltip. Defaults to following the cursor. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Position { + /// The tooltip will follow the cursor. + FollowCursor, + /// The tooltip will appear on the top of the widget. + Top, + /// The tooltip will appear on the bottom of the widget. + Bottom, + /// The tooltip will appear on the left of the widget. + Left, + /// The tooltip will appear on the right of the widget. + Right, +} + +impl<'a, Message, Renderer> Widget + for Tooltip<'a, Message, Renderer> +where + Renderer: text::Renderer, +{ + fn children(&self) -> Vec { + vec![Tree::new(&self.content)] + } + + fn diff(&self, tree: &mut Tree) { + tree.diff_children(std::slice::from_ref(&self.content)) + } + + fn width(&self) -> Length { + self.content.as_widget().width() + } + + fn height(&self) -> Length { + self.content.as_widget().height() + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + self.content.as_widget().layout(renderer, limits) + } + + fn on_event( + &mut self, + tree: &mut Tree, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + ) -> event::Status { + self.content.as_widget_mut().on_event( + &mut tree.children[0], + event, + layout, + cursor_position, + renderer, + clipboard, + shell, + ) + } + + fn mouse_interaction( + &self, + tree: &Tree, + layout: Layout<'_>, + cursor_position: Point, + viewport: &Rectangle, + renderer: &Renderer, + ) -> mouse::Interaction { + self.content.as_widget().mouse_interaction( + &tree.children[0], + layout.children().next().unwrap(), + cursor_position, + viewport, + renderer, + ) + } + + fn draw( + &self, + tree: &Tree, + renderer: &mut Renderer, + inherited_style: &renderer::Style, + layout: Layout<'_>, + cursor_position: Point, + viewport: &Rectangle, + ) { + self.content.as_widget().draw( + &tree.children[0], + renderer, + inherited_style, + layout, + cursor_position, + viewport, + ); + + let bounds = layout.bounds(); + + if bounds.contains(cursor_position) { + let gap = f32::from(self.gap); + let style = self.style_sheet.style(); + + let defaults = renderer::Style { + text_color: style + .text_color + .unwrap_or(inherited_style.text_color), + }; + + let text_layout = Widget::<(), Renderer>::layout( + &self.tooltip, + renderer, + &layout::Limits::new(Size::ZERO, viewport.size()) + .pad(Padding::new(self.padding)), + ); + + let padding = f32::from(self.padding); + let text_bounds = text_layout.bounds(); + let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0; + let y_center = + bounds.y + (bounds.height - text_bounds.height) / 2.0; + + let mut tooltip_bounds = { + let offset = match self.position { + Position::Top => Vector::new( + x_center, + bounds.y - text_bounds.height - gap - padding, + ), + Position::Bottom => Vector::new( + x_center, + bounds.y + bounds.height + gap + padding, + ), + Position::Left => Vector::new( + bounds.x - text_bounds.width - gap - padding, + y_center, + ), + Position::Right => Vector::new( + bounds.x + bounds.width + gap + padding, + y_center, + ), + Position::FollowCursor => Vector::new( + cursor_position.x, + cursor_position.y - text_bounds.height, + ), + }; + + Rectangle { + x: offset.x - padding, + y: offset.y - padding, + width: text_bounds.width + padding * 2.0, + height: text_bounds.height + padding * 2.0, + } + }; + + if tooltip_bounds.x < viewport.x { + tooltip_bounds.x = viewport.x; + } else if viewport.x + viewport.width + < tooltip_bounds.x + tooltip_bounds.width + { + tooltip_bounds.x = + viewport.x + viewport.width - tooltip_bounds.width; + } + + if tooltip_bounds.y < viewport.y { + tooltip_bounds.y = viewport.y; + } else if viewport.y + viewport.height + < tooltip_bounds.y + tooltip_bounds.height + { + tooltip_bounds.y = + viewport.y + viewport.height - tooltip_bounds.height; + } + + renderer.with_layer(*viewport, |renderer| { + container::draw_background(renderer, &style, tooltip_bounds); + + Widget::<(), Renderer>::draw( + &self.tooltip, + &tree.children[0], + renderer, + &defaults, + Layout::with_offset( + Vector::new( + tooltip_bounds.x + padding, + tooltip_bounds.y + padding, + ), + &text_layout, + ), + cursor_position, + viewport, + ); + }); + } + } + + fn overlay<'b>( + &'b self, + tree: &'b mut Tree, + layout: Layout<'_>, + renderer: &Renderer, + ) -> Option> { + self.content.as_widget().overlay( + &mut tree.children[0], + layout, + renderer, + ) + } +} + +impl<'a, Message, Renderer> From> + for Element<'a, Message, Renderer> +where + Renderer: 'a + text::Renderer, + Message: 'a, +{ + fn from( + tooltip: Tooltip<'a, Message, Renderer>, + ) -> Element<'a, Message, Renderer> { + Element::new(tooltip) + } +} diff --git a/src/pure/widget.rs b/src/pure/widget.rs index 6628b1fb..2a506f73 100644 --- a/src/pure/widget.rs +++ b/src/pure/widget.rs @@ -118,6 +118,15 @@ pub mod text_input { iced_pure::widget::TextInput<'a, Message, Renderer>; } +pub mod tooltip { + //! Display a widget over another. + pub use iced_pure::widget::tooltip::Position; + + /// A widget allowing the selection of a single value from a list of options. + pub type Tooltip<'a, Message> = + iced_pure::widget::Tooltip<'a, Message, crate::Renderer>; +} + pub use iced_pure::widget::progress_bar; pub use iced_pure::widget::rule; pub use iced_pure::widget::slider; @@ -135,6 +144,7 @@ pub use scrollable::Scrollable; pub use slider::Slider; pub use text_input::TextInput; pub use toggler::Toggler; +pub use tooltip::Tooltip; #[cfg(feature = "canvas")] pub use iced_graphics::widget::pure::canvas; -- cgit From 011b7d11126404eaeff1562e49d81693d4d852b2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 24 Apr 2022 20:25:49 +0700 Subject: Reuse `tooltip::Position` from `iced_native` in `iced_pure` --- pure/src/widget/tooltip.rs | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/pure/src/widget/tooltip.rs b/pure/src/widget/tooltip.rs index f0667e41..0155034b 100644 --- a/pure/src/widget/tooltip.rs +++ b/pure/src/widget/tooltip.rs @@ -2,15 +2,18 @@ use crate::widget::Tree; use crate::{Element, Widget}; use iced_native::event::{self, Event}; +use iced_native::layout; +use iced_native::mouse; +use iced_native::overlay; +use iced_native::renderer; +use iced_native::text; use iced_native::widget::container; -pub use iced_native::widget::Text; -use iced_native::{layout, mouse, overlay}; -use iced_native::{renderer, Size}; -use iced_native::{text, Vector}; +use iced_native::widget::Text; use iced_native::{ - Clipboard, Layout, Length, Padding, Point, Rectangle, Shell, + Clipboard, Layout, Length, Padding, Point, Rectangle, Shell, Size, Vector, }; +pub use iced_native::widget::tooltip::Position; pub use iced_style::container::{Style, StyleSheet}; /// An element to display a widget over another. @@ -85,21 +88,6 @@ where } } -/// The position of the tooltip. Defaults to following the cursor. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Position { - /// The tooltip will follow the cursor. - FollowCursor, - /// The tooltip will appear on the top of the widget. - Top, - /// The tooltip will appear on the bottom of the widget. - Bottom, - /// The tooltip will appear on the left of the widget. - Left, - /// The tooltip will appear on the right of the widget. - Right, -} - impl<'a, Message, Renderer> Widget for Tooltip<'a, Message, Renderer> where -- cgit From e33f43af31888b8b0795c2287aed9f26b4e1d699 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 24 Apr 2022 20:45:43 +0700 Subject: Reuse `Tooltip` draw logic in `iced_pure` --- native/src/widget/tooltip.rs | 219 ++++++++++++++++++++++++++----------------- pure/src/widget/tooltip.rs | 118 +++++------------------ 2 files changed, 155 insertions(+), 182 deletions(-) diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs index 253c26a3..e178c8b2 100644 --- a/native/src/widget/tooltip.rs +++ b/native/src/widget/tooltip.rs @@ -98,6 +98,117 @@ pub enum Position { Right, } +/// Draws a [`Tooltip`]. +pub fn draw( + renderer: &mut Renderer, + inherited_style: &renderer::Style, + layout: Layout<'_>, + cursor_position: Point, + viewport: &Rectangle, + position: Position, + gap: u16, + padding: u16, + style_sheet: &dyn container::StyleSheet, + layout_text: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node, + draw_text: impl FnOnce( + &mut Renderer, + &renderer::Style, + Layout<'_>, + Point, + &Rectangle, + ), +) { + let bounds = layout.bounds(); + + if bounds.contains(cursor_position) { + let gap = f32::from(gap); + let style = style_sheet.style(); + + let defaults = renderer::Style { + text_color: style.text_color.unwrap_or(inherited_style.text_color), + }; + + let text_layout = layout_text( + renderer, + &layout::Limits::new(Size::ZERO, viewport.size()) + .pad(Padding::new(padding)), + ); + + let padding = f32::from(padding); + let text_bounds = text_layout.bounds(); + let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0; + let y_center = bounds.y + (bounds.height - text_bounds.height) / 2.0; + + let mut tooltip_bounds = { + let offset = match position { + Position::Top => Vector::new( + x_center, + bounds.y - text_bounds.height - gap - padding, + ), + Position::Bottom => Vector::new( + x_center, + bounds.y + bounds.height + gap + padding, + ), + Position::Left => Vector::new( + bounds.x - text_bounds.width - gap - padding, + y_center, + ), + Position::Right => Vector::new( + bounds.x + bounds.width + gap + padding, + y_center, + ), + Position::FollowCursor => Vector::new( + cursor_position.x, + cursor_position.y - text_bounds.height, + ), + }; + + Rectangle { + x: offset.x - padding, + y: offset.y - padding, + width: text_bounds.width + padding * 2.0, + height: text_bounds.height + padding * 2.0, + } + }; + + if tooltip_bounds.x < viewport.x { + tooltip_bounds.x = viewport.x; + } else if viewport.x + viewport.width + < tooltip_bounds.x + tooltip_bounds.width + { + tooltip_bounds.x = + viewport.x + viewport.width - tooltip_bounds.width; + } + + if tooltip_bounds.y < viewport.y { + tooltip_bounds.y = viewport.y; + } else if viewport.y + viewport.height + < tooltip_bounds.y + tooltip_bounds.height + { + tooltip_bounds.y = + viewport.y + viewport.height - tooltip_bounds.height; + } + + renderer.with_layer(*viewport, |renderer| { + container::draw_background(renderer, &style, tooltip_bounds); + + draw_text( + renderer, + &defaults, + Layout::with_offset( + Vector::new( + tooltip_bounds.x + padding, + tooltip_bounds.y + padding, + ), + &text_layout, + ), + cursor_position, + viewport, + ) + }); + } +} + impl<'a, Message, Renderer> Widget for Tooltip<'a, Message, Renderer> where @@ -169,100 +280,32 @@ where viewport, ); - let bounds = layout.bounds(); - - if bounds.contains(cursor_position) { - let gap = f32::from(self.gap); - let style = self.style_sheet.style(); - - let defaults = renderer::Style { - text_color: style - .text_color - .unwrap_or(inherited_style.text_color), - }; - - let text_layout = Widget::<(), Renderer>::layout( - &self.tooltip, - renderer, - &layout::Limits::new(Size::ZERO, viewport.size()) - .pad(Padding::new(self.padding)), - ); - - let padding = f32::from(self.padding); - let text_bounds = text_layout.bounds(); - let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0; - let y_center = - bounds.y + (bounds.height - text_bounds.height) / 2.0; - - let mut tooltip_bounds = { - let offset = match self.position { - Position::Top => Vector::new( - x_center, - bounds.y - text_bounds.height - gap - padding, - ), - Position::Bottom => Vector::new( - x_center, - bounds.y + bounds.height + gap + padding, - ), - Position::Left => Vector::new( - bounds.x - text_bounds.width - gap - padding, - y_center, - ), - Position::Right => Vector::new( - bounds.x + bounds.width + gap + padding, - y_center, - ), - Position::FollowCursor => Vector::new( - cursor_position.x, - cursor_position.y - text_bounds.height, - ), - }; - - Rectangle { - x: offset.x - padding, - y: offset.y - padding, - width: text_bounds.width + padding * 2.0, - height: text_bounds.height + padding * 2.0, - } - }; - - if tooltip_bounds.x < viewport.x { - tooltip_bounds.x = viewport.x; - } else if viewport.x + viewport.width - < tooltip_bounds.x + tooltip_bounds.width - { - tooltip_bounds.x = - viewport.x + viewport.width - tooltip_bounds.width; - } - - if tooltip_bounds.y < viewport.y { - tooltip_bounds.y = viewport.y; - } else if viewport.y + viewport.height - < tooltip_bounds.y + tooltip_bounds.height - { - tooltip_bounds.y = - viewport.y + viewport.height - tooltip_bounds.height; - } - - renderer.with_layer(*viewport, |renderer| { - container::draw_background(renderer, &style, tooltip_bounds); + let tooltip = &self.tooltip; + draw( + renderer, + inherited_style, + layout, + cursor_position, + viewport, + self.position, + self.gap, + self.padding, + self.style_sheet.as_ref(), + |renderer, limits| { + Widget::<(), Renderer>::layout(tooltip, renderer, limits) + }, + |renderer, defaults, layout, cursor_position, viewport| { Widget::<(), Renderer>::draw( - &self.tooltip, + tooltip, renderer, - &defaults, - Layout::with_offset( - Vector::new( - tooltip_bounds.x + padding, - tooltip_bounds.y + padding, - ), - &text_layout, - ), + defaults, + layout, cursor_position, viewport, ); - }); - } + }, + ) } } diff --git a/pure/src/widget/tooltip.rs b/pure/src/widget/tooltip.rs index 0155034b..75c4d856 100644 --- a/pure/src/widget/tooltip.rs +++ b/pure/src/widget/tooltip.rs @@ -7,14 +7,12 @@ use iced_native::mouse; use iced_native::overlay; use iced_native::renderer; use iced_native::text; -use iced_native::widget::container; +use iced_native::widget::tooltip; use iced_native::widget::Text; -use iced_native::{ - Clipboard, Layout, Length, Padding, Point, Rectangle, Shell, Size, Vector, -}; +use iced_native::{Clipboard, Layout, Length, Point, Rectangle, Shell}; -pub use iced_native::widget::tooltip::Position; pub use iced_style::container::{Style, StyleSheet}; +pub use tooltip::Position; /// An element to display a widget over another. #[allow(missing_debug_implementations)] @@ -173,101 +171,33 @@ where viewport, ); - let bounds = layout.bounds(); - - if bounds.contains(cursor_position) { - let gap = f32::from(self.gap); - let style = self.style_sheet.style(); - - let defaults = renderer::Style { - text_color: style - .text_color - .unwrap_or(inherited_style.text_color), - }; - - let text_layout = Widget::<(), Renderer>::layout( - &self.tooltip, - renderer, - &layout::Limits::new(Size::ZERO, viewport.size()) - .pad(Padding::new(self.padding)), - ); - - let padding = f32::from(self.padding); - let text_bounds = text_layout.bounds(); - let x_center = bounds.x + (bounds.width - text_bounds.width) / 2.0; - let y_center = - bounds.y + (bounds.height - text_bounds.height) / 2.0; - - let mut tooltip_bounds = { - let offset = match self.position { - Position::Top => Vector::new( - x_center, - bounds.y - text_bounds.height - gap - padding, - ), - Position::Bottom => Vector::new( - x_center, - bounds.y + bounds.height + gap + padding, - ), - Position::Left => Vector::new( - bounds.x - text_bounds.width - gap - padding, - y_center, - ), - Position::Right => Vector::new( - bounds.x + bounds.width + gap + padding, - y_center, - ), - Position::FollowCursor => Vector::new( - cursor_position.x, - cursor_position.y - text_bounds.height, - ), - }; - - Rectangle { - x: offset.x - padding, - y: offset.y - padding, - width: text_bounds.width + padding * 2.0, - height: text_bounds.height + padding * 2.0, - } - }; - - if tooltip_bounds.x < viewport.x { - tooltip_bounds.x = viewport.x; - } else if viewport.x + viewport.width - < tooltip_bounds.x + tooltip_bounds.width - { - tooltip_bounds.x = - viewport.x + viewport.width - tooltip_bounds.width; - } - - if tooltip_bounds.y < viewport.y { - tooltip_bounds.y = viewport.y; - } else if viewport.y + viewport.height - < tooltip_bounds.y + tooltip_bounds.height - { - tooltip_bounds.y = - viewport.y + viewport.height - tooltip_bounds.height; - } - - renderer.with_layer(*viewport, |renderer| { - container::draw_background(renderer, &style, tooltip_bounds); + let tooltip = &self.tooltip; + tooltip::draw( + renderer, + inherited_style, + layout, + cursor_position, + viewport, + self.position, + self.gap, + self.padding, + self.style_sheet.as_ref(), + |renderer, limits| { + Widget::<(), Renderer>::layout(tooltip, renderer, limits) + }, + |renderer, defaults, layout, cursor_position, viewport| { Widget::<(), Renderer>::draw( - &self.tooltip, - &tree.children[0], + tooltip, + &Tree::empty(), renderer, - &defaults, - Layout::with_offset( - Vector::new( - tooltip_bounds.x + padding, - tooltip_bounds.y + padding, - ), - &text_layout, - ), + defaults, + layout, cursor_position, viewport, ); - }); - } + }, + ); } fn overlay<'b>( -- cgit From 83171f05d0111808ebafda309222e45062d3a0b0 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Mon, 25 Apr 2022 08:52:10 -0700 Subject: Don't wrap picklist label text --- native/src/widget/pick_list.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index e050ada5..998b9b3c 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -412,6 +412,7 @@ pub fn draw( bounds: Rectangle { x: bounds.x + f32::from(padding.left), y: bounds.center_y(), + width: f32::INFINITY, ..bounds }, horizontal_alignment: alignment::Horizontal::Left, -- cgit From 6e70d9ad83432b45e6bcfd022ba31e192ad99669 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Mon, 25 Apr 2022 09:01:04 -0700 Subject: Clip bounds to prevent text overflow --- native/src/widget/pick_list.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 998b9b3c..4f00c96e 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -402,22 +402,24 @@ pub fn draw( if let Some(label) = label.as_ref().map(String::as_str).or_else(|| placeholder) { - renderer.fill_text(Text { - content: label, - size: f32::from(text_size.unwrap_or(renderer.default_size())), - font: font.clone(), - color: is_selected - .then(|| style.text_color) - .unwrap_or(style.placeholder_color), - bounds: Rectangle { - x: bounds.x + f32::from(padding.left), - y: bounds.center_y(), - width: f32::INFINITY, - ..bounds - }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - }) + renderer.with_layer(bounds, |layer| { + layer.fill_text(Text { + content: label, + size: f32::from(text_size.unwrap_or(layer.default_size())), + font: font.clone(), + color: is_selected + .then(|| style.text_color) + .unwrap_or(style.placeholder_color), + bounds: Rectangle { + x: bounds.x + f32::from(padding.left), + y: bounds.center_y(), + width: f32::INFINITY, + ..bounds + }, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + }) + }); } } -- cgit From 70d290b2dcea4be270903c2f83686cd00dbd23a2 Mon Sep 17 00:00:00 2001 From: Nick Senger Date: Mon, 25 Apr 2022 16:33:07 -0700 Subject: add example --- examples/pure/component/src/main.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/pure/component/src/main.rs b/examples/pure/component/src/main.rs index b38d6fca..6d5a3b9c 100644 --- a/examples/pure/component/src/main.rs +++ b/examples/pure/component/src/main.rs @@ -1,6 +1,7 @@ use iced::pure::container; use iced::pure::{Element, Sandbox}; use iced::{Length, Settings}; +use iced_lazy::pure::responsive; use numeric_input::numeric_input; @@ -38,11 +39,14 @@ impl Sandbox for Component { } fn view(&self) -> Element { - container(numeric_input(self.value, Message::NumericInputChanged)) - .padding(20) - .height(Length::Fill) - .center_y() - .into() + responsive(|_| { + container(numeric_input(self.value, Message::NumericInputChanged)) + .padding(20) + .height(Length::Fill) + .center_y() + .into() + }) + .into() } } -- cgit From 7b539479cfbe06d2495a9904ed2eeb0536a32f1c Mon Sep 17 00:00:00 2001 From: Nick Senger Date: Mon, 25 Apr 2022 16:40:34 -0700 Subject: fix: panic when using pure component in pure responsive --- lazy/src/pure/responsive.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lazy/src/pure/responsive.rs b/lazy/src/pure/responsive.rs index 2b62a047..e464d156 100644 --- a/lazy/src/pure/responsive.rs +++ b/lazy/src/pure/responsive.rs @@ -67,12 +67,13 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> { self.element = view(new_size); self.size = new_size; + + tree.diff(&self.element); + self.layout = self .element .as_widget() .layout(renderer, &layout::Limits::new(Size::ZERO, self.size)); - - tree.diff(&self.element); } fn resolve( -- cgit From f71150c91fcb2fd7c4c7ddf8ed8d1eaed2dc7bdf Mon Sep 17 00:00:00 2001 From: Nick Senger Date: Mon, 25 Apr 2022 16:40:44 -0700 Subject: remove example --- examples/pure/component/src/main.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/examples/pure/component/src/main.rs b/examples/pure/component/src/main.rs index 6d5a3b9c..b38d6fca 100644 --- a/examples/pure/component/src/main.rs +++ b/examples/pure/component/src/main.rs @@ -1,7 +1,6 @@ use iced::pure::container; use iced::pure::{Element, Sandbox}; use iced::{Length, Settings}; -use iced_lazy::pure::responsive; use numeric_input::numeric_input; @@ -39,14 +38,11 @@ impl Sandbox for Component { } fn view(&self) -> Element { - responsive(|_| { - container(numeric_input(self.value, Message::NumericInputChanged)) - .padding(20) - .height(Length::Fill) - .center_y() - .into() - }) - .into() + container(numeric_input(self.value, Message::NumericInputChanged)) + .padding(20) + .height(Length::Fill) + .center_y() + .into() } } -- cgit From 4329f0480bec803346e7e5b8c02cc17f62b6ab35 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Wed, 27 Apr 2022 08:49:55 -0700 Subject: Use top alignment instead of new layer --- native/src/widget/pick_list.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 4f00c96e..5ed07863 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -402,23 +402,20 @@ pub fn draw( if let Some(label) = label.as_ref().map(String::as_str).or_else(|| placeholder) { - renderer.with_layer(bounds, |layer| { - layer.fill_text(Text { - content: label, - size: f32::from(text_size.unwrap_or(layer.default_size())), - font: font.clone(), - color: is_selected - .then(|| style.text_color) - .unwrap_or(style.placeholder_color), - bounds: Rectangle { - x: bounds.x + f32::from(padding.left), - y: bounds.center_y(), - width: f32::INFINITY, - ..bounds - }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - }) + renderer.fill_text(Text { + content: label, + size: f32::from(text_size.unwrap_or(renderer.default_size())), + font: font.clone(), + color: is_selected + .then(|| style.text_color) + .unwrap_or(style.placeholder_color), + bounds: Rectangle { + x: bounds.x + f32::from(padding.left), + y: bounds.center_y(), + ..bounds + }, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Top, }); } } -- cgit From bc8b4bb1828a8bd4fa95b585d0655adec8f85f9d Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Wed, 27 Apr 2022 08:56:43 -0700 Subject: Manually center top aligned text --- native/src/widget/pick_list.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 5ed07863..2e61e036 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -402,16 +402,18 @@ pub fn draw( if let Some(label) = label.as_ref().map(String::as_str).or_else(|| placeholder) { + let text_size = f32::from(text_size.unwrap_or(renderer.default_size())); + renderer.fill_text(Text { content: label, - size: f32::from(text_size.unwrap_or(renderer.default_size())), + size: text_size, font: font.clone(), color: is_selected .then(|| style.text_color) .unwrap_or(style.placeholder_color), bounds: Rectangle { x: bounds.x + f32::from(padding.left), - y: bounds.center_y(), + y: bounds.center_y() - text_size / 2.0, ..bounds }, horizontal_alignment: alignment::Horizontal::Left, -- cgit From d562c27e8ce10ecf4aed4d5fc4c64a737391c2c9 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Wed, 27 Apr 2022 09:13:11 -0700 Subject: Restrict text width & height to prevent overflow --- native/src/widget/pick_list.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 2e61e036..0374aef7 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -414,7 +414,8 @@ pub fn draw( bounds: Rectangle { x: bounds.x + f32::from(padding.left), y: bounds.center_y() - text_size / 2.0, - ..bounds + width: bounds.width - f32::from(padding.horizontal()), + height: text_size, }, horizontal_alignment: alignment::Horizontal::Left, vertical_alignment: alignment::Vertical::Top, -- cgit From a17a7103d382f02c64e7b271d953ea6babffac97 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 30 Apr 2022 13:44:37 +0200 Subject: Add new crates to `document` workflow --- .github/workflows/document.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/document.yml b/.github/workflows/document.yml index 3a8326b6..b67a62ab 100644 --- a/.github/workflows/document.yml +++ b/.github/workflows/document.yml @@ -15,8 +15,11 @@ jobs: run: | cargo doc --no-deps --all-features \ -p iced_core \ + -p iced_style \ + -p iced_futures \ -p iced_native \ -p iced_lazy \ + -p iced_pure \ -p iced_graphics \ -p iced_wgpu \ -p iced_glow \ -- cgit From ac35fe3edf78c1674fe85b37549002e006b0ff13 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 30 Apr 2022 13:54:07 +0200 Subject: Point repository links to `0.4` branch in documentation --- core/src/lib.rs | 4 ++-- futures/src/subscription.rs | 6 +++--- glow/src/lib.rs | 2 +- graphics/src/widget/canvas.rs | 8 ++++---- native/src/lib.rs | 4 ++-- native/src/user_interface.rs | 2 +- native/src/widget.rs | 10 +++++----- native/src/widget/pane_grid.rs | 2 +- pure/src/widget/pane_grid.rs | 2 +- src/application.rs | 18 +++++++++--------- src/lib.rs | 10 +++++----- src/pure/widget.rs | 2 +- src/sandbox.rs | 22 +++++++++++----------- src/widget.rs | 2 +- wgpu/src/lib.rs | 2 +- winit/src/conversion.rs | 12 ++++++------ winit/src/lib.rs | 2 +- 17 files changed, 55 insertions(+), 55 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index 3eb9f659..318d4032 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -7,8 +7,8 @@ //! ![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/tree/0.4/web #![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] 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 std::fmt::Debug for Subscription { /// - [`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 { /// The events that will be produced by a [`Subscription`] with this /// [`Recipe`]. diff --git a/glow/src/lib.rs b/glow/src/lib.rs index 05435b54..1862e1ec 100644 --- a/glow/src/lib.rs +++ b/glow/src/lib.rs @@ -3,7 +3,7 @@ //! ![The native path of the Iced ecosystem](https://github.com/hecrj/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/hecrj/iced/tree/0.4/native #![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..0ed45e42 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/hecrj/iced/tree/0.4/examples +/// [`clock`]: https://github.com/hecrj/iced/tree/0.4/examples/clock +/// [`game_of_life`]: https://github.com/hecrj/iced/tree/0.4/examples/game_of_life +/// [`solar_system`]: https://github.com/hecrj/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/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/user_interface.rs b/native/src/user_interface.rs index 6fc6a479..85625e23 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>, 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 where Renderer: crate::Renderer, 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/pure/src/widget/pane_grid.rs b/pure/src/widget/pane_grid.rs index 34a56bcc..b361664b 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; diff --git a/src/application.rs b/src/application.rs index 14a16d61..c5434c24 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/hecrj/iced/tree/0.4/examples +/// [`clock`]: https://github.com/hecrj/iced/tree/0.4/examples/clock +/// [`download_progress`]: https://github.com/hecrj/iced/tree/0.4/examples/download_progress +/// [`events`]: https://github.com/hecrj/iced/tree/0.4/examples/events +/// [`game_of_life`]: https://github.com/hecrj/iced/tree/0.4/examples/game_of_life +/// [`pokedex`]: https://github.com/hecrj/iced/tree/0.4/examples/pokedex +/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.4/examples/solar_system +/// [`stopwatch`]: https://github.com/hecrj/iced/tree/0.4/examples/stopwatch +/// [`todos`]: https://github.com/hecrj/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..e407b10d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,13 +24,13 @@ //! [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 +//! [renderer-agnostic native runtime]: https://github.com/hecrj/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/hecrj/iced/tree/0.4/wgpu +//! [windowing shell]: https://github.com/hecrj/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 +//! [web runtime]: https://github.com/hecrj/iced/tree/0.4/web +//! [examples]: https://github.com/hecrj/iced/tree/0.4/examples //! [repository]: https://github.com/hecrj/iced //! //! # Overview 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..177c43f9 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/hecrj/iced/tree/0.4/examples +/// [`bezier_tool`]: https://github.com/hecrj/iced/tree/0.4/examples/bezier_tool +/// [`counter`]: https://github.com/hecrj/iced/tree/0.4/examples/counter +/// [`custom_widget`]: https://github.com/hecrj/iced/tree/0.4/examples/custom_widget +/// [`geometry`]: https://github.com/hecrj/iced/tree/0.4/examples/geometry +/// [`pane_grid`]: https://github.com/hecrj/iced/tree/0.4/examples/pane_grid +/// [`progress_bar`]: https://github.com/hecrj/iced/tree/0.4/examples/progress_bar +/// [`styling`]: https://github.com/hecrj/iced/tree/0.4/examples/styling +/// [`svg`]: https://github.com/hecrj/iced/tree/0.4/examples/svg +/// [`tour`]: https://github.com/hecrj/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/hecrj/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..83df0052 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, 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/src/conversion.rs b/winit/src/conversion.rs index b00a095d..b45f6415 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/hecrj/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/hecrj/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/hecrj/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/hecrj/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/hecrj/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/hecrj/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..b153848f 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -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/hecrj/iced/tree/0.4/native //! [`winit`]: https://github.com/rust-windowing/winit //! [`conversion`]: crate::conversion #![doc( -- cgit From 68e9eb0a9b45b86713ce5d0e9c2273a60f2cc11c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sat, 30 Apr 2022 14:20:52 +0200 Subject: Fix broken intra-doc links in documentation --- core/src/keyboard/modifiers.rs | 8 ++++++++ futures/src/command.rs | 2 +- futures/src/runtime.rs | 6 +++++- graphics/src/widget/pure/canvas/program.rs | 4 ++-- graphics/src/window/compositor.rs | 5 +++-- native/src/command/action.rs | 4 ++++ native/src/image.rs | 4 ++-- native/src/overlay.rs | 2 +- native/src/renderer.rs | 23 +---------------------- native/src/svg.rs | 4 ++-- native/src/text.rs | 2 +- native/src/user_interface.rs | 5 ++--- native/src/widget/checkbox.rs | 2 +- native/src/widget/pane_grid/configuration.rs | 4 ++-- native/src/widget/pane_grid/content.rs | 2 +- native/src/widget/pane_grid/state.rs | 22 ++++++++++++++++++++++ native/src/widget/pane_grid/title_bar.rs | 2 +- native/src/widget/text.rs | 6 +++--- native/src/widget/text_input.rs | 9 ++++++--- native/src/widget/toggler.rs | 2 ++ pure/src/helpers.rs | 10 ++++++++-- pure/src/widget/pane_grid/content.rs | 2 +- pure/src/widget/pane_grid/title_bar.rs | 2 +- pure/src/widget/pick_list.rs | 5 ++--- pure/src/widget/slider.rs | 7 ++----- pure/src/widget/text_input.rs | 18 +++++++----------- src/pure.rs | 1 + winit/src/settings.rs | 4 ++++ 28 files changed, 96 insertions(+), 71 deletions(-) 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/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 Command { 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 { 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) { use futures::{FutureExt, SinkExt}; 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 { - /// 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>( &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/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 { /// Run a [`Future`] to completion. + /// + /// [`Future`]: iced_futures::BoxFuture Future(iced_futures::BoxFuture), /// Run a clipboard action. @@ -21,6 +23,8 @@ pub enum Action { impl Action { /// Applies a transformation to the result of a [`Command`]. + /// + /// [`Command`]: crate::Command pub fn map( 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/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 85625e23..f80786aa 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -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/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/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 { /// A split of the available space. @@ -21,6 +21,6 @@ pub enum Configuration { }, /// 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 { /// The panes of the [`PaneGrid`]. + /// + /// [`PaneGrid`]: crate::widget::PaneGrid pub panes: HashMap, /// The internal state of the [`PaneGrid`]. + /// + /// [`PaneGrid`]: crate::widget::PaneGrid pub internal: Internal, pub(super) action: Action, @@ -198,6 +204,8 @@ impl State { } /// 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( panes: &mut HashMap, content: Configuration, @@ -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/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 Text { /// Sets the [`Font`] of the [`Text`]. /// - /// [`Font`]: Renderer::Font + /// [`Font`]: crate::text::Renderer::Font pub fn font(mut self, font: impl Into) -> Self { self.font = font.into(); self @@ -77,7 +77,7 @@ impl Text { 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 Text { 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: &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/pure/src/helpers.rs b/pure/src/helpers.rs index 2ddab3ae..d6744262 100644 --- a/pure/src/helpers.rs +++ b/pure/src/helpers.rs @@ -142,11 +142,15 @@ pub fn vertical_space(height: Length) -> widget::Space { } /// 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 +158,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, value: f32, diff --git a/pure/src/widget/pane_grid/content.rs b/pure/src/widget/pane_grid/content.rs index a928b28c..6388b016 100644 --- a/pure/src/widget/pane_grid/content.rs +++ b/pure/src/widget/pane_grid/content.rs @@ -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..567db913 100644 --- a/pure/src/widget/pane_grid/title_bar.rs +++ b/pure/src/widget/pane_grid/title_bar.rs @@ -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>, selected: Option, 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/text_input.rs b/pure/src/widget/text_input.rs index d6041d7f..11e93b44 100644 --- a/pure/src/widget/text_input.rs +++ b/pure/src/widget/text_input.rs @@ -16,19 +16,17 @@ pub use iced_style::text_input::{Style, StyleSheet}; /// # Example /// ``` /// # use iced_native::renderer::Null; -/// # use iced_native::widget::text_input; +/// # use iced_pure::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, 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 +56,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(placeholder: &str, value: &str, on_change: F) -> Self where F: 'a + Fn(String) -> Message, @@ -86,10 +83,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/src/pure.rs b/src/pure.rs index 948183f1..5776de40 100644 --- a/src/pure.rs +++ b/src/pure.rs @@ -26,6 +26,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/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 { /// 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, } -- cgit From e7d595c7de3854e165fd68f05ab2292cae69dbc4 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:16:00 +0200 Subject: Write documentation for `iced_pure` --- native/src/widget/column.rs | 2 +- native/src/widget/row.rs | 2 +- native/src/widget/tooltip.rs | 2 +- pure/src/element.rs | 146 +++++++++++++++++++++++++++++++++ pure/src/helpers.rs | 50 +++++++++++ pure/src/lib.rs | 119 +++++++++++++++++++++++++++ pure/src/overlay.rs | 5 ++ pure/src/widget.rs | 49 ++++++++--- pure/src/widget/button.rs | 36 ++++++++ pure/src/widget/checkbox.rs | 1 + pure/src/widget/column.rs | 13 +++ pure/src/widget/image.rs | 1 + pure/src/widget/pane_grid.rs | 2 +- pure/src/widget/pane_grid/content.rs | 4 +- pure/src/widget/pane_grid/title_bar.rs | 4 +- pure/src/widget/progress_bar.rs | 1 + pure/src/widget/radio.rs | 1 + pure/src/widget/row.rs | 13 +++ pure/src/widget/rule.rs | 1 + pure/src/widget/scrollable.rs | 1 + pure/src/widget/svg.rs | 1 + pure/src/widget/text_input.rs | 6 +- pure/src/widget/toggler.rs | 1 + pure/src/widget/tooltip.rs | 2 +- pure/src/widget/tree.rs | 48 +++++++++-- src/pure.rs | 78 ++++++++++++++++++ 26 files changed, 558 insertions(+), 31 deletions(-) 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/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/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` +/// to turn it into an [`Element`]. +/// +/// [built-in widget]: crate::widget pub struct Element<'a, Message, Renderer> { widget: Box + 'a>, } impl<'a, Message, Renderer> Element<'a, Message, Renderer> { + /// Creates a new [`Element`] containing the given [`Widget`]. pub fn new(widget: impl Widget + 'a) -> Self { Self { widget: Box::new(widget), } } + /// Returns a reference to the [`Widget`] of the [`Element`], pub fn as_widget(&self) -> &dyn Widget { self.widget.as_ref() } + /// Returns a mutable reference to the [`Widget`] of the [`Element`], pub fn as_widget_mut(&mut self) -> &mut dyn Widget { 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, + /// } + /// ``` + /// + /// 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; + /// # + /// # #[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, + /// # } + /// # + /// # #[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 { + /// // 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.view().into(); + /// + /// row.push( + /// // Here we turn our `Element` into + /// // an `Element` 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, + /// # } + /// # + /// # #[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( self, f: impl Fn(Message) -> B + 'a, diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs index d6744262..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>, ) -> 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>, ) -> 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>, ) -> 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>, 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(text: impl Into) -> widget::Text 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, 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, 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>, 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, 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>, selected: Option, @@ -129,14 +170,23 @@ where widget::PickList::new(options, selected, on_selected) } +/// Creates a new [`Image`]. +/// +/// [`Image`]: widget::Image pub fn image(handle: impl Into) -> widget::Image { 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) } diff --git a/pure/src/lib.rs b/pure/src/lib.rs index f9f0ae2d..fc803222 100644 --- a/pure/src/lib.rs +++ b/pure/src/lib.rs @@ -1,3 +1,93 @@ +//! 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; +//! } +//! ``` +//! +//! 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 { +//! 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 { +//! 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(missing_debug_implementations)] +//#![deny(unused_results)] +#![forbid(unsafe_code)] +//#![forbid(rust_2018_idioms)] + pub mod helpers; pub mod overlay; pub mod widget; @@ -16,6 +106,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 { +/// 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 +142,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>, @@ -37,6 +154,7 @@ where } } +/// The internal state of a [`Pure`] widget. pub struct State { state_tree: widget::Tree, } @@ -48,6 +166,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(), 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 { + /// 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 { 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 { 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 { 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, @@ -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>) -> 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>, ) -> 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>(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>, 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 b361664b..c532a6de 100644 --- a/pure/src/widget/pane_grid.rs +++ b/pure/src/widget/pane_grid.rs @@ -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 6388b016..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]); diff --git a/pure/src/widget/pane_grid/title_bar.rs b/pure/src/widget/pane_grid/title_bar.rs index 567db913..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); 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>, ) -> 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>(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>, 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/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 11e93b44..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,10 +16,7 @@ pub use iced_style::text_input::{Style, StyleSheet}; /// /// # Example /// ``` -/// # use iced_native::renderer::Null; -/// # use iced_pure::widget::text_input; -/// # -/// # pub type TextInput<'a, Message> = iced_pure::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), 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, } 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( 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( &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( &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( &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() -> Self where T: 'static, @@ -84,17 +104,23 @@ impl Tag { Self(any::TypeId::of::()) } + /// 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), } impl State { + /// Creates a new [`State`]. pub fn new(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(&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(&mut self) -> &mut T where T: 'static, diff --git a/src/pure.rs b/src/pure.rs index 5776de40..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; +//! } +//! ``` +//! +//! 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 { +//! 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 { +//! 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 -- cgit From aecbd46123eb556fa1193cdf3b9eb96cfd4beff2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:25:47 +0200 Subject: Replace `hecrj` in links with `iced-rs` --- CONTRIBUTING.md | 2 +- README.md | 12 ++++++------ core/src/lib.rs | 2 +- glow/README.md | 4 ++-- glow/src/backend.rs | 2 +- glow/src/lib.rs | 6 +++--- graphics/src/lib.rs | 4 ++-- graphics/src/widget/canvas.rs | 8 ++++---- src/application.rs | 18 +++++++++--------- src/lib.rs | 16 ++++++++-------- src/sandbox.rs | 22 +++++++++++----------- winit/README.md | 2 +- winit/src/conversion.rs | 12 ++++++------ winit/src/lib.rs | 4 ++-- 14 files changed, 57 insertions(+), 57 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/README.md b/README.md index e73891ce..dad50e50 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,9 @@ [![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. @@ -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 @@ -237,12 +237,12 @@ the [Rust Community Discord]. I go by `lone_scientist#9554` there. 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/lib.rs b/core/src/lib.rs index 318d4032..dc340d3a 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -8,7 +8,7 @@ //! //! [Iced]: https://github.com/iced-rs/iced //! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native -//! [`iced_web`]: https://github.com/iced-rs/iced/tree/0.4/web +//! [`iced_web`]: https://github.com/iced-rs/iced_web #![deny(missing_docs)] #![deny(missing_debug_implementations)] #![deny(unused_results)] diff --git a/glow/README.md b/glow/README.md index 5e37b7a2..9d555cb1 100644 --- a/glow/README.md +++ b/glow/README.md @@ -1,7 +1,7 @@ # `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. @@ -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 1862e1ec..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/0.4/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; 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 0ed45e42..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/0.4/examples -/// [`clock`]: https://github.com/hecrj/iced/tree/0.4/examples/clock -/// [`game_of_life`]: https://github.com/hecrj/iced/tree/0.4/examples/game_of_life -/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.4/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/src/application.rs b/src/application.rs index c5434c24..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.4/examples -/// [`clock`]: https://github.com/hecrj/iced/tree/0.4/examples/clock -/// [`download_progress`]: https://github.com/hecrj/iced/tree/0.4/examples/download_progress -/// [`events`]: https://github.com/hecrj/iced/tree/0.4/examples/events -/// [`game_of_life`]: https://github.com/hecrj/iced/tree/0.4/examples/game_of_life -/// [`pokedex`]: https://github.com/hecrj/iced/tree/0.4/examples/pokedex -/// [`solar_system`]: https://github.com/hecrj/iced/tree/0.4/examples/solar_system -/// [`stopwatch`]: https://github.com/hecrj/iced/tree/0.4/examples/stopwatch -/// [`todos`]: https://github.com/hecrj/iced/tree/0.4/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 e407b10d..e154d9c7 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/0.4/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/0.4/wgpu -//! [windowing shell]: https://github.com/hecrj/iced/tree/0.4/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/0.4/web -//! [examples]: https://github.com/hecrj/iced/tree/0.4/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 diff --git a/src/sandbox.rs b/src/sandbox.rs index 177c43f9..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.4/examples -/// [`bezier_tool`]: https://github.com/hecrj/iced/tree/0.4/examples/bezier_tool -/// [`counter`]: https://github.com/hecrj/iced/tree/0.4/examples/counter -/// [`custom_widget`]: https://github.com/hecrj/iced/tree/0.4/examples/custom_widget -/// [`geometry`]: https://github.com/hecrj/iced/tree/0.4/examples/geometry -/// [`pane_grid`]: https://github.com/hecrj/iced/tree/0.4/examples/pane_grid -/// [`progress_bar`]: https://github.com/hecrj/iced/tree/0.4/examples/progress_bar -/// [`styling`]: https://github.com/hecrj/iced/tree/0.4/examples/styling -/// [`svg`]: https://github.com/hecrj/iced/tree/0.4/examples/svg -/// [`tour`]: https://github.com/hecrj/iced/tree/0.4/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.4/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/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 b45f6415..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/0.4/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/0.4/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/0.4/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/0.4/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/0.4/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/0.4/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 b153848f..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/0.4/native +//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.4/native //! [`winit`]: https://github.com/rust-windowing/winit //! [`conversion`]: crate::conversion #![doc( -- cgit From d98d700c4dc2ca4b245a5cebae77607d2293ceab Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:27:49 +0200 Subject: Forbid `unused_results` and `rust_2018_idioms` in `iced_pure` --- pure/src/flex.rs | 2 +- pure/src/lib.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) 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( padding: Padding, spacing: f32, align_items: Alignment, - items: &[Element], + items: &[Element<'_, Message, Renderer>], ) -> Node where Renderer: iced_native::Renderer, diff --git a/pure/src/lib.rs b/pure/src/lib.rs index fc803222..6af74771 100644 --- a/pure/src/lib.rs +++ b/pure/src/lib.rs @@ -83,10 +83,9 @@ html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] #![deny(missing_docs)] -//#![deny(missing_debug_implementations)] -//#![deny(unused_results)] +#![deny(unused_results)] #![forbid(unsafe_code)] -//#![forbid(rust_2018_idioms)] +#![forbid(rust_2018_idioms)] pub mod helpers; pub mod overlay; @@ -175,7 +174,7 @@ impl State { fn diff( &mut self, - new_element: &Element, + new_element: &Element<'_, Message, Renderer>, ) { self.state_tree.diff(new_element); } -- cgit From 6fe6daa64f6a549493f641d035d5aa2eed3c58c9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:33:10 +0200 Subject: Add `html_logo_url` to `iced_core` and `iced_lazy` --- core/src/lib.rs | 3 +++ lazy/src/lib.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/core/src/lib.rs b/core/src/lib.rs index dc340d3a..7b0dc57b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -9,6 +9,9 @@ //! [Iced]: https://github.com/iced-rs/iced //! [`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/lazy/src/lib.rs b/lazy/src/lib.rs index 5d7d10e4..e1b06f74 100644 --- a/lazy/src/lib.rs +++ b/lazy/src/lib.rs @@ -1,3 +1,6 @@ +#![doc( + html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" +)] pub mod component; pub mod responsive; -- cgit From dbc24210a128a7009b997688a1684faccb725487 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:34:40 +0200 Subject: Link to `iced_web` repository in `README` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dad50e50..d8db4aed 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ __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 -- cgit From ab71e8ad145aee163337d27ef0f95a868d054927 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:36:12 +0200 Subject: Fix typo in `README` of `iced_glow` --- glow/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glow/README.md b/glow/README.md index 9d555cb1..00f38f64 100644 --- a/glow/README.md +++ b/glow/README.md @@ -6,7 +6,7 @@ `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. -- cgit From a7752a1ec0372ceeb4ca895342a9070eae03402b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 20:46:24 +0200 Subject: Capitalize `iced` once again Since its a proper noun! --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d8db4aed..2c3286e1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -# 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) @@ -40,7 +40,7 @@ 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 @@ -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: @@ -234,7 +234,7 @@ 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/iced-rs/iced/tree/master/examples -- cgit From 84c28a73e2a7ace8547e892f675bfc497d157bcb Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 21:01:25 +0200 Subject: Indicate feature-flagged modules in documentation --- lazy/src/lib.rs | 2 ++ src/lib.rs | 1 + src/widget.rs | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/lazy/src/lib.rs b/lazy/src/lib.rs index e1b06f74..916f9458 100644 --- a/lazy/src/lib.rs +++ b/lazy/src/lib.rs @@ -1,10 +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/src/lib.rs b/src/lib.rs index e154d9c7..bbc60746 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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/widget.rs b/src/widget.rs index 83df0052..5e2b63fc 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -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; -- cgit From 7e111f273fb22a6ffc7a4fd24bea5e838d276758 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 21:10:55 +0200 Subject: Enable `pure` feature in `docs.rs` --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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"] -- cgit From 990c0500806889c854388fcda0689f8e77c02199 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 21:38:21 +0200 Subject: Update `CHANGELOG` --- CHANGELOG.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a476631d..4c42ee29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] + +## [0.4.0] - 2022-05-02 +### Added +- __[Stateless widgets][stateless]__ (#1284) + A brand new widget API that removes the need to keep track of internal widget state. No more `button::State` in your application! + +- __[`Component` trait][component]__ (#1131) + A new trait to implement custom widgets with internal mutable state while using composition and [The Elm Architecture]. + +- __[`Responsive` widget][responsive]__ (#1193) + A widget that is aware of its dimensions and can be used to easily build responsive user interfaces. + +- __[Experimental WebGL support][webgl]__ (#1096) + Applications can now be rendered into an HTML `canvas` when targeting Wasm by leveraging the WebGL support in [`wgpu`]. Thanks to @pacmancoder and @kaimast! + +- __[Support for Raspberry Pis and older devices][raspberry]__ (#1160) + The compatibility of our OpenGL renderer has been improved and should run on any hardware that supports OpenGL 3.0+ or OpenGL ES 2.0+. Additionally, we started maintaining [Docker images for `aarch64` and `armv7`](https://github.com/orgs/iced-rs/packages) to easily cross-compile `iced` applications and target Raspberry Pis. Thanks to @derezzedex! + +- __[Simpler `Renderer` APIs][renderer_apis]__ (#1110) + The surface of the `Renderer` APIs of the library has been considerably reduced. Instead of a `Renderer` trait per widget, now there are only 3 traits that are reused by all the widgets. + +[webgl]: https://github.com/iced-rs/iced/pull/1096 +[renderer_apis]: https://github.com/iced-rs/iced/pull/1110 +[component]: https://github.com/iced-rs/iced/pull/1131 +[raspberry]: https://github.com/iced-rs/iced/pull/1160 +[responsive]: https://github.com/iced-rs/iced/pull/1193 +[stateless]: https://github.com/iced-rs/iced/pull/1284 +[The Elm Architecture]: https://guide.elm-lang.org/architecture/ +[`wgpu`]: https://github.com/gfx-rs/wgpu + + ## [0.3.0] - 2021-03-31 ### Added - Touch support. [#57] [#650] (thanks to @simlay and @discordance!) @@ -219,7 +250,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - First release! :tada: -[Unreleased]: https://github.com/iced-rs/iced/compare/0.3.0...HEAD +[Unreleased]: https://github.com/iced-rs/iced/compare/0.4.0...HEAD +[0.4.0]: https://github.com/iced-rs/iced/compare/0.3.0...0.4.0 [0.3.0]: https://github.com/iced-rs/iced/compare/0.2.0...0.3.0 [0.2.0]: https://github.com/iced-rs/iced/compare/0.1.1...0.2.0 [0.1.1]: https://github.com/iced-rs/iced/compare/0.1.0...0.1.1 -- cgit From d23026d2dd24ae6daa20f479678ad802f493c7bc Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 21:53:25 +0200 Subject: Bump versions :tada: --- Cargo.toml | 22 +++++++++++----------- core/Cargo.toml | 2 +- futures/Cargo.toml | 2 +- glow/Cargo.toml | 8 ++++---- glutin/Cargo.toml | 8 ++++---- graphics/Cargo.toml | 10 +++++----- lazy/Cargo.toml | 11 +++++++++-- native/Cargo.toml | 8 ++++---- pure/Cargo.toml | 12 +++++++++--- style/Cargo.toml | 4 ++-- wgpu/Cargo.toml | 6 +++--- winit/Cargo.toml | 10 +++++----- 12 files changed, 58 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 899d392a..fcb14899 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced" -version = "0.3.0" +version = "0.4.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A cross-platform GUI library inspired by Elm" @@ -98,21 +98,21 @@ members = [ ] [dependencies] -iced_core = { version = "0.4", path = "core" } -iced_futures = { version = "0.3", path = "futures" } -iced_native = { version = "0.4", path = "native" } -iced_graphics = { version = "0.2", path = "graphics" } -iced_winit = { version = "0.3", path = "winit" } -iced_glutin = { version = "0.2", path = "glutin", optional = true } -iced_glow = { version = "0.2", path = "glow", optional = true } -iced_pure = { version = "0.1", path = "pure", optional = true } +iced_core = { version = "0.5", path = "core" } +iced_futures = { version = "0.4", path = "futures" } +iced_native = { version = "0.5", path = "native" } +iced_graphics = { version = "0.3", path = "graphics" } +iced_winit = { version = "0.4", path = "winit" } +iced_glutin = { version = "0.3", path = "glutin", optional = true } +iced_glow = { version = "0.3", path = "glow", optional = true } +iced_pure = { version = "0.2", path = "pure", optional = true } thiserror = "1.0" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -iced_wgpu = { version = "0.4", path = "wgpu", optional = true } +iced_wgpu = { version = "0.5", path = "wgpu", optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] -iced_wgpu = { version = "0.4", path = "wgpu", features = ["webgl"], optional = true } +iced_wgpu = { version = "0.5", path = "wgpu", features = ["webgl"], optional = true } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] diff --git a/core/Cargo.toml b/core/Cargo.toml index a8d50801..c9c7686e 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_core" -version = "0.4.0" +version = "0.5.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "The essential concepts of Iced" diff --git a/futures/Cargo.toml b/futures/Cargo.toml index 78e673e0..ed99d79a 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_futures" -version = "0.3.0" +version = "0.4.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "Commands, subscriptions, and runtimes for Iced" diff --git a/glow/Cargo.toml b/glow/Cargo.toml index e0907a66..18215e9b 100644 --- a/glow/Cargo.toml +++ b/glow/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "iced_glow" -version = "0.2.0" +version = "0.3.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A glow renderer for iced" license = "MIT AND OFL-1.1" -repository = "https://github.com/hecrj/iced" +repository = "https://github.com/iced-rs/iced" [features] canvas = ["iced_graphics/canvas"] @@ -24,11 +24,11 @@ bytemuck = "1.4" log = "0.4" [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_graphics] -version = "0.2" +version = "0.3" path = "../graphics" features = ["font-fallback", "font-icons", "opengl"] diff --git a/glutin/Cargo.toml b/glutin/Cargo.toml index d1b0468d..fca0cd9f 100644 --- a/glutin/Cargo.toml +++ b/glutin/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_glutin" -version = "0.2.0" +version = "0.3.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A glutin runtime for Iced" @@ -19,14 +19,14 @@ git = "https://github.com/iced-rs/glutin" rev = "7a0ee02782eb2bf059095e0c953c4bb53f1eef0e" [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_winit] -version = "0.3" +version = "0.4" path = "../winit" [dependencies.iced_graphics] -version = "0.2" +version = "0.3" path = "../graphics" features = ["opengl"] diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index a84acbd6..e916975d 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "iced_graphics" -version = "0.2.0" +version = "0.3.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for Iced" license = "MIT" -repository = "https://github.com/hecrj/iced" +repository = "https://github.com/iced-rs/iced" documentation = "https://docs.rs/iced_graphics" keywords = ["gui", "ui", "graphics", "interface", "widgets"] categories = ["gui"] @@ -29,15 +29,15 @@ version = "1.4" features = ["derive"] [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_style] -version = "0.3" +version = "0.4" path = "../style" [dependencies.iced_pure] -version = "0.1" +version = "0.2" path = "../pure" optional = true diff --git a/lazy/Cargo.toml b/lazy/Cargo.toml index 2d7451f3..7d439e47 100644 --- a/lazy/Cargo.toml +++ b/lazy/Cargo.toml @@ -1,7 +1,14 @@ [package] name = "iced_lazy" version = "0.1.0" +authors = ["Héctor Ramón Jiménez "] edition = "2021" +description = "Lazy widgets for Iced" +license = "MIT" +repository = "https://github.com/iced-rs/iced" +documentation = "https://docs.rs/iced_lazy" +keywords = ["gui", "ui", "graphics", "interface", "widgets"] +categories = ["gui"] [features] pure = ["iced_pure"] @@ -10,10 +17,10 @@ pure = ["iced_pure"] ouroboros = "0.13" [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_pure] -version = "0.1" +version = "0.2" path = "../pure" optional = true diff --git a/native/Cargo.toml b/native/Cargo.toml index c4b363ae..a21385de 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_native" -version = "0.4.0" +version = "0.5.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A renderer-agnostic library for native GUIs" @@ -16,14 +16,14 @@ unicode-segmentation = "1.6" num-traits = "0.2" [dependencies.iced_core] -version = "0.4" +version = "0.5" path = "../core" [dependencies.iced_futures] -version = "0.3" +version = "0.4" path = "../futures" features = ["thread-pool"] [dependencies.iced_style] -version = "0.3" +version = "0.4" path = "../style" diff --git a/pure/Cargo.toml b/pure/Cargo.toml index 317dccdf..8369a717 100644 --- a/pure/Cargo.toml +++ b/pure/Cargo.toml @@ -1,9 +1,15 @@ [package] name = "iced_pure" -version = "0.1.0" +version = "0.2.0" edition = "2021" +description = "Pure widgets for Iced" +license = "MIT" +repository = "https://github.com/iced-rs/iced" +documentation = "https://docs.rs/iced_pure" +keywords = ["gui", "ui", "graphics", "interface", "widgets"] +categories = ["gui"] [dependencies] -iced_native = { version = "0.4", path = "../native" } -iced_style = { version = "0.3", path = "../style" } +iced_native = { version = "0.5", path = "../native" } +iced_style = { version = "0.4", path = "../style" } num-traits = "0.2" diff --git a/style/Cargo.toml b/style/Cargo.toml index 047c905d..bb2a9645 100644 --- a/style/Cargo.toml +++ b/style/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_style" -version = "0.3.0" +version = "0.4.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "The default set of styles of Iced" @@ -11,5 +11,5 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"] categories = ["gui"] [dependencies.iced_core] -version = "0.4" +version = "0.5" path = "../core" diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index b4173413..6911ff56 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_wgpu" -version = "0.4.0" +version = "0.5.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A wgpu renderer for Iced" @@ -43,11 +43,11 @@ version = "1.4" features = ["derive"] [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_graphics] -version = "0.2" +version = "0.3" path = "../graphics" features = ["font-fallback", "font-icons"] diff --git a/winit/Cargo.toml b/winit/Cargo.toml index f7232248..2beebdfb 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "iced_winit" -version = "0.3.0" +version = "0.4.0" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A winit runtime for Iced" license = "MIT" -repository = "https://github.com/hecrj/iced" +repository = "https://github.com/iced-rs/iced" documentation = "https://docs.rs/iced_winit" keywords = ["gui", "ui", "graphics", "interface", "widgets"] categories = ["gui"] @@ -24,15 +24,15 @@ git = "https://github.com/iced-rs/winit" rev = "02a12380960cec2f351c09a33d6a7cc2789d96a6" [dependencies.iced_native] -version = "0.4" +version = "0.5" path = "../native" [dependencies.iced_graphics] -version = "0.2" +version = "0.3" path = "../graphics" [dependencies.iced_futures] -version = "0.3" +version = "0.4" path = "../futures" [target.'cfg(target_os = "windows")'.dependencies.winapi] -- cgit From cb1aaf1bddd86ef37502602fe0c9d900e8f3f769 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 2 May 2022 22:18:22 +0200 Subject: Bump version in `README` --- Cargo.toml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fcb14899..3dcfacc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced" -version = "0.4.0" +version = "0.4.1" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A cross-platform GUI library inspired by Elm" diff --git a/README.md b/README.md index 2c3286e1..3d1e6e1e 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ __Iced is currently experimental software.__ [Take a look at the roadmap], Add `iced` as a dependency in your `Cargo.toml`: ```toml -iced = "0.3" +iced = "0.4" ``` __Iced moves fast and the `master` branch can contain breaking changes!__ If @@ -215,7 +215,7 @@ $ cargo run --features iced/glow --package game_of_life and then use it in your project with ```toml -iced = { version = "0.3", default-features = false, features = ["glow"] } +iced = { version = "0.4", default-features = false, features = ["glow"] } ``` **NOTE:** Chances are you have hardware that supports at least OpenGL 2.1 or OpenGL ES 2.0, -- cgit From f3d6d3bbcec195aa399db66f729a8c81a28dcfe6 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 3 May 2022 19:37:48 +0200 Subject: Expose `Padding` in `iced` root crate --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bbc60746..60606143 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -226,6 +226,6 @@ pub use settings::Settings; pub use runtime::alignment; pub use runtime::futures; pub use runtime::{ - Alignment, Background, Color, Command, ContentFit, Font, Length, Point, - Rectangle, Size, Subscription, Vector, + Alignment, Background, Color, Command, ContentFit, Font, Length, Padding, + Point, Rectangle, Size, Subscription, Vector, }; -- cgit From 30e84433f711fb2b372a0f864552a84ca25cec56 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 3 May 2022 19:42:33 +0200 Subject: Update `CHANGELOG` --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c42ee29..0f0fa47c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.2] - 2022-05-03 +### Fixed +- `Padding` type not exposed in `iced`. + +## [0.4.1] - 2022-05-02 +### Fixed +- Version number in `README`. ## [0.4.0] - 2022-05-02 ### Added @@ -250,7 +257,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - First release! :tada: -[Unreleased]: https://github.com/iced-rs/iced/compare/0.4.0...HEAD +[Unreleased]: https://github.com/iced-rs/iced/compare/0.4.2...HEAD +[0.4.2]: https://github.com/iced-rs/iced/compare/0.4.1...0.4.2 +[0.4.1]: https://github.com/iced-rs/iced/compare/0.4.0...0.4.1 [0.4.0]: https://github.com/iced-rs/iced/compare/0.3.0...0.4.0 [0.3.0]: https://github.com/iced-rs/iced/compare/0.2.0...0.3.0 [0.2.0]: https://github.com/iced-rs/iced/compare/0.1.1...0.2.0 -- cgit From 62677eafc0c11e8dcbede9870a74cdcccfeba55c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 3 May 2022 19:43:27 +0200 Subject: Bump version :tada: --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3dcfacc3..b090b58d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced" -version = "0.4.1" +version = "0.4.2" authors = ["Héctor Ramón Jiménez "] edition = "2021" description = "A cross-platform GUI library inspired by Elm" -- cgit From 02914e5e68d1fbaad53483cd32c74d9ac448d1eb Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 3 May 2022 19:48:32 +0200 Subject: Use `nightly` toolchain in `document` CI workflow --- .github/workflows/document.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/document.yml b/.github/workflows/document.yml index b67a62ab..5a8cb252 100644 --- a/.github/workflows/document.yml +++ b/.github/workflows/document.yml @@ -10,10 +10,13 @@ jobs: group: ${{ github.workflow }}-${{ github.ref }} steps: - uses: hecrj/setup-rust-action@v1 + with: + rust-version: nightly - uses: actions/checkout@v2 - name: Generate documentation run: | - cargo doc --no-deps --all-features \ + RUSTDOCFLAGS="--cfg docsrs" \ + cargo doc --no-deps --all-features \ -p iced_core \ -p iced_style \ -p iced_futures \ -- cgit

- iced ecosystem + The Iced Ecosystem