summaryrefslogtreecommitdiff
path: root/rust/crates/commands/src/bookmarks.rs
blob: 79a73015a4db1dfbcb361e9f30566ddfb5b9ee5e (plain) (blame)
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use scene::Bookmark;
use time::{FrameRate, MediaTime};

#[derive(Clone, Debug, Default, PartialEq)]
pub struct BookmarkPatch {
    pub note: Option<Option<String>>,
    pub color: Option<Option<String>>,
    pub duration: Option<Option<MediaTime>>,
}

pub fn find_bookmark_index(bookmarks: &[Bookmark], frame_time: MediaTime) -> Option<usize> {
    bookmarks.iter().position(|bookmark| bookmark.time == frame_time)
}

pub fn is_bookmark_at_time(bookmarks: &[Bookmark], frame_time: MediaTime) -> bool {
    find_bookmark_index(bookmarks, frame_time).is_some()
}

pub fn toggle_bookmark_in_array(
    bookmarks: &[Bookmark],
    frame_time: MediaTime,
) -> Vec<Bookmark> {
    if let Some(index) = find_bookmark_index(bookmarks, frame_time) {
        return bookmarks
            .iter()
            .enumerate()
            .filter(|(bookmark_index, _)| *bookmark_index != index)
            .map(|(_, bookmark)| bookmark.clone())
            .collect();
    }

    let mut next = bookmarks.to_vec();
    next.push(Bookmark {
        time: frame_time,
        note: None,
        color: None,
        duration: None,
    });
    next.sort_by_key(|bookmark| bookmark.time);
    next
}

pub fn remove_bookmark_from_array(
    bookmarks: &[Bookmark],
    frame_time: MediaTime,
) -> Vec<Bookmark> {
    bookmarks
        .iter()
        .filter(|bookmark| bookmark.time != frame_time)
        .cloned()
        .collect()
}

pub fn update_bookmark_in_array(
    bookmarks: &[Bookmark],
    frame_time: MediaTime,
    updates: &BookmarkPatch,
) -> Vec<Bookmark> {
    let Some(index) = find_bookmark_index(bookmarks, frame_time) else {
        return bookmarks.to_vec();
    };

    let mut next = bookmarks.to_vec();
    let bookmark = &mut next[index];
    if let Some(note) = &updates.note {
        bookmark.note = note.clone();
    }
    if let Some(color) = &updates.color {
        bookmark.color = color.clone();
    }
    if let Some(duration) = &updates.duration {
        bookmark.duration = *duration;
    }
    next
}

pub fn move_bookmark_in_array(
    bookmarks: &[Bookmark],
    from_time: MediaTime,
    to_time: MediaTime,
) -> Vec<Bookmark> {
    let Some(index) = find_bookmark_index(bookmarks, from_time) else {
        return bookmarks.to_vec();
    };

    let mut next = bookmarks.to_vec();
    next[index].time = to_time;
    next.sort_by_key(|bookmark| bookmark.time);
    next
}

pub fn get_frame_time(time: MediaTime, fps: FrameRate) -> MediaTime {
    time.round_to_frame(fps).unwrap_or(time)
}