gpui_component/
indicator.rs1use std::time::Duration;
2
3use crate::{Icon, IconName, Sizable, Size};
4use gpui::{
5 div, ease_in_out, percentage, prelude::FluentBuilder as _, Animation, AnimationExt as _, App,
6 Hsla, IntoElement, ParentElement, RenderOnce, Styled as _, Transformation, Window,
7};
8
9#[derive(IntoElement)]
10pub struct Indicator {
11 size: Size,
12 icon: Icon,
13 speed: Duration,
14 color: Option<Hsla>,
15}
16
17impl Indicator {
18 pub fn new() -> Self {
19 Self {
20 size: Size::Medium,
21 speed: Duration::from_secs_f64(0.8),
22 icon: Icon::new(IconName::Loader),
23 color: None,
24 }
25 }
26
27 pub fn icon(mut self, icon: impl Into<Icon>) -> Self {
28 self.icon = icon.into();
29 self
30 }
31
32 pub fn color(mut self, color: Hsla) -> Self {
33 self.color = Some(color);
34 self
35 }
36}
37
38impl Sizable for Indicator {
39 fn with_size(mut self, size: impl Into<Size>) -> Self {
40 self.size = size.into();
41 self
42 }
43}
44
45impl RenderOnce for Indicator {
46 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
47 div()
48 .child(
49 self.icon
50 .with_size(self.size)
51 .when_some(self.color, |this, color| this.text_color(color))
52 .with_animation(
53 "circle",
54 Animation::new(self.speed).repeat().with_easing(ease_in_out),
55 |this, delta| this.transform(Transformation::rotate(percentage(delta))),
56 ),
57 )
58 .into_element()
59 }
60}