fix(app): footage drop auto-creates the media's track

A fresh sequence has no tracks and a drop rejected with 'display track
does not exist'; wrong-kind drops also rejected. Dropping footage now
creates a matching track first (the Premiere convention), so the
drag-to-timeline path works on empty timelines too.
This commit is contained in:
2026-08-16 19:46:05 +08:00
parent 2958464bd7
commit b2d353fe99
2 changed files with 35 additions and 8 deletions
+32 -8
View File
@@ -2951,17 +2951,41 @@ impl AppEngine for RealEngine {
match self.tracks.iter().position(|t| t.kind == footage_kind) {
Some(index) => index,
None => {
println!(
"[real engine] drop footage: no {:?} track for {:?} media \"{}\"",
footage_kind, track_kind, filename
);
// SAFETY: `footage_node` is a box from
// `oakengine_project_footage_at`.
unsafe { oakengine_node_free(footage_node) };
return;
// No track of the media's kind: create one (the NLE
// convention — Premiere auto-creates on drop).
self.add_track(footage_kind, cx);
match self.tracks.iter().position(|t| t.kind == footage_kind) {
Some(index) => index,
None => {
println!(
"[real engine] drop footage: could not add a {:?} track for \"{}\"",
footage_kind, filename
);
// SAFETY: `footage_node` is a box from
// `oakengine_project_footage_at`.
unsafe { oakengine_node_free(footage_node) };
return;
}
}
}
}
}
} else if self.tracks.is_empty() {
// An empty timeline (a fresh sequence has no tracks yet): create
// the media's track and drop onto it.
self.add_track(footage_kind, cx);
match self.tracks.iter().position(|t| t.kind == footage_kind) {
Some(index) => index,
None => {
println!(
"[real engine] drop footage: could not add a {:?} track",
footage_kind
);
// SAFETY: `footage_node` is a box from `oakengine_project_footage_at`.
unsafe { oakengine_node_free(footage_node) };
return;
}
}
} else {
println!("[real engine] drop footage: display track {track_index} does not exist");
// SAFETY: `footage_node` is a box from `oakengine_project_footage_at`.
+3
View File
@@ -424,6 +424,9 @@ impl<E: AppEngine> Render for TimelinePanel<E> {
},
))
.on_drop(cx.listener(|this, drag: &FootageDrag, _window, cx| {
if std::env::var("OAK_DEBUG_DRAG").is_ok() {
eprintln!("[drag] timeline drop: {drag:?}");
}
this.finish_footage_drop(drag, cx);
}))
.child(self.timeline.clone()),