diff options
author | 2020-02-06 01:24:40 +0100 | |
---|---|---|
committer | 2020-02-06 01:24:40 +0100 | |
commit | f5228695a2fcdecd1da9071d477ee34855783b29 (patch) | |
tree | e0fd0698b6a7813af05229008d5d482608e1db35 /web | |
parent | acfc815e1df7209d1e43f36e5f465b0ac44294cc (diff) | |
download | iced-f5228695a2fcdecd1da9071d477ee34855783b29.tar.gz iced-f5228695a2fcdecd1da9071d477ee34855783b29.tar.bz2 iced-f5228695a2fcdecd1da9071d477ee34855783b29.zip |
Implement `ProgressBar` widget in `iced_web`
Diffstat (limited to 'web')
-rw-r--r-- | web/src/widget.rs | 2 | ||||
-rw-r--r-- | web/src/widget/progress_bar.rs | 125 |
2 files changed, 127 insertions, 0 deletions
diff --git a/web/src/widget.rs b/web/src/widget.rs index e5481243..025cf22f 100644 --- a/web/src/widget.rs +++ b/web/src/widget.rs @@ -21,6 +21,7 @@ pub mod button; pub mod checkbox; pub mod container; pub mod image; +pub mod progress_bar; pub mod radio; pub mod scrollable; pub mod slider; @@ -46,6 +47,7 @@ pub use checkbox::Checkbox; pub use column::Column; pub use container::Container; pub use image::Image; +pub use progress_bar::ProgressBar; pub use radio::Radio; pub use row::Row; pub use space::Space; diff --git a/web/src/widget/progress_bar.rs b/web/src/widget/progress_bar.rs new file mode 100644 index 00000000..b1fcb4d8 --- /dev/null +++ b/web/src/widget/progress_bar.rs @@ -0,0 +1,125 @@ +//! Provide progress feedback to your users. +use crate::{bumpalo, css, Bus, Css, Element, Length, Widget}; + +pub use iced_style::progress_bar::{Style, StyleSheet}; + +use std::ops::RangeInclusive; + +/// A bar that displays progress. +/// +/// # Example +/// ``` +/// # use iced_native::renderer::Null; +/// # +/// # pub type ProgressBar = iced_native::ProgressBar<Null>; +/// let value = 50.0; +/// +/// ProgressBar::new(0.0..=100.0, value); +/// ``` +/// +///  +#[allow(missing_debug_implementations)] +pub struct ProgressBar { + range: RangeInclusive<f32>, + value: f32, + width: Length, + height: Option<Length>, + style: Box<dyn StyleSheet>, +} + +impl ProgressBar { + /// Creates a new [`ProgressBar`]. + /// + /// It expects: + /// * an inclusive range of possible values + /// * the current value of the [`ProgressBar`] + /// + /// [`ProgressBar`]: struct.ProgressBar.html + pub fn new(range: RangeInclusive<f32>, value: f32) -> Self { + ProgressBar { + value: value.max(*range.start()).min(*range.end()), + range, + width: Length::Fill, + height: None, + style: Default::default(), + } + } + + /// Sets the width of the [`ProgressBar`]. + /// + /// [`ProgressBar`]: struct.ProgressBar.html + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + /// Sets the height of the [`ProgressBar`]. + /// + /// [`ProgressBar`]: struct.ProgressBar.html + pub fn height(mut self, height: Length) -> Self { + self.height = Some(height); + self + } + + /// Sets the style of the [`ProgressBar`]. + /// + /// [`ProgressBar`]: struct.ProgressBar.html + pub fn style(mut self, style: impl Into<Box<dyn StyleSheet>>) -> Self { + self.style = style.into(); + self + } +} + +impl<Message> Widget<Message> for ProgressBar { + fn node<'b>( + &self, + bump: &'b bumpalo::Bump, + _bus: &Bus<Message>, + _style_sheet: &mut Css<'b>, + ) -> dodrio::Node<'b> { + use dodrio::builder::*; + + let (range_start, range_end) = self.range.clone().into_inner(); + let amount_filled = + (self.value - range_start) / (range_end - range_start).max(1.0); + + let style = self.style.style(); + + let bar = div(bump) + .attr( + "style", + bumpalo::format!( + in bump, + "width: {}%; height: 100%; background: {}", + amount_filled * 100.0, + css::background(style.bar) + ) + .into_bump_str(), + ) + .finish(); + + let node = div(bump).attr( + "style", + bumpalo::format!( + in bump, + "width: {}; height: {}; background: {}; border-radius: {}px; overflow: hidden;", + css::length(self.width), + css::length(self.height.unwrap_or(Length::Units(30))), + css::background(style.background), + style.border_radius + ) + .into_bump_str(), + ).children(vec![bar]); + + node.finish() + } +} + +impl<'a, Message> From<ProgressBar> for Element<'a, Message> +where + Message: 'static, +{ + fn from(container: ProgressBar) -> Element<'a, Message> { + Element::new(container) + } +} |