From f5a82152394fde4d8f740f664ab7737b82861618 Mon Sep 17 00:00:00 2001 From: cashmere Date: Tue, 28 Jul 2026 19:41:16 +0200 Subject: feat: GPUI desktop port foundation - scene crate: full project/scene/element model, serde round-trip proven against the web SerializedProject shape - transfer crate: .ocp zip container, cross-compat with web fflate archives proven in both directions - storage crate: filesystem project store replacing IndexedDB, .ocp import/export - media crate: ffmpeg-next 8 decoder (frames, audio, thumbnails, waveform summaries) - playback crate: wall-clock anchored, frame-rounded playback clock - gpu crate: native texture readback; compositor renders headless offscreen on Vulkan (spike test) - flake devshell: rust toolchain, GPUI native deps, ffmpeg dev, bindgen clang args; GPUI hello-world builds - port plan in notes/gpui-port.md --- rust/crates/commands/src/project/mod.rs | 3 + .../src/project/update_project_settings.rs | 77 ++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 rust/crates/commands/src/project/mod.rs create mode 100644 rust/crates/commands/src/project/update_project_settings.rs (limited to 'rust/crates/commands/src/project') diff --git a/rust/crates/commands/src/project/mod.rs b/rust/crates/commands/src/project/mod.rs new file mode 100644 index 00000000..28e9c92c --- /dev/null +++ b/rust/crates/commands/src/project/mod.rs @@ -0,0 +1,3 @@ +pub mod update_project_settings; + +pub use update_project_settings::{ProjectSettingsPatch, UpdateProjectSettingsCommand}; diff --git a/rust/crates/commands/src/project/update_project_settings.rs b/rust/crates/commands/src/project/update_project_settings.rs new file mode 100644 index 00000000..a0f6e99c --- /dev/null +++ b/rust/crates/commands/src/project/update_project_settings.rs @@ -0,0 +1,77 @@ +use scene::{Background, CanvasSize, CanvasSizeMode, Project, ProjectSettings}; +use time::FrameRate; + +use crate::command::{Command, CommandError, CommandResult}; + +#[derive(Clone, Debug, Default, PartialEq)] +pub struct ProjectSettingsPatch { + pub fps: Option, + pub canvas_size: Option, + pub canvas_size_mode: Option>, + pub last_custom_canvas_size: Option>, + pub original_canvas_size: Option>, + pub background: Option, +} + +impl ProjectSettingsPatch { + pub fn apply_to(&self, settings: &mut ProjectSettings) { + if let Some(fps) = self.fps { + settings.fps = fps; + } + if let Some(canvas_size) = self.canvas_size { + settings.canvas_size = canvas_size; + } + if let Some(canvas_size_mode) = &self.canvas_size_mode { + settings.canvas_size_mode = *canvas_size_mode; + } + if let Some(last_custom_canvas_size) = &self.last_custom_canvas_size { + settings.last_custom_canvas_size = *last_custom_canvas_size; + } + if let Some(original_canvas_size) = &self.original_canvas_size { + settings.original_canvas_size = *original_canvas_size; + } + if let Some(background) = &self.background { + settings.background = background.clone(); + } + } +} + +pub struct UpdateProjectSettingsCommand { + updates: ProjectSettingsPatch, + saved_settings: Option, + saved_updated_at: Option>, +} + +impl UpdateProjectSettingsCommand { + pub fn new(updates: ProjectSettingsPatch) -> Self { + Self { + updates, + saved_settings: None, + saved_updated_at: None, + } + } +} + +impl Command for UpdateProjectSettingsCommand { + fn execute( + &mut self, + project: &mut Project, + ) -> Result, CommandError> { + self.saved_settings = Some(project.settings.clone()); + self.saved_updated_at = Some(project.metadata.updated_at); + + self.updates.apply_to(&mut project.settings); + project.metadata.updated_at = chrono::Utc::now(); + Ok(None) + } + + fn undo(&mut self, project: &mut Project) { + let (Some(saved_settings), Some(saved_updated_at)) = + (&self.saved_settings, self.saved_updated_at) + else { + return; + }; + project.settings = saved_settings.clone(); + project.metadata.updated_at = saved_updated_at; + } +} -- cgit v1.3.1