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
59 .radius
60 .map(|r| t.radius(r))
61 .unwrap_or(height / 2.0);
62 let track = t
63 .color(ColorName::Gray, if t.scheme.is_dark() { 7 } else { 2 })
64 .hsla();
65 let fill = t.color(self.color, t.primary_shade()).hsla();
66 let fraction = (self.value / 100.0).clamp(0.0, 1.0);
67
68 div()
69 .w_full()
70 .h(px(height))
71 .rounded(px(radius))
72 .bg(track)
73 .child(
74 div()
75 .h_full()
76 .w(relative(fraction))
77 .rounded(px(radius))
78 .bg(fill),
79 )
80 }
81}