diff --git a/src/widget/progress_bar/linear.rs b/src/widget/progress_bar/linear.rs index b8e92453..941666a2 100644 --- a/src/widget/progress_bar/linear.rs +++ b/src/widget/progress_bar/linear.rs @@ -175,6 +175,7 @@ where } } + #[allow(clippy::too_many_lines)] fn draw( &self, tree: &Tree, @@ -197,62 +198,50 @@ where let border_color = custom_style.border_color.unwrap_or(custom_style.bar_color); let radius = custom_style.border_radius; - let mut draw_quad = |x: f32, - width: f32, - color: iced::Color, - mut border: iced::Border, - is_track: bool, - total_progress_width: f32| { - let mut height = bounds.height; - if !is_track { - // For progress that is at the end of completion - if total_progress_width > bounds.width - radius { - let border_radius = - radius.min(bounds.height / 2.0) - (bounds.width - total_progress_width); - border.radius.top_right = border_radius; - border.radius.bottom_right = border_radius; - } else { - border.radius.top_right = 0.0; - border.radius.bottom_right = 0.0; - } - - // For indeterminate mode or when progress has just started - if x < radius.min(bounds.height / 2.0) { - let border_radius = radius.min(bounds.height / 2.0) - x; - border.radius.top_left = border_radius; - border.radius.bottom_left = border_radius; - - if total_progress_width < radius.min(bounds.height / 2.0) { - height = bounds.height - 2.0 * radius.min(bounds.height / 2.0) - + total_progress_width * 2.0; - } - } else { - border.radius.top_left = 0.0; - border.radius.bottom_left = 0.0; - } - - if x > bounds.width - radius.min(bounds.height / 2.0) { - height = bounds.height - 2.0 * radius.min(bounds.height / 2.0) + width * 2.0; - } - } - - renderer.fill_quad( - renderer::Quad { - bounds: Rectangle { - x: bounds.x + x, - y: bounds.y + (bounds.height - height) / 2.0, - width, - height, - }, - border, - snap: true, - ..renderer::Quad::default() - }, - color, - ); - }; - if self.progress.is_some() { + let mut draw_quad = + |start: f32, segment_width: f32, progress_width: f32, border: iced::Border| { + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: bounds.x + start, + y: bounds.y, + width: segment_width, + height: bounds.height, + }, + border, + snap: true, + ..renderer::Quad::default() + }, + custom_style.track_color, + ); + + renderer.with_layer( + Rectangle { + x: bounds.x + start, + y: bounds.y, + width: progress_width, + height: bounds.height, + }, + |renderer| { + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: bounds.x + start, + y: bounds.y, + width: segment_width, + height: bounds.height, + }, + border, + snap: true, + ..renderer::Quad::default() + }, + custom_style.bar_color, + ); + }, + ); + }; + let current_p = state.progress.current; let len = self.markers.len(); let spacing = self.segment_spacing; @@ -265,7 +254,6 @@ where }; let drawable = 1.0 - gap * len as f32; - let mut absolute_width = 0.0; for i in 0..=len { let (seg_lo, r_left) = if i == 0 { (0.0, radius) @@ -279,65 +267,21 @@ where }; let x_start = seg_lo * drawable + i as f32 * gap; let x_width = (seg_hi - seg_lo) * drawable; + let segment_radius = [r_left, r_right, r_right, r_left].into(); - let mut segment_radius = if i == 0 && len == 0 { - [r_left, r_right, r_right, r_left].into() - } else if i == 0 { - [r_left, 0.0, 0.0, r_left].into() - } else if i == len { - [0.0, r_right, r_right, 0.0].into() - } else { - [0.0, 0.0, 0.0, 0.0].into() - }; - - // draw track segment + let fill = ((current_p - seg_lo) / (seg_hi - seg_lo)).min(1.0); draw_quad( x_start * bounds.width, x_width * bounds.width, - custom_style.track_color, + x_width * fill * bounds.width, iced::Border { width: border_width, color: border_color, radius: segment_radius, }, - true, - bounds.width, ); - - // draw bar segment - if current_p > seg_lo { - let fill = ((current_p - seg_lo) / (seg_hi - seg_lo)).min(1.0); - absolute_width += x_width * fill + if i == 0 { 0.0 } else { gap }; - segment_radius = [r_left, r_right, r_right, r_left].into(); - draw_quad( - x_start * bounds.width, - x_width * fill * bounds.width, - custom_style.bar_color, - iced::Border { - radius: segment_radius, - ..iced::Border::default() - }, - false, - absolute_width * bounds.width, - ); - } } } else { - // draw track - draw_quad( - 0.0, - bounds.width, - custom_style.track_color, - iced::Border { - width: border_width, - color: border_color, - radius: radius.into(), - }, - true, - bounds.width, - ); - - // draw bar let (bar_start, bar_end) = state .animation @@ -347,25 +291,73 @@ where let right_width = (1.0 - start).min(length); let left_width = length - right_width; let border = iced::Border { + width: border_width, + color: border_color, radius: radius.into(), - ..iced::Border::default() }; - draw_quad( - start * bounds.width, - right_width * bounds.width, - custom_style.bar_color, - border, - false, - (right_width + start) * bounds.width, + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height, + }, + border, + ..renderer::Quad::default() + }, + custom_style.track_color, ); - draw_quad( - 0.0, - left_width * bounds.width, - custom_style.bar_color, - border, - false, - left_width * bounds.width, + + renderer.with_layer( + Rectangle { + x: bounds.x, + y: bounds.y, + width: left_width * bounds.width, + height: bounds.height, + }, + |renderer| { + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height, + }, + border, + snap: true, + ..renderer::Quad::default() + }, + custom_style.bar_color, + ); + }, + ); + + renderer.with_layer( + Rectangle { + x: bounds.x + start * bounds.width, + y: bounds.y, + width: right_width * bounds.width, + height: bounds.height, + }, + |renderer| { + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height, + }, + border, + snap: true, + ..renderer::Quad::default() + }, + custom_style.bar_color, + ); + }, ); } }