summaryrefslogtreecommitdiff
path: root/rust/crates/timeline/src/track_element_update.rs
blob: 98395ab0174e9c7184e458b304f597fe11597a39 (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
95
96
97
use scene::{Element, SceneTracks, Track};

pub fn find_track_in_scene_tracks<'a>(tracks: &'a SceneTracks, track_id: &str) -> Option<&'a Track> {
    if tracks.main.id() == track_id {
        return Some(&tracks.main);
    }

    tracks
        .overlay
        .iter()
        .chain(tracks.audio.iter())
        .find(|track| track.id() == track_id)
}

pub fn update_track_in_scene_tracks(
    tracks: &SceneTracks,
    track_id: &str,
    update: impl Fn(&Track) -> Track,
) -> SceneTracks {
    if tracks.main.id() == track_id {
        return SceneTracks {
            main: update(&tracks.main),
            ..tracks.clone()
        };
    }

    if tracks.overlay.iter().any(|track| track.id() == track_id) {
        return SceneTracks {
            overlay: tracks
                .overlay
                .iter()
                .map(|track| {
                    if track.id() == track_id {
                        update(track)
                    } else {
                        track.clone()
                    }
                })
                .collect(),
            ..tracks.clone()
        };
    }

    if tracks.audio.iter().any(|track| track.id() == track_id) {
        return SceneTracks {
            audio: tracks
                .audio
                .iter()
                .map(|track| {
                    if track.id() == track_id {
                        update(track)
                    } else {
                        track.clone()
                    }
                })
                .collect(),
            ..tracks.clone()
        };
    }

    tracks.clone()
}

fn with_replaced_elements(track: &Track, elements: Vec<Element>) -> Track {
    let mut next = track.clone();
    *next.elements_mut() = elements;
    next
}

pub fn update_element_in_scene_tracks(
    tracks: &SceneTracks,
    track_id: &str,
    element_id: &str,
    update: impl Fn(&Element) -> Element,
    element_predicate: Option<&dyn Fn(&Element) -> bool>,
) -> SceneTracks {
    let update_in_track = |track: &Track| {
        let elements = track
            .elements()
            .iter()
            .map(|element| {
                if element.base().id != element_id {
                    return element.clone();
                }
                if let Some(predicate) = element_predicate
                    && !predicate(element)
                {
                    return element.clone();
                }
                update(element)
            })
            .collect();
        with_replaced_elements(track, elements)
    };

    update_track_in_scene_tracks(tracks, track_id, update_in_track)
}