guise/feedback/
progress.rs1use gpui::prelude::*;
4use gpui::{div, px, relative, App, IntoElement, Window};
5
6use crate::theme::{theme, ColorName, Size};
7
8#[derive(IntoElement)]
11pub struct Progress {
12 value: f32,
13 color: ColorName,
14 size: Size,
15 radius: Option<Size>,
16}
17
18impl Progress {
19 pub fn new(value: f32) -> Self {
20 Progress {
21 value: value.clamp(0.0, 100.0),
22 color: ColorName::Blue,
23 size: Size::Md,
24 radius: None,
25 }
26 }
27
28 pub fn color(mut self, color: ColorName) -> Self {
29 self.color = color;
30 self
31 }
32
33 pub fn size(mut self, size: Size) -> Self {
34 self.size = size;
35 self
36 }
37
38 pub fn radius(mut self, radius: Size) -> Self {
39 self.radius = Some(radius);
40 self
41 }
42
43 fn height(&self) -> f32 {
44 match self.size {
45 Size::Xs => 4.0,
46 Size::Sm => 6.0,
47 Size::Md => 8.0,
48 Size::Lg => 12.0,
49 Size::Xl => 16.0,
50 }
51 }
52}
53
54impl RenderOnce for Progress {
55 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
56 let t = theme(cx);
57 let height = self.height();
58 let radius = self.radius.map(|r| t.radius(r)).unwrap_or(height / 2.0);
59 let track = t
60 .color(ColorName::Gray, if t.scheme.is_dark() { 7 } else { 2 })
61 .hsla();
62 let fill = t.color(self.color, t.primary_shade()).hsla();
63 let fraction = (self.value / 100.0).clamp(0.0, 1.0);
64
65 div()
66 .w_full()
67 .h(px(height))
68 .rounded(px(radius))
69 .bg(track)
70 .child(
71 div()
72 .h_full()
73 .w(relative(fraction))
74 .rounded(px(radius))
75 .bg(fill),
76 )
77 }
78}