summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-02-06 01:24:40 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-02-06 01:24:40 +0100
commitf5228695a2fcdecd1da9071d477ee34855783b29 (patch)
treee0fd0698b6a7813af05229008d5d482608e1db35 /web
parentacfc815e1df7209d1e43f36e5f465b0ac44294cc (diff)
downloadiced-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.rs2
-rw-r--r--web/src/widget/progress_bar.rs125
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);
+/// ```
+///
+/// ![Progress bar drawn with `iced_wgpu`](https://user-images.githubusercontent.com/18618951/71662391-a316c200-2d51-11ea-9cef-52758cab85e3.png)
+#[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)
+ }
+}