summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/progress_bar/src/main.rs42
-rw-r--r--widget/src/progress_bar.rs87
2 files changed, 101 insertions, 28 deletions
diff --git a/examples/progress_bar/src/main.rs b/examples/progress_bar/src/main.rs
index 67da62f2..e431a404 100644
--- a/examples/progress_bar/src/main.rs
+++ b/examples/progress_bar/src/main.rs
@@ -1,4 +1,7 @@
-use iced::widget::{column, progress_bar, slider};
+use iced::widget::{
+ center, center_x, checkbox, column, progress_bar, row, slider,
+ vertical_slider,
+};
use iced::Element;
pub fn main() -> iced::Result {
@@ -8,25 +11,58 @@ pub fn main() -> iced::Result {
#[derive(Default)]
struct Progress {
value: f32,
+ is_vertical: bool,
}
#[derive(Debug, Clone, Copy)]
enum Message {
SliderChanged(f32),
+ ToggleVertical(bool),
}
impl Progress {
fn update(&mut self, message: Message) {
match message {
Message::SliderChanged(x) => self.value = x,
+ Message::ToggleVertical(is_vertical) => {
+ self.is_vertical = is_vertical
+ }
}
}
fn view(&self) -> Element<Message> {
+ let bar = progress_bar(0.0..=100.0, self.value);
+
column![
- progress_bar(0.0..=100.0, self.value),
- slider(0.0..=100.0, self.value, Message::SliderChanged).step(0.01)
+ if self.is_vertical {
+ center(
+ row![
+ bar.vertical(),
+ vertical_slider(
+ 0.0..=100.0,
+ self.value,
+ Message::SliderChanged
+ )
+ .step(0.01)
+ ]
+ .spacing(20),
+ )
+ } else {
+ center(
+ column![
+ bar,
+ slider(0.0..=100.0, self.value, Message::SliderChanged)
+ .step(0.01)
+ ]
+ .spacing(20),
+ )
+ },
+ center_x(
+ checkbox("Vertical", self.is_vertical)
+ .on_toggle(Message::ToggleVertical)
+ ),
]
+ .spacing(20)
.padding(20)
.into()
}
diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs
index 8f85dcf3..0af0a073 100644
--- a/widget/src/progress_bar.rs
+++ b/widget/src/progress_bar.rs
@@ -59,8 +59,9 @@ where
{
range: RangeInclusive<f32>,
value: f32,
- width: Length,
- height: Option<Length>,
+ length: Length,
+ girth: Length,
+ is_vertical: bool,
class: Theme::Class<'a>,
}
@@ -68,8 +69,8 @@ impl<'a, Theme> ProgressBar<'a, Theme>
where
Theme: Catalog,
{
- /// The default height of a [`ProgressBar`].
- pub const DEFAULT_HEIGHT: f32 = 30.0;
+ /// The default girth of a [`ProgressBar`].
+ pub const DEFAULT_GIRTH: f32 = 30.0;
/// Creates a new [`ProgressBar`].
///
@@ -80,21 +81,30 @@ where
ProgressBar {
value: value.clamp(*range.start(), *range.end()),
range,
- width: Length::Fill,
- height: None,
+ length: Length::Fill,
+ girth: Length::from(Self::DEFAULT_GIRTH),
+ is_vertical: false,
class: Theme::default(),
}
}
/// Sets the width of the [`ProgressBar`].
- pub fn width(mut self, width: impl Into<Length>) -> Self {
- self.width = width.into();
+ pub fn length(mut self, length: impl Into<Length>) -> Self {
+ self.length = length.into();
self
}
/// Sets the height of the [`ProgressBar`].
- pub fn height(mut self, height: impl Into<Length>) -> Self {
- self.height = Some(height.into());
+ pub fn girth(mut self, girth: impl Into<Length>) -> Self {
+ self.girth = girth.into();
+ self
+ }
+
+ /// Turns the [`ProgressBar`] into a vertical [`ProgressBar`].
+ ///
+ /// By default, a [`ProgressBar`] is horizontal.
+ pub fn vertical(mut self) -> Self {
+ self.is_vertical = true;
self
}
@@ -115,6 +125,22 @@ where
self.class = class.into();
self
}
+
+ fn width(&self) -> Length {
+ if self.is_vertical {
+ self.girth
+ } else {
+ self.length
+ }
+ }
+
+ fn height(&self) -> Length {
+ if self.is_vertical {
+ self.length
+ } else {
+ self.girth
+ }
+ }
}
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>
@@ -125,8 +151,8 @@ where
{
fn size(&self) -> Size<Length> {
Size {
- width: self.width,
- height: self.height.unwrap_or(Length::Fixed(Self::DEFAULT_HEIGHT)),
+ width: self.width(),
+ height: self.height(),
}
}
@@ -136,11 +162,7 @@ where
_renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- layout::atomic(
- limits,
- self.width,
- self.height.unwrap_or(Length::Fixed(Self::DEFAULT_HEIGHT)),
- )
+ layout::atomic(limits, self.width(), self.height())
}
fn draw(
@@ -156,11 +178,16 @@ where
let bounds = layout.bounds();
let (range_start, range_end) = self.range.clone().into_inner();
- let active_progress_width = if range_start >= range_end {
+ let length = if self.is_vertical {
+ bounds.height
+ } else {
+ bounds.width
+ };
+
+ let active_progress_length = if range_start >= range_end {
0.0
} else {
- bounds.width * (self.value - range_start)
- / (range_end - range_start)
+ length * (self.value - range_start) / (range_end - range_start)
};
let style = theme.style(&self.class);
@@ -174,13 +201,23 @@ where
style.background,
);
- if active_progress_width > 0.0 {
+ if active_progress_length > 0.0 {
+ let bounds = if self.is_vertical {
+ Rectangle {
+ y: bounds.y + bounds.height - active_progress_length,
+ height: active_progress_length,
+ ..bounds
+ }
+ } else {
+ Rectangle {
+ width: active_progress_length,
+ ..bounds
+ }
+ };
+
renderer.fill_quad(
renderer::Quad {
- bounds: Rectangle {
- width: active_progress_width,
- ..bounds
- },
+ bounds,
border: Border {
color: Color::TRANSPARENT,
..style.border