Skip to main content

itools_tui/components/
loading_animation.rs

1//! 加载动画组件
2
3use crate::{layout::Rect, render::Frame, style::Style};
4use std::time::Duration;
5
6/// 加载动画组件
7pub struct LoadingAnimation {
8    /// 加载消息
9    message: String,
10    /// 动画帧
11    frames: Vec<String>,
12    /// 当前帧索引
13    current_frame: usize,
14    /// 动画速度
15    frame_duration: Duration,
16    /// 样式
17    style: Style,
18}
19
20impl LoadingAnimation {
21    /// 创建新的加载动画
22    pub fn new(message: &str) -> Self {
23        Self {
24            message: message.to_string(),
25            frames: vec!["|".to_string(), "/".to_string(), "-".to_string(), "\\".to_string()],
26            current_frame: 0,
27            frame_duration: Duration::from_millis(100),
28            style: Style::new(),
29        }
30    }
31
32    /// 设置动画帧
33    pub fn frames(mut self, frames: Vec<String>) -> Self {
34        self.frames = frames;
35        self
36    }
37
38    /// 设置动画速度
39    pub fn frame_duration(mut self, duration: Duration) -> Self {
40        self.frame_duration = duration;
41        self
42    }
43
44    /// 设置样式
45    pub fn style(mut self, style: Style) -> Self {
46        self.style = style;
47        self
48    }
49
50    /// 更新动画帧
51    pub fn tick(&mut self) {
52        self.current_frame = (self.current_frame + 1) % self.frames.len();
53    }
54
55    /// 获取当前帧
56    pub fn current_frame(&self) -> &str {
57        &self.frames[self.current_frame]
58    }
59}
60
61impl super::Component for LoadingAnimation {
62    fn render(&self, frame: &mut Frame, area: Rect) {
63        frame.render_loading_animation(&self.message, self.current_frame(), area, self.style.clone());
64    }
65
66    fn handle_event(&mut self, _event: &crate::event::Event) -> bool {
67        false
68    }
69}