aboutsummaryrefslogtreecommitdiff
path: root/src/animations.rs
blob: 634986b3aa9c377c26663e975e36436b241f09a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use crate::IndicatorConfig;
use std::thread;
use std::time::Duration;

pub struct Animation {
    duration_per_frame: Duration,
    frames: Vec<xcb::Arc>,
    clear: bool,
}

impl Animation {
    pub fn circles(
        config: IndicatorConfig,
        function: Box<dyn DoubleEndedIterator<Item = u16>>,
        clear: bool,
    ) -> Animation {
        let no_of_frames = config.framerate;
        let duration_per_frame =
            Duration::from_millis(config.duration).div_f64(no_of_frames as f64);
        let frames = function
            .map(|i| {
                xcb::Arc::new(
                    ((config.max_size as f32) / (2. * no_of_frames as f32) * i as f32) as i16, // x
                    ((config.max_size as f32) / (2. * no_of_frames as f32) * i as f32) as i16, // y
                    (config.max_size) - (config.max_size / no_of_frames) * i as u16, // width
                    (config.max_size) - (config.max_size / no_of_frames) * i as u16, // height
                    0,                                                               // start angle
                    360 << 6,                                                        // end angle
                )
            })
            .collect::<Vec<xcb::Arc>>();
        return Animation {
            duration_per_frame,
            frames,
            clear,
        };
    }
    pub fn play(&self, conn: &xcb::Connection, win: u32, gfx_ctx: u32) {
        for frame in &self.frames {
            xcb::poly_arc(&conn, win, gfx_ctx, &[*frame]);
            conn.flush();
            if self.clear {
                xcb::clear_area(&conn, true, win, frame.x(), frame.y(), 2000, 2000);
            }
            thread::sleep(self.duration_per_frame);
        }
    }
}