Skip to main content

hefesto_widgets/spins/
themed_spin.rs

1use ratatui::{
2    buffer::Buffer,
3    layout::Rect,
4    style::Style,
5    widgets::StatefulWidget,
6};
7
8use crate::spin::{Spin, SpinState};
9
10/// Pre-built animation frame sets.
11#[derive(Clone, Copy)]
12pub enum SpinVariant {
13    /// Braille dots spinning clockwise
14    Dots,
15    /// Left-right line oscillation
16    Line,
17    /// Braille dots in a different pattern
18    Dots2,
19    /// Bouncing ball
20    Bounce,
21    /// Expanding pulse bar
22    Pulse,
23    /// Rotating arrow
24    Arrows,
25    /// Square toggle
26    Square,
27    /// Clock face (requires emoji font support)
28    Clock,
29    /// Custom user-provided frames
30    Custom(&'static [&'static str]),
31}
32
33impl SpinVariant {
34    pub fn frames(&self) -> &'static [&'static str] {
35        match self {
36            Self::Dots => crate::DEFAULT_FRAMES,
37            Self::Line => &["╶", "╴"],
38            Self::Dots2 => &["⠄", "⠆", "⠖", "⠶", "⠾", "⠷", "⠧", "⠇"],
39            Self::Bounce => &["⢀", "⡀", "⣀", "⡄", "⢄"],
40            Self::Pulse => &["▁", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃"],
41            Self::Arrows => &["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"],
42            Self::Square => &["▰", "▱"],
43            Self::Clock => &[
44                "🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚", "🕛",
45            ],
46            Self::Custom(f) => f,
47        }
48    }
49}
50
51impl Default for SpinVariant {
52    fn default() -> Self {
53        Self::Dots
54    }
55}
56
57/// A widget wrapping [`Spin`](Spin) with pre-built animation variants.
58///
59/// Delegates rendering to [`Spin`] and shares its state ([`SpinState`](SpinState)).
60#[derive(Clone)]
61pub struct ThemedSpin {
62    spin: Spin,
63}
64
65impl ThemedSpin {
66    pub fn new() -> Self {
67        Self {
68            spin: Spin::new().frames(SpinVariant::Dots.frames()),
69        }
70    }
71
72    pub fn variant(mut self, variant: SpinVariant) -> Self {
73        self.spin = self.spin.frames(variant.frames());
74        self
75    }
76
77    pub fn spinner_style(mut self, style: Style) -> Self {
78        self.spin = self.spin.spinner_style(style);
79        self
80    }
81}
82
83impl StatefulWidget for ThemedSpin {
84    type State = SpinState;
85
86    fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
87        self.spin.render(area, buf, state);
88    }
89}