summaryrefslogtreecommitdiff
path: root/rust/crates/commands/src/scene
diff options
context:
space:
mode:
Diffstat (limited to 'rust/crates/commands/src/scene')
-rw-r--r--rust/crates/commands/src/scene/create_scene.rs46
-rw-r--r--rust/crates/commands/src/scene/delete_scene.rs61
-rw-r--r--rust/crates/commands/src/scene/mod.rs15
-rw-r--r--rust/crates/commands/src/scene/move_bookmark.rs50
-rw-r--r--rust/crates/commands/src/scene/remove_bookmark.rs54
-rw-r--r--rust/crates/commands/src/scene/rename_scene.rs58
-rw-r--r--rust/crates/commands/src/scene/toggle_bookmark.rs48
-rw-r--r--rust/crates/commands/src/scene/update_bookmark.rs49
8 files changed, 381 insertions, 0 deletions
diff --git a/rust/crates/commands/src/scene/create_scene.rs b/rust/crates/commands/src/scene/create_scene.rs
new file mode 100644
index 00000000..1f2de02b
--- /dev/null
+++ b/rust/crates/commands/src/scene/create_scene.rs
@@ -0,0 +1,46 @@
+use scene::{Project, Scene};
+
+use crate::command::{Command, CommandError, CommandResult};
+
+pub struct CreateSceneCommand {
+ name: String,
+ is_main: bool,
+ saved_scenes: Option<Vec<Scene>>,
+ created_scene_id: Option<String>,
+}
+
+impl CreateSceneCommand {
+ pub fn new(name: impl Into<String>, is_main: bool) -> Self {
+ Self {
+ name: name.into(),
+ is_main,
+ saved_scenes: None,
+ created_scene_id: None,
+ }
+ }
+
+ pub fn scene_id(&self) -> Option<&str> {
+ self.created_scene_id.as_deref()
+ }
+}
+
+impl Command for CreateSceneCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ self.saved_scenes = Some(project.scenes.clone());
+
+ let created = timeline::scenes::build_default_scene(&self.name, self.is_main);
+ self.created_scene_id = Some(created.id.clone());
+ project.scenes.push(created);
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let Some(saved) = &self.saved_scenes else {
+ return;
+ };
+ project.scenes = saved.clone();
+ }
+}
diff --git a/rust/crates/commands/src/scene/delete_scene.rs b/rust/crates/commands/src/scene/delete_scene.rs
new file mode 100644
index 00000000..61763dfd
--- /dev/null
+++ b/rust/crates/commands/src/scene/delete_scene.rs
@@ -0,0 +1,61 @@
+use scene::{Project, Scene};
+
+use crate::command::{Command, CommandError, CommandResult};
+
+pub struct DeleteSceneCommand {
+ scene_id: String,
+ saved_scenes: Option<Vec<Scene>>,
+ saved_current_scene_id: Option<String>,
+}
+
+impl DeleteSceneCommand {
+ pub fn new(scene_id: impl Into<String>) -> Self {
+ Self {
+ scene_id: scene_id.into(),
+ saved_scenes: None,
+ saved_current_scene_id: None,
+ }
+ }
+}
+
+impl Command for DeleteSceneCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ let Some(deleted) = project.scenes.iter().find(|scene| scene.id == self.scene_id)
+ else {
+ return Ok(None);
+ };
+ if deleted.is_main {
+ return Ok(None);
+ }
+
+ self.saved_scenes = Some(project.scenes.clone());
+ self.saved_current_scene_id = Some(project.current_scene_id.clone());
+
+ project.scenes.retain(|scene| scene.id != self.scene_id);
+
+ if project.current_scene_id == self.scene_id {
+ let fallback_id = project
+ .scenes
+ .iter()
+ .find(|scene| scene.is_main)
+ .map(|scene| scene.id.clone());
+ if let Some(fallback_id) = fallback_id {
+ project.current_scene_id = fallback_id;
+ }
+ }
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let (Some(saved_scenes), Some(saved_current_scene_id)) =
+ (&self.saved_scenes, &self.saved_current_scene_id)
+ else {
+ return;
+ };
+ project.scenes = saved_scenes.clone();
+ project.current_scene_id = saved_current_scene_id.clone();
+ }
+}
diff --git a/rust/crates/commands/src/scene/mod.rs b/rust/crates/commands/src/scene/mod.rs
new file mode 100644
index 00000000..10d687c1
--- /dev/null
+++ b/rust/crates/commands/src/scene/mod.rs
@@ -0,0 +1,15 @@
+pub mod create_scene;
+pub mod delete_scene;
+pub mod move_bookmark;
+pub mod remove_bookmark;
+pub mod rename_scene;
+pub mod toggle_bookmark;
+pub mod update_bookmark;
+
+pub use create_scene::CreateSceneCommand;
+pub use delete_scene::DeleteSceneCommand;
+pub use move_bookmark::MoveBookmarkCommand;
+pub use remove_bookmark::RemoveBookmarkCommand;
+pub use rename_scene::RenameSceneCommand;
+pub use toggle_bookmark::ToggleBookmarkCommand;
+pub use update_bookmark::UpdateBookmarkCommand;
diff --git a/rust/crates/commands/src/scene/move_bookmark.rs b/rust/crates/commands/src/scene/move_bookmark.rs
new file mode 100644
index 00000000..dddef11f
--- /dev/null
+++ b/rust/crates/commands/src/scene/move_bookmark.rs
@@ -0,0 +1,50 @@
+use scene::Project;
+use time::MediaTime;
+
+use crate::bookmarks::{get_frame_time, move_bookmark_in_array};
+use crate::command::{Command, CommandError, CommandResult};
+use crate::project_ext::active_scene_mut;
+
+pub struct MoveBookmarkCommand {
+ from_time: MediaTime,
+ to_time: MediaTime,
+ saved_bookmarks: Option<Vec<scene::Bookmark>>,
+}
+
+impl MoveBookmarkCommand {
+ pub fn new(from_time: MediaTime, to_time: MediaTime) -> Self {
+ Self {
+ from_time,
+ to_time,
+ saved_bookmarks: None,
+ }
+ }
+}
+
+impl Command for MoveBookmarkCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ let fps = project.settings.fps;
+ let Some(scene) = active_scene_mut(project) else {
+ return Ok(None);
+ };
+
+ self.saved_bookmarks = Some(scene.bookmarks.clone());
+ let from_frame_time = get_frame_time(self.from_time, fps);
+ let to_frame_time = get_frame_time(self.to_time, fps);
+ scene.bookmarks =
+ move_bookmark_in_array(&scene.bookmarks, from_frame_time, to_frame_time);
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let Some(saved) = &self.saved_bookmarks else {
+ return;
+ };
+ if let Some(scene) = active_scene_mut(project) {
+ scene.bookmarks = saved.clone();
+ }
+ }
+}
diff --git a/rust/crates/commands/src/scene/remove_bookmark.rs b/rust/crates/commands/src/scene/remove_bookmark.rs
new file mode 100644
index 00000000..f8fe0c5a
--- /dev/null
+++ b/rust/crates/commands/src/scene/remove_bookmark.rs
@@ -0,0 +1,54 @@
+use scene::Project;
+use time::MediaTime;
+
+use crate::bookmarks::{get_frame_time, remove_bookmark_from_array};
+use crate::command::{Command, CommandError, CommandResult};
+use crate::project_ext::active_scene_mut;
+
+pub struct RemoveBookmarkCommand {
+ time: MediaTime,
+ frame_time: MediaTime,
+ saved_bookmarks: Option<Vec<scene::Bookmark>>,
+}
+
+impl RemoveBookmarkCommand {
+ pub fn new(time: MediaTime) -> Self {
+ Self {
+ time,
+ frame_time: MediaTime::ZERO,
+ saved_bookmarks: None,
+ }
+ }
+}
+
+impl Command for RemoveBookmarkCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ let fps = project.settings.fps;
+ let Some(scene) = active_scene_mut(project) else {
+ return Ok(None);
+ };
+
+ self.saved_bookmarks = Some(scene.bookmarks.clone());
+ self.frame_time = get_frame_time(self.time, fps);
+
+ let updated = remove_bookmark_from_array(&scene.bookmarks, self.frame_time);
+ if updated.len() == scene.bookmarks.len() {
+ return Ok(None);
+ }
+
+ scene.bookmarks = updated;
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let Some(saved) = &self.saved_bookmarks else {
+ return;
+ };
+ if let Some(scene) = active_scene_mut(project) {
+ scene.bookmarks = saved.clone();
+ }
+ }
+}
diff --git a/rust/crates/commands/src/scene/rename_scene.rs b/rust/crates/commands/src/scene/rename_scene.rs
new file mode 100644
index 00000000..4876fb9b
--- /dev/null
+++ b/rust/crates/commands/src/scene/rename_scene.rs
@@ -0,0 +1,58 @@
+use scene::Project;
+
+use crate::command::{Command, CommandError, CommandResult};
+
+pub struct RenameSceneCommand {
+ scene_id: String,
+ new_name: String,
+ saved_name: Option<String>,
+ saved_updated_at: Option<chrono::DateTime<chrono::Utc>>,
+}
+
+impl RenameSceneCommand {
+ pub fn new(scene_id: impl Into<String>, new_name: impl Into<String>) -> Self {
+ Self {
+ scene_id: scene_id.into(),
+ new_name: new_name.into(),
+ saved_name: None,
+ saved_updated_at: None,
+ }
+ }
+}
+
+impl Command for RenameSceneCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ let Some(scene) = project
+ .scenes
+ .iter_mut()
+ .find(|scene| scene.id == self.scene_id)
+ else {
+ return Ok(None);
+ };
+
+ self.saved_name = Some(scene.name.clone());
+ self.saved_updated_at = Some(scene.updated_at);
+ scene.name = self.new_name.clone();
+ scene.updated_at = chrono::Utc::now();
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let (Some(saved_name), Some(saved_updated_at)) =
+ (&self.saved_name, self.saved_updated_at)
+ else {
+ return;
+ };
+ if let Some(scene) = project
+ .scenes
+ .iter_mut()
+ .find(|scene| scene.id == self.scene_id)
+ {
+ scene.name = saved_name.clone();
+ scene.updated_at = saved_updated_at;
+ }
+ }
+}
diff --git a/rust/crates/commands/src/scene/toggle_bookmark.rs b/rust/crates/commands/src/scene/toggle_bookmark.rs
new file mode 100644
index 00000000..054e1c78
--- /dev/null
+++ b/rust/crates/commands/src/scene/toggle_bookmark.rs
@@ -0,0 +1,48 @@
+use scene::Project;
+
+use crate::bookmarks::{get_frame_time, toggle_bookmark_in_array};
+use crate::command::{Command, CommandError, CommandResult};
+use crate::project_ext::active_scene_mut;
+use time::MediaTime;
+
+pub struct ToggleBookmarkCommand {
+ time: MediaTime,
+ frame_time: MediaTime,
+ saved_bookmarks: Option<Vec<scene::Bookmark>>,
+}
+
+impl ToggleBookmarkCommand {
+ pub fn new(time: MediaTime) -> Self {
+ Self {
+ time,
+ frame_time: MediaTime::ZERO,
+ saved_bookmarks: None,
+ }
+ }
+}
+
+impl Command for ToggleBookmarkCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ let fps = project.settings.fps;
+ let Some(scene) = active_scene_mut(project) else {
+ return Ok(None);
+ };
+
+ self.saved_bookmarks = Some(scene.bookmarks.clone());
+ self.frame_time = get_frame_time(self.time, fps);
+ scene.bookmarks = toggle_bookmark_in_array(&scene.bookmarks, self.frame_time);
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let Some(saved) = &self.saved_bookmarks else {
+ return;
+ };
+ if let Some(scene) = active_scene_mut(project) {
+ scene.bookmarks = saved.clone();
+ }
+ }
+}
diff --git a/rust/crates/commands/src/scene/update_bookmark.rs b/rust/crates/commands/src/scene/update_bookmark.rs
new file mode 100644
index 00000000..f2c9b94e
--- /dev/null
+++ b/rust/crates/commands/src/scene/update_bookmark.rs
@@ -0,0 +1,49 @@
+use scene::Project;
+use time::MediaTime;
+
+use crate::bookmarks::{BookmarkPatch, get_frame_time, update_bookmark_in_array};
+use crate::command::{Command, CommandError, CommandResult};
+use crate::project_ext::active_scene_mut;
+
+pub struct UpdateBookmarkCommand {
+ time: MediaTime,
+ updates: BookmarkPatch,
+ saved_bookmarks: Option<Vec<scene::Bookmark>>,
+}
+
+impl UpdateBookmarkCommand {
+ pub fn new(time: MediaTime, updates: BookmarkPatch) -> Self {
+ Self {
+ time,
+ updates,
+ saved_bookmarks: None,
+ }
+ }
+}
+
+impl Command for UpdateBookmarkCommand {
+ fn execute(
+ &mut self,
+ project: &mut Project,
+ ) -> Result<Option<CommandResult>, CommandError> {
+ let fps = project.settings.fps;
+ let Some(scene) = active_scene_mut(project) else {
+ return Ok(None);
+ };
+
+ self.saved_bookmarks = Some(scene.bookmarks.clone());
+ let frame_time = get_frame_time(self.time, fps);
+ scene.bookmarks =
+ update_bookmark_in_array(&scene.bookmarks, frame_time, &self.updates);
+ Ok(None)
+ }
+
+ fn undo(&mut self, project: &mut Project) {
+ let Some(saved) = &self.saved_bookmarks else {
+ return;
+ };
+ if let Some(scene) = active_scene_mut(project) {
+ scene.bookmarks = saved.clone();
+ }
+ }
+}