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/timeline/src/placement/mod.rs | 104 ++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 rust/crates/timeline/src/placement/mod.rs (limited to 'rust/crates/timeline/src/placement/mod.rs') diff --git a/rust/crates/timeline/src/placement/mod.rs b/rust/crates/timeline/src/placement/mod.rs new file mode 100644 index 00000000..8ad5710e --- /dev/null +++ b/rust/crates/timeline/src/placement/mod.rs @@ -0,0 +1,104 @@ +use scene::{Element, SceneTracks, Track}; +use time::MediaTime; + +use crate::types::{ElementType, TrackType}; + +pub mod apply; +pub mod compatibility; +pub mod insert_index; +pub mod main_track; +pub mod overlap; +pub mod resolve; +pub mod track_factory; + +pub use apply::{PlacementApplied, apply_placement}; +pub use compatibility::{ + can_element_go_on_track, get_track_type_for_element_type, validate_element_track_compatibility, +}; +pub use insert_index::{ + get_default_insert_index_for_track, get_highest_insert_index_for_track, + resolve_preferred_new_track_placement, +}; +pub use main_track::{MAIN_TRACK_NAME, enforce_main_track_start, get_earliest_main_track_element}; +pub use overlap::can_place_time_spans_on_track; +pub use resolve::resolve_track_placement; +pub use track_factory::build_empty_track; + +#[derive(Clone, Debug, PartialEq)] +pub struct PlacementTimeSpan { + pub start_time: MediaTime, + pub duration: MediaTime, + pub exclude_element_id: Option, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum PlacementSubject { + ElementType(ElementType), + TrackType(TrackType), +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum InsertDirection { + Above, + Below, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum VerticalDragDirection { + Up, + Down, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum NewTrackPosition { + Highest, + Default, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum PlacementStrategy { + Explicit { + track_id: String, + }, + FirstAvailable, + PreferIndex { + track_index: usize, + hover_direction: InsertDirection, + vertical_drag_direction: Option, + create_new_track_only: bool, + }, + AboveSource { + source_track_index: usize, + }, + AlwaysNew { + position: NewTrackPosition, + }, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum PlacementResult { + ExistingTrack { + track_id: String, + track_index: usize, + track_type: TrackType, + adjusted_start_time: Option, + }, + NewTrack { + track_type: TrackType, + insert_index: usize, + insert_position: Option, + }, +} + +pub fn ordered_tracks(tracks: &SceneTracks) -> Vec<&Track> { + tracks + .overlay + .iter() + .chain(std::iter::once(&tracks.main)) + .chain(tracks.audio.iter()) + .collect() +} + +pub fn track_elements(track: &Track) -> &[Element] { + track.elements() +} -- cgit v1.3.1