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
|
use scene::{Project, SceneTracks};
use timeline::update_pipeline::{ElementPatch, ElementUpdateContext, apply_element_update};
use crate::command::{Command, CommandError, CommandResult};
use crate::project_ext::active_scene_mut;
use crate::tracks::find_track_mut;
#[derive(Clone, Debug)]
pub struct ElementUpdate {
pub track_id: String,
pub element_id: String,
pub patch: ElementPatch,
}
pub struct UpdateElementsCommand {
updates: Vec<ElementUpdate>,
saved_state: Option<SceneTracks>,
}
impl UpdateElementsCommand {
pub fn new(updates: Vec<ElementUpdate>) -> Self {
Self {
updates,
saved_state: None,
}
}
}
impl Command for UpdateElementsCommand {
fn execute(
&mut self,
project: &mut Project,
) -> Result<Option<CommandResult>, CommandError> {
let Some(scene) = active_scene_mut(project) else {
return Ok(None);
};
self.saved_state = Some(scene.tracks.clone());
for update in &self.updates {
let context_tracks = scene.tracks.clone();
let context = ElementUpdateContext {
tracks: &context_tracks,
track_id: &update.track_id,
};
let Some(track) = find_track_mut(&mut scene.tracks, &update.track_id) else {
continue;
};
let Some(element) = track
.elements_mut()
.iter_mut()
.find(|element| element.base().id == update.element_id)
else {
continue;
};
*element = apply_element_update(element, &update.patch, &context);
}
Ok(None)
}
fn undo(&mut self, project: &mut Project) {
let Some(saved) = &self.saved_state else {
return;
};
if let Some(scene) = active_scene_mut(project) {
scene.tracks = saved.clone();
}
}
}
|