summaryrefslogtreecommitdiff
path: root/rust/crates/commands/src/timeline/element/split_elements.rs
blob: 98d292abcd2f29b4944d7a1887f3ce9b647707d3 (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
use std::cell::RefCell;
use std::rc::Rc;

use scene::{ElementRef, Project, SceneTracks};
use time::MediaTime;
pub use timeline::split::RetainSide;

use crate::command::{Command, CommandError, CommandResult};
use crate::project_ext::active_scene_mut;

pub struct SplitElementsCommand {
    elements: Vec<ElementRef>,
    split_time: MediaTime,
    retain_side: RetainSide,
    saved_state: Option<SceneTracks>,
    right_side: Rc<RefCell<Vec<ElementRef>>>,
}

impl SplitElementsCommand {
    pub fn new(elements: Vec<ElementRef>, split_time: MediaTime, retain_side: RetainSide) -> Self {
        Self {
            elements,
            split_time,
            retain_side,
            saved_state: None,
            right_side: Rc::new(RefCell::new(Vec::new())),
        }
    }

    pub fn right_side_handle(&self) -> Rc<RefCell<Vec<ElementRef>>> {
        Rc::clone(&self.right_side)
    }

    pub fn right_side_elements(&self) -> Vec<ElementRef> {
        self.right_side.borrow().clone()
    }
}

impl Command for SplitElementsCommand {
    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());

        let result = timeline::split::split_elements(
            &scene.tracks,
            &self.elements,
            self.split_time,
            self.retain_side,
        );
        scene.tracks = result.tracks;

        *self.right_side.borrow_mut() = result.right_side_elements;

        let right_side = self.right_side.borrow();
        if right_side.is_empty() {
            return Ok(None);
        }
        Ok(Some(CommandResult::element_selection(right_side.clone())))
    }

    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();
        }
    }
}