From 52a185fbab728b85cf414d4997567f52ebc66205 Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Sat, 19 Sep 2020 18:44:27 +0200 Subject: [PATCH 01/14] Implement `Toggler` widget for iced_native --- graphics/src/widget.rs | 3 + graphics/src/widget/toggler.rs | 94 ++++++++++++ native/src/renderer/null.rs | 18 ++- native/src/widget.rs | 3 + native/src/widget/toggler.rs | 262 +++++++++++++++++++++++++++++++++ src/widget.rs | 6 +- style/src/lib.rs | 1 + style/src/toggler.rs | 57 +++++++ wgpu/src/widget.rs | 3 + wgpu/src/widget/toggler.rs | 9 ++ 10 files changed, 452 insertions(+), 4 deletions(-) create mode 100644 graphics/src/widget/toggler.rs create mode 100644 native/src/widget/toggler.rs create mode 100644 style/src/toggler.rs create mode 100644 wgpu/src/widget/toggler.rs diff --git a/graphics/src/widget.rs b/graphics/src/widget.rs index 190ea9c05d..e34d267f0f 100644 --- a/graphics/src/widget.rs +++ b/graphics/src/widget.rs @@ -20,6 +20,7 @@ pub mod scrollable; pub mod slider; pub mod svg; pub mod text_input; +pub mod toggler; pub mod tooltip; mod column; @@ -50,6 +51,8 @@ pub use slider::Slider; #[doc(no_inline)] pub use text_input::TextInput; #[doc(no_inline)] +pub use toggler::Toggler; +#[doc(no_inline)] pub use tooltip::Tooltip; pub use column::Column; diff --git a/graphics/src/widget/toggler.rs b/graphics/src/widget/toggler.rs new file mode 100644 index 0000000000..a258443ef1 --- /dev/null +++ b/graphics/src/widget/toggler.rs @@ -0,0 +1,94 @@ +//! Show toggle controls using togglers. +use crate::backend::{self, Backend}; +use crate::{Primitive, Renderer}; +use iced_native::mouse; +use iced_native::toggler; +use iced_native::Rectangle; + +pub use iced_style::toggler::{Style, StyleSheet}; + +/// Makes sure that the border radius of the toggler looks good at every size. +const BORDER_RADIUS_RATIO: f32 = 32.0 / 13.0; + +/// The space ratio between the background Quad and the Toggler bounds, and +/// between the background Quad and foreground Quad. +const SPACE_RATIO: f32 = 0.05; + +/// A toggler that can be toggled. +/// +/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`. +pub type Toggler = + iced_native::Toggler>; + +impl toggler::Renderer for Renderer +where + B: Backend + backend::Text, +{ + type Style = Box; + + const DEFAULT_SIZE: u16 = 20; + + fn draw( + &mut self, + bounds: Rectangle, + is_active: bool, + is_mouse_over: bool, + (label, _): Self::Output, + style_sheet: &Self::Style, + ) -> Self::Output { + let style = if is_mouse_over { + style_sheet.hovered(is_active) + } else { + style_sheet.active(is_active) + }; + + let border_radius = bounds.height as f32 / BORDER_RADIUS_RATIO; + let space = SPACE_RATIO * bounds.height as f32; + + let toggler_background_bounds = Rectangle { + x: bounds.x + space, + y: bounds.y + space, + width: bounds.width - (2.0 * space), + height: bounds.height - (2.0 * space), + }; + + let toggler_background = Primitive::Quad { + bounds: toggler_background_bounds, + background: style.background.into(), + border_radius, + border_width: 1.0, + border_color: style.background_border.unwrap_or(style.background), + }; + + let toggler_foreground_bounds = Rectangle { + x: bounds.x + + if is_active { + bounds.width - 2.0 * space - (bounds.height - (4.0 * space)) + } else { + 2.0 * space + }, + y: bounds.y + (2.0 * space), + width: bounds.height - (4.0 * space), + height: bounds.height - (4.0 * space), + }; + + let toggler_foreground = Primitive::Quad { + bounds: toggler_foreground_bounds, + background: style.foreground.into(), + border_radius, + border_width: 1.0, + border_color: style.foreground_border.unwrap_or(style.foreground), + }; + + ( + Primitive::Group { + primitives: vec![label, toggler_background, toggler_foreground], + }, + if is_mouse_over { + mouse::Interaction::Pointer + } else { + mouse::Interaction::default() + }, + ) + } +} diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index 28746585d0..89bb9433c7 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -1,6 +1,6 @@ use crate::{ button, checkbox, column, container, pane_grid, progress_bar, radio, row, - scrollable, slider, text, text_input, Color, Element, Font, + scrollable, slider, text, text_input, toggler, Color, Element, Font, HorizontalAlignment, Layout, Padding, Point, Rectangle, Renderer, Size, VerticalAlignment, }; @@ -288,3 +288,19 @@ impl pane_grid::Renderer for Null { ) { } } + +impl toggler::Renderer for Null { + type Style = (); + + const DEFAULT_SIZE: u16 = 20; + + fn draw( + &mut self, + _bounds: Rectangle, + _is_checked: bool, + _is_mouse_over: bool, + _label: Self::Output, + _style: &Self::Style, + ) { + } +} diff --git a/native/src/widget.rs b/native/src/widget.rs index 791c53a3e4..759fe71a68 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -36,6 +36,7 @@ pub mod space; pub mod svg; pub mod text; pub mod text_input; +pub mod toggler; pub mod tooltip; #[doc(no_inline)] @@ -73,6 +74,8 @@ pub use text::Text; #[doc(no_inline)] pub use text_input::TextInput; #[doc(no_inline)] +pub use toggler::Toggler; +#[doc(no_inline)] pub use tooltip::Tooltip; use crate::event::{self, Event}; diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs new file mode 100644 index 0000000000..250abac42f --- /dev/null +++ b/native/src/widget/toggler.rs @@ -0,0 +1,262 @@ +//! Show toggle controls using togglers. +use std::hash::Hash; + +use crate::{ + event, layout, mouse, row, text, Align, Clipboard, Element, Event, Hasher, + HorizontalAlignment, Layout, Length, Point, Rectangle, Row, Text, + VerticalAlignment, Widget, +}; + +/// A toggler widget +/// +/// # Example +/// +/// ``` +/// # type Toggler = iced_native::Toggler; +/// # +/// pub enum Message { +/// TogglerToggled(bool), +/// } +/// +/// let is_active = true; +/// +/// Toggler::new(is_active, "Toggle me!", |b| Message::TogglerToggled(b)) +/// ``` +/// +#[allow(missing_debug_implementations)] +pub struct Toggler { + is_active: bool, + on_toggle: Box Message>, + label: String, + width: Length, + size: u16, + text_size: Option, + font: Renderer::Font, + style: Renderer::Style, +} + +impl + Toggler +{ + /// Creates a new [`Toggler`]. + /// + /// It expects: + /// * a boolean describing whether the [`Toggler`] is checked or not + /// * the label of the [`Toggler`] + /// * a function that will be called when the [`Toggler`] is toggled. It + /// will receive the new state of the [`Toggler`] and must produce a + /// `Message`. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn new(is_active: bool, label: impl Into, f: F) -> Self + where + F: 'static + Fn(bool) -> Message, + { + Toggler { + is_active, + on_toggle: Box::new(f), + label: label.into(), + width: Length::Fill, + size: ::DEFAULT_SIZE, + text_size: None, + font: Renderer::Font::default(), + style: Renderer::Style::default(), + } + } + + /// Sets the size of the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn size(mut self, size: u16) -> Self { + self.size = size; + self + } + + /// Sets the width of the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + /// Sets the text size o the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn text_size(mut self, text_size: u16) -> Self { + self.text_size = Some(text_size); + self + } + + /// Sets the [`Font`] of the text of the [`Toggler`] + /// + /// [`Toggler`]: struct.Toggler.html + /// [`Font`]: ../../struct.Font.html + pub fn font(mut self, font: Renderer::Font) -> Self { + self.font = font; + self + } + + /// Sets the style of the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn style(mut self, style: impl Into) -> Self { + self.style = style.into(); + self + } +} + +impl Widget for Toggler +where + Renderer: self::Renderer + text::Renderer + row::Renderer, +{ + fn width(&self) -> Length { + self.width + } + + fn height(&self) -> Length { + Length::Shrink + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + Row::<(), Renderer>::new() + .width(self.width) + .align_items(Align::Center) + .push( + Text::new(&self.label) + .font(self.font) + .width(self.width) + .size(self.text_size.unwrap_or(renderer.default_size())), + ) + .push( + Row::new() + .width(Length::Units(2 * self.size)) + .height(Length::Units(self.size)), + ) + .layout(renderer, limits) + } + + fn on_event( + &mut self, + event: Event, + layout: Layout<'_>, + cursor_position: Point, + _renderer: &Renderer, + _clipboard: &mut dyn Clipboard, + messages: &mut Vec, + ) -> event::Status { + match event { + Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { + let mouse_over = layout.bounds().contains(cursor_position); + + if mouse_over { + messages.push((self.on_toggle)(!self.is_active)); + + event::Status::Captured + } else { + event::Status::Ignored + } + } + _ => event::Status::Ignored, + } + } + + fn draw( + &self, + renderer: &mut Renderer, + defaults: &Renderer::Defaults, + layout: Layout<'_>, + cursor_position: Point, + _viewport: &Rectangle, + ) -> Renderer::Output { + let bounds = layout.bounds(); + let mut children = layout.children(); + + let label_layout = children.next().unwrap(); + let toggler_layout = children.next().unwrap(); + let toggler_bounds = toggler_layout.bounds(); + + let label = text::Renderer::draw( + renderer, + defaults, + label_layout.bounds(), + &self.label, + self.text_size.unwrap_or(renderer.default_size()), + self.font, + None, + HorizontalAlignment::Left, + VerticalAlignment::Center, + ); + + let is_mouse_over = bounds.contains(cursor_position); + + self::Renderer::draw( + renderer, + toggler_bounds, + self.is_active, + is_mouse_over, + label, + &self.style, + ) + } + + fn hash_layout(&self, state: &mut Hasher) { + struct Marker; + std::any::TypeId::of::().hash(state); + + self.label.hash(state) + } +} + +/// The renderer of a [`Toggler`]. +/// +/// Your [renderer] will need to implement this trait before being +/// able to use a [`Toggler`] in your user interface. +/// +/// [`Toggler`]: struct.Toggler.html +/// [renderer]: ../../renderer/index.html +pub trait Renderer: crate::Renderer { + /// The style supported by this renderer. + type Style: Default; + + /// The default size of a [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + const DEFAULT_SIZE: u16; + + /// Draws a [`Toggler`]. + /// + /// It receives: + /// * the bounds of the [`Toggler`] + /// * whether the [`Toggler`] is activated or not + /// * whether the mouse is over the [`Toggler`] or not + /// * the drawn label of the [`Toggler`] + /// * the style of the [`Toggler`] + /// + /// [`Toggler`]: struct.Toggler.html + fn draw( + &mut self, + bounds: Rectangle, + is_active: bool, + is_mouse_over: bool, + label: Self::Output, + style: &Self::Style, + ) -> Self::Output; +} + +impl<'a, Message, Renderer> From> + for Element<'a, Message, Renderer> +where + Renderer: 'a + self::Renderer + text::Renderer + row::Renderer, + Message: 'a, +{ + fn from( + toggler: Toggler, + ) -> Element<'a, Message, Renderer> { + Element::new(toggler) + } +} diff --git a/src/widget.rs b/src/widget.rs index eac50d576c..db052106a8 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -17,8 +17,8 @@ mod platform { pub use crate::renderer::widget::{ button, checkbox, container, pane_grid, pick_list, progress_bar, radio, - rule, scrollable, slider, text_input, tooltip, Column, Row, Space, - Text, + rule, scrollable, slider, text_input, toggler, tooltip, Column, Row, + Space, Text, }; #[cfg(any(feature = "canvas", feature = "glow_canvas"))] @@ -53,7 +53,7 @@ mod platform { button::Button, checkbox::Checkbox, container::Container, image::Image, pane_grid::PaneGrid, pick_list::PickList, progress_bar::ProgressBar, radio::Radio, rule::Rule, scrollable::Scrollable, slider::Slider, - svg::Svg, text_input::TextInput, tooltip::Tooltip, + svg::Svg, text_input::TextInput, toggler::Toggler, tooltip::Tooltip, }; #[cfg(any(feature = "canvas", feature = "glow_canvas"))] diff --git a/style/src/lib.rs b/style/src/lib.rs index f09b5f9d7c..08d9f0444a 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -18,3 +18,4 @@ pub mod rule; pub mod scrollable; pub mod slider; pub mod text_input; +pub mod toggler; diff --git a/style/src/toggler.rs b/style/src/toggler.rs new file mode 100644 index 0000000000..5a15512374 --- /dev/null +++ b/style/src/toggler.rs @@ -0,0 +1,57 @@ +//! Show toggle controls using togglers. +use iced_core::Color; + +/// The appearance of a toggler. +#[derive(Debug)] +pub struct Style { + pub background: Color, + pub background_border: Option, + pub foreground: Color, + pub foreground_border: Option, +} + +/// A set of rules that dictate the style of a toggler. +pub trait StyleSheet { + fn active(&self, is_active: bool) -> Style; + + fn hovered(&self, is_active: bool) -> Style; +} + +struct Default; + +impl StyleSheet for Default { + fn active(&self, is_active: bool) -> Style { + Style { + background: if is_active { + Color::from_rgb(0.0, 1.0, 0.0) + } else { + Color::from_rgb(0.7, 0.7, 0.7) + }, + background_border: None, + foreground: Color::WHITE, + foreground_border: None, + } + } + + fn hovered(&self, is_active: bool) -> Style { + Style { + foreground: Color::from_rgb(0.95, 0.95, 0.95), + ..self.active(is_active) + } + } +} + +impl std::default::Default for Box { + fn default() -> Self { + Box::new(Default) + } +} + +impl From for Box +where + T: 'static + StyleSheet, +{ + fn from(style: T) -> Self { + Box::new(style) + } +} diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index 304bb726c3..a575d03693 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -20,6 +20,7 @@ pub mod rule; pub mod scrollable; pub mod slider; pub mod text_input; +pub mod toggler; pub mod tooltip; #[doc(no_inline)] @@ -45,6 +46,8 @@ pub use slider::Slider; #[doc(no_inline)] pub use text_input::TextInput; #[doc(no_inline)] +pub use toggler::Toggler; +#[doc(no_inline)] pub use tooltip::Tooltip; #[cfg(feature = "canvas")] diff --git a/wgpu/src/widget/toggler.rs b/wgpu/src/widget/toggler.rs new file mode 100644 index 0000000000..dfcf759bd0 --- /dev/null +++ b/wgpu/src/widget/toggler.rs @@ -0,0 +1,9 @@ +//! Show toggle controls using togglers. +use crate::Renderer; + +pub use iced_graphics::toggler::{Style, StyleSheet}; + +/// A toggler that can be toggled +/// +/// This is an alias of an `iced_native` toggler with an `iced_wgpu::Renderer`. +pub type Toggler = iced_native::Toggler; From 7370dfac6e798667771d768dbc5c3ed04930364c Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Sat, 19 Sep 2020 19:57:56 +0200 Subject: [PATCH 02/14] fix missing semicolon in doc test --- native/src/widget/toggler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 250abac42f..1acdf6ecb2 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -20,7 +20,7 @@ use crate::{ /// /// let is_active = true; /// -/// Toggler::new(is_active, "Toggle me!", |b| Message::TogglerToggled(b)) +/// Toggler::new(is_active, "Toggle me!", |b| Message::TogglerToggled(b)); /// ``` /// #[allow(missing_debug_implementations)] From 88da268724527e1b41c303ebec9056a606a01486 Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Sat, 19 Sep 2020 20:16:36 +0200 Subject: [PATCH 03/14] add missing glow support --- glow/src/widget.rs | 3 +++ glow/src/widget/toggler.rs | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 glow/src/widget/toggler.rs diff --git a/glow/src/widget.rs b/glow/src/widget.rs index 5481216a29..a77511e812 100644 --- a/glow/src/widget.rs +++ b/glow/src/widget.rs @@ -20,6 +20,7 @@ pub mod rule; pub mod scrollable; pub mod slider; pub mod text_input; +pub mod toggler; pub mod tooltip; #[doc(no_inline)] @@ -45,6 +46,8 @@ pub use slider::Slider; #[doc(no_inline)] pub use text_input::TextInput; #[doc(no_inline)] +pub use toggler::Toggler; +#[doc(no_inline)] pub use tooltip::Tooltip; #[cfg(feature = "canvas")] diff --git a/glow/src/widget/toggler.rs b/glow/src/widget/toggler.rs new file mode 100644 index 0000000000..0bd5b75808 --- /dev/null +++ b/glow/src/widget/toggler.rs @@ -0,0 +1,9 @@ +//! Show toggle controls using togglers. +use crate::Renderer; + +pub use iced_graphics::toggler::{Style, StyleSheet}; + +/// A toggler that can be toggled. +/// +/// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`. +pub type Toggler = iced_native::Toggler; \ No newline at end of file From bab71971fb6653c81e74a517c9ace93be63b49fc Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Sat, 19 Sep 2020 20:20:14 +0200 Subject: [PATCH 04/14] fix format --- glow/src/widget/toggler.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glow/src/widget/toggler.rs b/glow/src/widget/toggler.rs index 0bd5b75808..1cd8711bf5 100644 --- a/glow/src/widget/toggler.rs +++ b/glow/src/widget/toggler.rs @@ -4,6 +4,6 @@ use crate::Renderer; pub use iced_graphics::toggler::{Style, StyleSheet}; /// A toggler that can be toggled. -/// +/// /// This is an alias of an `iced_native` checkbox with an `iced_wgpu::Renderer`. -pub type Toggler = iced_native::Toggler; \ No newline at end of file +pub type Toggler = iced_native::Toggler; From aa18a6e0d5550a83510aaf38a2b01d4a5fa56ccd Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Thu, 24 Sep 2020 15:49:48 +0200 Subject: [PATCH 05/14] Add alignment of `Toggler` label. --- native/src/widget/toggler.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 1acdf6ecb2..63058d06b6 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -31,6 +31,8 @@ pub struct Toggler { width: Length, size: u16, text_size: Option, + text_align: Option, + spacing: u16, font: Renderer::Font, style: Renderer::Style, } @@ -59,6 +61,8 @@ impl width: Length::Fill, size: ::DEFAULT_SIZE, text_size: None, + text_align: None, + spacing: 0, font: Renderer::Font::default(), style: Renderer::Style::default(), } @@ -88,6 +92,22 @@ impl self } + /// Sets the alignment of the text of the [`Toggler`] + /// + /// [`Toggler`]: struct.Toggler.html + pub fn text_align(mut self, align: HorizontalAlignment) -> Self { + self.text_align = Some(align); + self + } + + /// Sets the spacing between the [`Toggler`] and the text. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn spacing(mut self, spacing: u16) -> Self { + self.spacing = spacing; + self + } + /// Sets the [`Font`] of the text of the [`Toggler`] /// /// [`Toggler`]: struct.Toggler.html @@ -125,9 +145,13 @@ where ) -> layout::Node { Row::<(), Renderer>::new() .width(self.width) + .spacing(self.spacing) .align_items(Align::Center) .push( Text::new(&self.label) + .horizontal_alignment( + self.text_align.unwrap_or(HorizontalAlignment::Left), + ) .font(self.font) .width(self.width) .size(self.text_size.unwrap_or(renderer.default_size())), @@ -188,7 +212,7 @@ where self.text_size.unwrap_or(renderer.default_size()), self.font, None, - HorizontalAlignment::Left, + self.text_align.unwrap_or(HorizontalAlignment::Left), VerticalAlignment::Center, ); From 7a626f3b7b6871052e5fade697e120cfb7d726d7 Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Thu, 24 Sep 2020 16:31:39 +0200 Subject: [PATCH 06/14] Change label of `Toggler` to optional --- graphics/src/widget/toggler.rs | 9 ++++- native/src/renderer/null.rs | 2 +- native/src/widget/toggler.rs | 74 +++++++++++++++++++++------------- 3 files changed, 53 insertions(+), 32 deletions(-) diff --git a/graphics/src/widget/toggler.rs b/graphics/src/widget/toggler.rs index a258443ef1..852d18ee8e 100644 --- a/graphics/src/widget/toggler.rs +++ b/graphics/src/widget/toggler.rs @@ -33,7 +33,7 @@ where bounds: Rectangle, is_active: bool, is_mouse_over: bool, - (label, _): Self::Output, + label: Option, style_sheet: &Self::Style, ) -> Self::Output { let style = if is_mouse_over { @@ -82,7 +82,12 @@ where ( Primitive::Group { - primitives: vec![label, toggler_background, toggler_foreground], + primitives: match label { + Some((l, _)) => { + vec![l, toggler_background, toggler_foreground] + } + None => vec![toggler_background, toggler_foreground], + }, }, if is_mouse_over { mouse::Interaction::Pointer diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index 89bb9433c7..bb57c163d5 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -299,7 +299,7 @@ impl toggler::Renderer for Null { _bounds: Rectangle, _is_checked: bool, _is_mouse_over: bool, - _label: Self::Output, + _label: Option, _style: &Self::Style, ) { } diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 63058d06b6..36e7d1105a 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -20,14 +20,14 @@ use crate::{ /// /// let is_active = true; /// -/// Toggler::new(is_active, "Toggle me!", |b| Message::TogglerToggled(b)); +/// Toggler::new(is_active, String::from("Toggle me!"), |b| Message::TogglerToggled(b)); /// ``` /// #[allow(missing_debug_implementations)] pub struct Toggler { is_active: bool, on_toggle: Box Message>, - label: String, + label: Option, width: Length, size: u16, text_size: Option, @@ -44,13 +44,17 @@ impl /// /// It expects: /// * a boolean describing whether the [`Toggler`] is checked or not - /// * the label of the [`Toggler`] + /// * An optional label for the [`Toggler`] /// * a function that will be called when the [`Toggler`] is toggled. It /// will receive the new state of the [`Toggler`] and must produce a /// `Message`. /// /// [`Toggler`]: struct.Toggler.html - pub fn new(is_active: bool, label: impl Into, f: F) -> Self + pub fn new( + is_active: bool, + label: impl Into>, + f: F, + ) -> Self where F: 'static + Fn(bool) -> Message, { @@ -143,25 +147,30 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - Row::<(), Renderer>::new() + let mut row = Row::<(), Renderer>::new() .width(self.width) .spacing(self.spacing) - .align_items(Align::Center) - .push( - Text::new(&self.label) + .align_items(Align::Center); + + if let Some(label) = &self.label { + row = row.push( + Text::new(label) .horizontal_alignment( self.text_align.unwrap_or(HorizontalAlignment::Left), ) .font(self.font) .width(self.width) .size(self.text_size.unwrap_or(renderer.default_size())), - ) - .push( - Row::new() - .width(Length::Units(2 * self.size)) - .height(Length::Units(self.size)), - ) - .layout(renderer, limits) + ); + } + + row = row.push( + Row::new() + .width(Length::Units(2 * self.size)) + .height(Length::Units(self.size)), + ); + + row.layout(renderer, limits) } fn on_event( @@ -200,22 +209,29 @@ where let bounds = layout.bounds(); let mut children = layout.children(); - let label_layout = children.next().unwrap(); + let label = match &self.label { + Some(label) => { + let label_layout = children.next().unwrap(); + + Some(text::Renderer::draw( + renderer, + defaults, + label_layout.bounds(), + &label, + self.text_size.unwrap_or(renderer.default_size()), + self.font, + None, + self.text_align.unwrap_or(HorizontalAlignment::Left), + VerticalAlignment::Center, + )) + } + + None => None, + }; + let toggler_layout = children.next().unwrap(); let toggler_bounds = toggler_layout.bounds(); - let label = text::Renderer::draw( - renderer, - defaults, - label_layout.bounds(), - &self.label, - self.text_size.unwrap_or(renderer.default_size()), - self.font, - None, - self.text_align.unwrap_or(HorizontalAlignment::Left), - VerticalAlignment::Center, - ); - let is_mouse_over = bounds.contains(cursor_position); self::Renderer::draw( @@ -267,7 +283,7 @@ pub trait Renderer: crate::Renderer { bounds: Rectangle, is_active: bool, is_mouse_over: bool, - label: Self::Output, + label: Option, style: &Self::Style, ) -> Self::Output; } From 1ef38cc207ad5a393cb54ea779ae87eec2cd5ad9 Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Fri, 25 Sep 2020 15:45:46 +0200 Subject: [PATCH 07/14] Add `Toggler` to styling example --- examples/styling/src/main.rs | 73 +++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 4d7dfc48d6..7bc49281a9 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -1,7 +1,7 @@ use iced::{ button, scrollable, slider, text_input, Align, Button, Checkbox, Column, Container, Element, Length, ProgressBar, Radio, Row, Rule, Sandbox, - Scrollable, Settings, Slider, Space, Text, TextInput, + Scrollable, Settings, Slider, Space, Text, TextInput, Toggler, }; pub fn main() -> iced::Result { @@ -17,7 +17,8 @@ struct Styling { button: button::State, slider: slider::State, slider_value: f32, - toggle_value: bool, + checkbox_value: bool, + toggler_value: bool, } #[derive(Debug, Clone)] @@ -27,6 +28,7 @@ enum Message { ButtonPressed, SliderChanged(f32), CheckboxToggled(bool), + TogglerToggled(bool), } impl Sandbox for Styling { @@ -46,7 +48,8 @@ impl Sandbox for Styling { Message::InputChanged(value) => self.input_value = value, Message::ButtonPressed => {} Message::SliderChanged(value) => self.slider_value = value, - Message::CheckboxToggled(value) => self.toggle_value = value, + Message::CheckboxToggled(value) => self.checkbox_value = value, + Message::TogglerToggled(value) => self.toggler_value = value, } } @@ -101,11 +104,19 @@ impl Sandbox for Styling { .push(Text::new("You did it!")); let checkbox = Checkbox::new( - self.toggle_value, - "Toggle me!", + self.checkbox_value, + "Check me!", Message::CheckboxToggled, ) - .width(Length::Fill) + .style(self.theme); + + let toggler = Toggler::new( + self.toggler_value, + String::from("Toggle me!"), + Message::TogglerToggled, + ) + .width(Length::Shrink) + .spacing(10) .style(self.theme); let content = Column::new() @@ -124,7 +135,13 @@ impl Sandbox for Styling { .align_items(Align::Center) .push(scrollable) .push(Rule::vertical(38).style(self.theme)) - .push(checkbox), + .push( + Column::new() + .width(Length::Shrink) + .spacing(20) + .push(checkbox) + .push(toggler), + ), ); Container::new(content) @@ -140,7 +157,7 @@ impl Sandbox for Styling { mod style { use iced::{ button, checkbox, container, progress_bar, radio, rule, scrollable, - slider, text_input, + slider, text_input, toggler, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -231,6 +248,15 @@ mod style { } } + impl From for Box { + fn from(theme: Theme) -> Self { + match theme { + Theme::Light => Default::default(), + Theme::Dark => dark::Toggler.into(), + } + } + } + impl From for Box { fn from(theme: Theme) -> Self { match theme { @@ -269,7 +295,7 @@ mod style { mod dark { use iced::{ button, checkbox, container, progress_bar, radio, rule, scrollable, - slider, text_input, Color, + slider, text_input, toggler, Color, }; const SURFACE: Color = Color::from_rgb( @@ -520,6 +546,35 @@ mod style { } } + pub struct Toggler; + + impl toggler::StyleSheet for Toggler { + fn active(&self, is_active: bool) -> toggler::Style { + toggler::Style { + background: if is_active { ACTIVE } else { SURFACE }, + background_border: None, + foreground: if is_active { Color::WHITE } else { ACTIVE }, + foreground_border: None, + } + } + + fn hovered(&self, is_active: bool) -> toggler::Style { + toggler::Style { + background: if is_active { ACTIVE } else { SURFACE }, + background_border: None, + foreground: if is_active { + Color { + a: 0.5, + ..Color::WHITE + } + } else { + Color { a: 0.5, ..ACTIVE } + }, + foreground_border: None, + } + } + } + pub struct Rule; impl rule::StyleSheet for Rule { From be3ee9adf1659cf8eaa7a75cbb2aa1ecc33e4c42 Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Fri, 25 Sep 2020 16:35:58 +0200 Subject: [PATCH 08/14] Add `Toggler` to tour example --- examples/tour/src/main.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index e8755d3922..de93544454 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -1,7 +1,7 @@ use iced::{ button, scrollable, slider, text_input, Button, Checkbox, Color, Column, Container, Element, HorizontalAlignment, Image, Length, Radio, Row, - Sandbox, Scrollable, Settings, Slider, Space, Text, TextInput, + Sandbox, Scrollable, Settings, Slider, Space, Text, TextInput, Toggler, }; pub fn main() -> iced::Result { @@ -135,6 +135,9 @@ impl Steps { color: Color::BLACK, }, Step::Radio { selection: None }, + Step::Toggler { + can_continue: false, + }, Step::Image { width: 300, slider: slider::State::new(), @@ -206,6 +209,9 @@ enum Step { Radio { selection: Option, }, + Toggler { + can_continue: bool, + }, Image { width: u16, slider: slider::State, @@ -232,6 +238,7 @@ pub enum StepMessage { InputChanged(String), ToggleSecureInput(bool), DebugToggled(bool), + TogglerChanged(bool), } impl<'a> Step { @@ -287,6 +294,11 @@ impl<'a> Step { *is_secure = toggle; } } + StepMessage::TogglerChanged(value) => { + if let Step::Toggler { can_continue, .. } = self { + *can_continue = value; + } + } }; } @@ -294,6 +306,7 @@ impl<'a> Step { match self { Step::Welcome => "Welcome", Step::Radio { .. } => "Radio button", + Step::Toggler { .. } => "Toggler", Step::Slider { .. } => "Slider", Step::Text { .. } => "Text", Step::Image { .. } => "Image", @@ -309,6 +322,7 @@ impl<'a> Step { match self { Step::Welcome => true, Step::Radio { selection } => *selection == Some(Language::Rust), + Step::Toggler { can_continue } => *can_continue, Step::Slider { .. } => true, Step::Text { .. } => true, Step::Image { .. } => true, @@ -324,6 +338,7 @@ impl<'a> Step { match self { Step::Welcome => Self::welcome(), Step::Radio { selection } => Self::radio(*selection), + Step::Toggler { can_continue } => Self::toggler(*can_continue), Step::Slider { state, value } => Self::slider(state, *value), Step::Text { size_slider, @@ -545,6 +560,18 @@ impl<'a> Step { )) } + fn toggler(can_continue: bool) -> Column<'a, StepMessage> { + Self::container("Toggler") + .push(Text::new( + "A toggler is mostly used to enable or disable something.", + )) + .push(Toggler::new( + can_continue, + String::from("Toggle me to continue..."), + StepMessage::TogglerChanged, + )) + } + fn image( width: u16, slider: &'a mut slider::State, From c0cfd9d5cf373d4d7f89cf14c15f36e9995c1dbf Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Fri, 25 Sep 2020 16:38:30 +0200 Subject: [PATCH 09/14] Update documentation of `Toggler` --- native/src/widget/toggler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 36e7d1105a..8dbd94a152 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -96,7 +96,7 @@ impl self } - /// Sets the alignment of the text of the [`Toggler`] + /// Sets the horizontal alignment of the text of the [`Toggler`] /// /// [`Toggler`]: struct.Toggler.html pub fn text_align(mut self, align: HorizontalAlignment) -> Self { From e00fca637202d7cd20fd10b2d7e2b2963f11dd33 Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Sat, 3 Oct 2020 18:26:31 +0200 Subject: [PATCH 10/14] Add `Toggler` widget to `iced_web` --- web/src/css.rs | 44 ++++++++++ web/src/widget.rs | 3 + web/src/widget/toggler.rs | 168 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 web/src/widget/toggler.rs diff --git a/web/src/css.rs b/web/src/css.rs index 66c363f26d..21f51f8552 100644 --- a/web/src/css.rs +++ b/web/src/css.rs @@ -14,6 +14,9 @@ pub enum Rule { /// Spacing between elements Spacing(u16), + + /// Toggler input for a specific size + Toggler(u16), } impl Rule { @@ -23,6 +26,7 @@ impl Rule { Rule::Column => String::from("c"), Rule::Row => String::from("r"), Rule::Spacing(spacing) => format!("s-{}", spacing), + Rule::Toggler(size) => format!("toggler-{}", size), } } @@ -55,6 +59,46 @@ impl Rule { class ) .into_bump_str(), + Rule::Toggler(size) => bumpalo::format!( + in bump, + ".toggler-{} {{ display: flex; cursor: pointer; justify-content: space-between; }} \ + .toggler-{} input {{ display:none; }} \ + .toggler-{} span {{ background-color: #b1b1b1; position: relative; display: inline-flex; width:{}px; height: {}px; border-radius: {}px;}} \ + .toggler-{} span > span {{ background-color: #FFFFFF; width: {}px; height: {}px; border-radius: 50%; top: 1px; left: 1px;}} \ + .toggler-{}:hover span > span {{ background-color: #f1f1f1 !important; }} \ + .toggler-{} input:checked + span {{ background-color: #00FF00; }} \ + .toggler-{} input:checked + span > span {{ -webkit-transform: translateX({}px); -ms-transform:translateX({}px); transform: translateX({}px); }} + ", + // toggler + size, + + // toggler input + size, + + // toggler span + size, + size*2, + size, + size, + + // toggler span > span + size, + size-2, + size-2, + + // toggler: hover + span > span + size, + + // toggler input:checked + span + size, + + // toggler input:checked + span > span + size, + size, + size, + size + ) + .into_bump_str(), } } } diff --git a/web/src/widget.rs b/web/src/widget.rs index 023f5f1301..4cb0a9cc2d 100644 --- a/web/src/widget.rs +++ b/web/src/widget.rs @@ -24,6 +24,7 @@ pub mod radio; pub mod scrollable; pub mod slider; pub mod text_input; +pub mod toggler; mod column; mod row; @@ -40,6 +41,8 @@ pub use slider::Slider; pub use text::Text; #[doc(no_inline)] pub use text_input::TextInput; +#[doc(no_inline)] +pub use toggler::Toggler; pub use checkbox::Checkbox; pub use column::Column; diff --git a/web/src/widget/toggler.rs b/web/src/widget/toggler.rs new file mode 100644 index 0000000000..5bcc1fc765 --- /dev/null +++ b/web/src/widget/toggler.rs @@ -0,0 +1,168 @@ +//! Show toggle controls using togglers. +use crate::{css, Bus, Css, Element, Length, Widget}; + +pub use iced_style::toggler::{Style, StyleSheet}; + +use dodrio::bumpalo; +use std::rc::Rc; + +/// A toggler that can be toggled. +/// +/// # Example +/// +/// ``` +/// # use iced_web::Toggler; +/// +/// pub enum Message { +/// TogglerToggled(bool), +/// } +/// +/// let is_active = true; +/// +/// Toggler::new(is_active, String::from("Toggle me!"), Message::TogglerToggled); +/// ``` +/// +#[allow(missing_debug_implementations)] +pub struct Toggler { + is_active: bool, + on_toggle: Rc Message>, + label: Option, + id: Option, + width: Length, + style: Box, +} + +impl Toggler { + /// Creates a new [`Toggler`]. + /// + /// It expects: + /// * a boolean describing whether the [`Toggler`] is active or not + /// * An optional label for the [`Toggler`] + /// * a function that will be called when the [`Toggler`] is toggled. It + /// will receive the new state of the [`Toggler`] and must produce a + /// `Message`. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn new(is_active: bool, label: impl Into>, f: F) -> Self + where + F: 'static + Fn(bool) -> Message, + { + Toggler { + is_active, + on_toggle: Rc::new(f), + label: label.into(), + id: None, + width: Length::Shrink, + style: Default::default(), + } + } + + /// Sets the width of the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + /// Sets the style of the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn style(mut self, style: impl Into>) -> Self { + self.style = style.into(); + self + } + + /// Sets the id of the [`Toggler`]. + /// + /// [`Toggler`]: struct.Toggler.html + pub fn id(mut self, id: impl Into) -> Self { + self.id = Some(id.into()); + self + } +} + +impl Widget for Toggler +where + Message: 'static, +{ + fn node<'b>( + &self, + bump: &'b bumpalo::Bump, + bus: &Bus, + style_sheet: &mut Css<'b>, + ) -> dodrio::Node<'b> { + use dodrio::builder::*; + use dodrio::bumpalo::collections::String; + + let toggler_label = &self.label.as_ref().map(|label| { + String::from_str_in(&label, bump).into_bump_str() + }); + + let event_bus = bus.clone(); + let on_toggle = self.on_toggle.clone(); + let is_active = self.is_active; + + let row_class = style_sheet.insert(bump, css::Rule::Row); + let toggler_class = style_sheet.insert(bump, css::Rule::Toggler(16)); + + let (label, input) = if let Some(id) = &self.id { + let id = String::from_str_in(id, bump).into_bump_str(); + + (label(bump).attr("for", id), input(bump).attr("id", id)) + } else { + (label(bump), input(bump)) + }; + + let checkbox = input + .attr("type", "checkbox") + .bool_attr("checked", self.is_active) + .on("click", move |_root, vdom, _event| { + let msg = on_toggle(!is_active); + event_bus.publish(msg); + + vdom.schedule_render(); + }) + .finish(); + + let toggler = span(bump) + .children(vec![span(bump).finish()]) + .finish(); + + label + .attr( + "class", + bumpalo::format!(in bump, "{} {}", row_class, toggler_class) + .into_bump_str(), + ) + .attr( + "style", + bumpalo::format!(in bump, "width: {}; align-items: center", css::length(self.width)) + .into_bump_str() + ) + .children( + if let Some(label) = toggler_label { + vec![ + text(label), + checkbox, + toggler, + ] + } else { + vec![ + checkbox, + toggler, + ] + } + ) + .finish() + } +} + +impl<'a, Message> From> for Element<'a, Message> +where + Message: 'static, +{ + fn from(toggler: Toggler) -> Element<'a, Message> { + Element::new(toggler) + } +} \ No newline at end of file From 2a5aa69024fe8c73929a4c616f02c50eb5ce43ae Mon Sep 17 00:00:00 2001 From: Kaiden42 Date: Sat, 3 Oct 2020 20:30:08 +0200 Subject: [PATCH 11/14] Fix format --- web/src/widget/toggler.rs | 43 +++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/web/src/widget/toggler.rs b/web/src/widget/toggler.rs index 5bcc1fc765..0a198079ac 100644 --- a/web/src/widget/toggler.rs +++ b/web/src/widget/toggler.rs @@ -7,21 +7,21 @@ use dodrio::bumpalo; use std::rc::Rc; /// A toggler that can be toggled. -/// +/// /// # Example -/// +/// /// ``` /// # use iced_web::Toggler; -/// +/// /// pub enum Message { /// TogglerToggled(bool), /// } -/// +/// /// let is_active = true; -/// +/// /// Toggler::new(is_active, String::from("Toggle me!"), Message::TogglerToggled); /// ``` -/// +/// #[allow(missing_debug_implementations)] pub struct Toggler { is_active: bool, @@ -34,16 +34,20 @@ pub struct Toggler { impl Toggler { /// Creates a new [`Toggler`]. - /// + /// /// It expects: /// * a boolean describing whether the [`Toggler`] is active or not /// * An optional label for the [`Toggler`] /// * a function that will be called when the [`Toggler`] is toggled. It /// will receive the new state of the [`Toggler`] and must produce a /// `Message`. - /// + /// /// [`Toggler`]: struct.Toggler.html - pub fn new(is_active: bool, label: impl Into>, f: F) -> Self + pub fn new( + is_active: bool, + label: impl Into>, + f: F, + ) -> Self where F: 'static + Fn(bool) -> Message, { @@ -58,7 +62,7 @@ impl Toggler { } /// Sets the width of the [`Toggler`]. - /// + /// /// [`Toggler`]: struct.Toggler.html pub fn width(mut self, width: Length) -> Self { self.width = width; @@ -66,7 +70,7 @@ impl Toggler { } /// Sets the style of the [`Toggler`]. - /// + /// /// [`Toggler`]: struct.Toggler.html pub fn style(mut self, style: impl Into>) -> Self { self.style = style.into(); @@ -74,7 +78,7 @@ impl Toggler { } /// Sets the id of the [`Toggler`]. - /// + /// /// [`Toggler`]: struct.Toggler.html pub fn id(mut self, id: impl Into) -> Self { self.id = Some(id.into()); @@ -95,9 +99,10 @@ where use dodrio::builder::*; use dodrio::bumpalo::collections::String; - let toggler_label = &self.label.as_ref().map(|label| { - String::from_str_in(&label, bump).into_bump_str() - }); + let toggler_label = &self + .label + .as_ref() + .map(|label| String::from_str_in(&label, bump).into_bump_str()); let event_bus = bus.clone(); let on_toggle = self.on_toggle.clone(); @@ -125,9 +130,7 @@ where }) .finish(); - let toggler = span(bump) - .children(vec![span(bump).finish()]) - .finish(); + let toggler = span(bump).children(vec![span(bump).finish()]).finish(); label .attr( @@ -140,7 +143,7 @@ where bumpalo::format!(in bump, "width: {}; align-items: center", css::length(self.width)) .into_bump_str() ) - .children( + .children( if let Some(label) = toggler_label { vec![ text(label), @@ -165,4 +168,4 @@ where fn from(toggler: Toggler) -> Element<'a, Message> { Element::new(toggler) } -} \ No newline at end of file +} From a32ce271bd38a6d405859210fa3fbd5a14146ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n?= Date: Thu, 3 Jun 2021 20:27:32 +0700 Subject: [PATCH 12/14] Rename `text_align` to `text_alignment` in `Toggler` --- native/src/widget/toggler.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 8dbd94a152..d565bda16e 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -31,7 +31,7 @@ pub struct Toggler { width: Length, size: u16, text_size: Option, - text_align: Option, + text_alignment: HorizontalAlignment, spacing: u16, font: Renderer::Font, style: Renderer::Style, @@ -65,7 +65,7 @@ impl width: Length::Fill, size: ::DEFAULT_SIZE, text_size: None, - text_align: None, + text_alignment: HorizontalAlignment::Left, spacing: 0, font: Renderer::Font::default(), style: Renderer::Style::default(), @@ -99,8 +99,8 @@ impl /// Sets the horizontal alignment of the text of the [`Toggler`] /// /// [`Toggler`]: struct.Toggler.html - pub fn text_align(mut self, align: HorizontalAlignment) -> Self { - self.text_align = Some(align); + pub fn text_alignment(mut self, alignment: HorizontalAlignment) -> Self { + self.text_alignment = alignment; self } @@ -155,9 +155,7 @@ where if let Some(label) = &self.label { row = row.push( Text::new(label) - .horizontal_alignment( - self.text_align.unwrap_or(HorizontalAlignment::Left), - ) + .horizontal_alignment(self.text_alignment) .font(self.font) .width(self.width) .size(self.text_size.unwrap_or(renderer.default_size())), @@ -221,7 +219,7 @@ where self.text_size.unwrap_or(renderer.default_size()), self.font, None, - self.text_align.unwrap_or(HorizontalAlignment::Left), + self.text_alignment, VerticalAlignment::Center, )) } From ef5f46bcddffb191bde5dd2df131bdd1197a1e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n?= Date: Thu, 3 Jun 2021 20:28:36 +0700 Subject: [PATCH 13/14] Use intra-doc links in `Toggler` docs --- native/src/widget/toggler.rs | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index d565bda16e..4035276c55 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -22,7 +22,6 @@ use crate::{ /// /// Toggler::new(is_active, String::from("Toggle me!"), |b| Message::TogglerToggled(b)); /// ``` -/// #[allow(missing_debug_implementations)] pub struct Toggler { is_active: bool, @@ -48,8 +47,6 @@ impl /// * a function that will be called when the [`Toggler`] is toggled. It /// will receive the new state of the [`Toggler`] and must produce a /// `Message`. - /// - /// [`Toggler`]: struct.Toggler.html pub fn new( is_active: bool, label: impl Into>, @@ -73,57 +70,42 @@ impl } /// Sets the size of the [`Toggler`]. - /// - /// [`Toggler`]: struct.Toggler.html pub fn size(mut self, size: u16) -> Self { self.size = size; self } /// Sets the width of the [`Toggler`]. - /// - /// [`Toggler`]: struct.Toggler.html pub fn width(mut self, width: Length) -> Self { self.width = width; self } /// Sets the text size o the [`Toggler`]. - /// - /// [`Toggler`]: struct.Toggler.html pub fn text_size(mut self, text_size: u16) -> Self { self.text_size = Some(text_size); self } /// Sets the horizontal alignment of the text of the [`Toggler`] - /// - /// [`Toggler`]: struct.Toggler.html pub fn text_alignment(mut self, alignment: HorizontalAlignment) -> Self { self.text_alignment = alignment; self } /// Sets the spacing between the [`Toggler`] and the text. - /// - /// [`Toggler`]: struct.Toggler.html pub fn spacing(mut self, spacing: u16) -> Self { self.spacing = spacing; self } /// Sets the [`Font`] of the text of the [`Toggler`] - /// - /// [`Toggler`]: struct.Toggler.html - /// [`Font`]: ../../struct.Font.html pub fn font(mut self, font: Renderer::Font) -> Self { self.font = font; self } /// Sets the style of the [`Toggler`]. - /// - /// [`Toggler`]: struct.Toggler.html pub fn style(mut self, style: impl Into) -> Self { self.style = style.into(); self @@ -255,15 +237,12 @@ where /// Your [renderer] will need to implement this trait before being /// able to use a [`Toggler`] in your user interface. /// -/// [`Toggler`]: struct.Toggler.html /// [renderer]: ../../renderer/index.html pub trait Renderer: crate::Renderer { /// The style supported by this renderer. type Style: Default; /// The default size of a [`Toggler`]. - /// - /// [`Toggler`]: struct.Toggler.html const DEFAULT_SIZE: u16; /// Draws a [`Toggler`]. @@ -274,8 +253,6 @@ pub trait Renderer: crate::Renderer { /// * whether the mouse is over the [`Toggler`] or not /// * the drawn label of the [`Toggler`] /// * the style of the [`Toggler`] - /// - /// [`Toggler`]: struct.Toggler.html fn draw( &mut self, bounds: Rectangle, From d3d6f3efb33f601ff3fca4a6496cfeef052501ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n?= Date: Thu, 3 Jun 2021 20:35:26 +0700 Subject: [PATCH 14/14] Add some horizontal padding to `toggler` section in `tour` example --- examples/tour/src/main.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index de93544454..1215f83de5 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -565,11 +565,14 @@ impl<'a> Step { .push(Text::new( "A toggler is mostly used to enable or disable something.", )) - .push(Toggler::new( - can_continue, - String::from("Toggle me to continue..."), - StepMessage::TogglerChanged, - )) + .push( + Container::new(Toggler::new( + can_continue, + String::from("Toggle me to continue..."), + StepMessage::TogglerChanged, + )) + .padding([0, 40]), + ) } fn image(