diff --git a/hui-examples/examples/align_test.rs b/hui-examples/examples/align_test.rs index 1368dbb..95076eb 100644 --- a/hui-examples/examples/align_test.rs +++ b/hui-examples/examples/align_test.rs @@ -62,7 +62,7 @@ fn main() { children: ElementList(vec![ Box::new(ProgressBar { value: z, - corner_radius: Corners::all(0.25 * ProgressBar::DEFAULT_HEIGHT), + // corner_radius: Corners::all(0.25 * ProgressBar::DEFAULT_HEIGHT), ..Default::default() }), Box::new(Container { diff --git a/hui-examples/examples/mom_downloader.rs b/hui-examples/examples/mom_downloader.rs index 5e66bb7..cd28de0 100644 --- a/hui-examples/examples/mom_downloader.rs +++ b/hui-examples/examples/mom_downloader.rs @@ -1,6 +1,6 @@ use std::time::Instant; use hui::{ - element::{ + color, element::{ container::Container, progress_bar::ProgressBar, text::Text, @@ -43,7 +43,14 @@ ui_main!{ .add_child(ui); ProgressBar::default() .with_value(mom_ratio) - .with_corner_radius(0.125 * ProgressBar::DEFAULT_HEIGHT) + .with_background(frame_rect! { + color: color::BLACK, + corner_radius: 0.125 * ProgressBar::DEFAULT_HEIGHT + }) + .with_foreground(frame_rect! { + color: color::BLUE, + corner_radius: 0.125 * ProgressBar::DEFAULT_HEIGHT + }) .add_child(ui); Container::default() .with_direction(Direction::Horizontal) diff --git a/hui/src/element/builtin/progress_bar.rs b/hui/src/element/builtin/progress_bar.rs index c5e9c51..f9fb518 100644 --- a/hui/src/element/builtin/progress_bar.rs +++ b/hui/src/element/builtin/progress_bar.rs @@ -1,16 +1,15 @@ use derive_setters::Setters; -use glam::{vec2, vec4}; +use glam::vec2; use crate::{ - draw::{RoundedCorners, UiDrawCommand}, element::{MeasureContext, ProcessContext, UiElement}, + frame::{Frame, FrameRect}, layout::{compute_size, Size, Size2d}, measure::Response, - rect::{Corners, FillColor} }; //TODO: Use Frames here instead of FillColor -#[derive(Debug, Clone, Copy, Setters)] +#[derive(Setters)] #[setters(prefix = "with_")] pub struct ProgressBar { /// Current progress, should be in the range 0.0..=1.0 @@ -21,20 +20,26 @@ pub struct ProgressBar { pub size: Size2d, /// Foreground (bar) color - #[setters(into)] - pub foreground: FillColor, + #[setters(skip)] + pub foreground: Box, /// Background color - #[setters(into)] - pub background: FillColor, - - /// Corner radius of the progress bar - #[setters(into)] - pub corner_radius: Corners, + #[setters(skip)] + pub background: Box, } impl ProgressBar { pub const DEFAULT_HEIGHT: f32 = 20.0; + + pub fn with_background(mut self, frame: impl Frame + 'static) -> Self { + self.background = Box::new(frame); + self + } + + pub fn with_foreground(mut self, frame: impl Frame + 'static) -> Self { + self.foreground = Box::new(frame); + self + } } impl Default for ProgressBar { @@ -42,9 +47,8 @@ impl Default for ProgressBar { Self { value: 0., size: Size::Auto.into(), - foreground: vec4(0.0, 0.0, 1.0, 1.0).into(), - background: vec4(0.0, 0.0, 0.0, 1.0).into(), - corner_radius: Corners::all(0.), + foreground: Box::new(FrameRect::color((0.0, 0.0, 1.0, 1.0))), + background: Box::new(FrameRect::color((0.0, 0.0, 0.0, 1.0))), } } } @@ -57,7 +61,7 @@ impl UiElement for ProgressBar { fn measure(&self, ctx: MeasureContext) -> Response { Response { size: compute_size(ctx.layout, self.size, vec2( - ctx.layout.max_size.x.max(300.), + ctx.layout.max_size.x.max(300.), //XXX: remove .max(300)? Self::DEFAULT_HEIGHT, )), hints: Default::default(), @@ -68,40 +72,49 @@ impl UiElement for ProgressBar { fn process(&self, ctx: ProcessContext) { let value = self.value.clamp(0., 1.); - let rounded_corners = - (self.corner_radius.max_f32() > 0.).then_some({ - //HACK: fix clipping issues; //todo: get rid of this - let mut radii = self.corner_radius; - let width = ctx.measure.size.x * value; - if width <= radii.max_f32() * 2. { - radii.bottom_right = 0.; - radii.top_right = 0.; - } - if width <= radii.max_f32() { - radii.bottom_left = 0.; - radii.top_left = 0.; - } - RoundedCorners::from_radius(radii) - }); - if value < 1. { - ctx.draw.add(UiDrawCommand::Rectangle { - position: ctx.layout.position, - size: ctx.measure.size, - color: self.background.corners(), - texture: None, - texture_uv: None, - rounded_corners - }); + + //FIXME: these optimizations may not be valid + if value < 1. || !self.foreground.covers_opaque() { + self.background.draw(ctx.draw, ctx.layout.position, ctx.measure.size); } if value > 0. { - ctx.draw.add(UiDrawCommand::Rectangle { - position: ctx.layout.position, - size: ctx.measure.size * vec2(value, 1.0), - color: self.foreground.corners(), - texture: None, - texture_uv: None, - rounded_corners, - }); + self.foreground.draw(ctx.draw, ctx.layout.position, ctx.measure.size * vec2(value, 1.)); } + + // let rounded_corners = + // (self.corner_radius.max_f32() > 0.).then_some({ + // //HACK: fix clipping issues; //todo: get rid of this + // let mut radii = self.corner_radius; + // let width = ctx.measure.size.x * value; + // if width <= radii.max_f32() * 2. { + // radii.bottom_right = 0.; + // radii.top_right = 0.; + // } + // if width <= radii.max_f32() { + // radii.bottom_left = 0.; + // radii.top_left = 0.; + // } + // RoundedCorners::from_radius(radii) + // }); + // if value < 1. { + // ctx.draw.add(UiDrawCommand::Rectangle { + // position: ctx.layout.position, + // size: ctx.measure.size, + // color: self.background.corners(), + // texture: None, + // texture_uv: None, + // rounded_corners + // }); + // } + // if value > 0. { + // ctx.draw.add(UiDrawCommand::Rectangle { + // position: ctx.layout.position, + // size: ctx.measure.size * vec2(value, 1.0), + // color: self.foreground.corners(), + // texture: None, + // texture_uv: None, + // rounded_corners, + // }); + // } } }