Implement ProgressBar
widget in iced_web
This commit is contained in:
parent
acfc815e1d
commit
f5228695a2
@ -21,6 +21,7 @@ pub mod button;
|
|||||||
pub mod checkbox;
|
pub mod checkbox;
|
||||||
pub mod container;
|
pub mod container;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
pub mod progress_bar;
|
||||||
pub mod radio;
|
pub mod radio;
|
||||||
pub mod scrollable;
|
pub mod scrollable;
|
||||||
pub mod slider;
|
pub mod slider;
|
||||||
@ -46,6 +47,7 @@ pub use checkbox::Checkbox;
|
|||||||
pub use column::Column;
|
pub use column::Column;
|
||||||
pub use container::Container;
|
pub use container::Container;
|
||||||
pub use image::Image;
|
pub use image::Image;
|
||||||
|
pub use progress_bar::ProgressBar;
|
||||||
pub use radio::Radio;
|
pub use radio::Radio;
|
||||||
pub use row::Row;
|
pub use row::Row;
|
||||||
pub use space::Space;
|
pub use space::Space;
|
||||||
|
125
web/src/widget/progress_bar.rs
Normal file
125
web/src/widget/progress_bar.rs
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user