mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-24 10:10:05 -06:00
Merge pull request #833 from vbasky/fix/785-explorer-timeline-drop
OS drops on an empty Timeline create a sequence
This commit is contained in:
@@ -666,6 +666,26 @@ fn empty_state(app: &mut FilmcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
||||
{
|
||||
let _ = app.session.execute("file.newSequence", json!({"fromItem": item.0}));
|
||||
}
|
||||
// OS files dropped on an empty Timeline: import already happened; create a sequence from the first item
|
||||
if let Some((items, p)) = app.pending_timeline_drop.clone()
|
||||
&& rect.contains(p)
|
||||
&& let Some((first, rest)) = items.split_first()
|
||||
{
|
||||
app.pending_timeline_drop = None;
|
||||
if let Err(e) = app.session.execute("file.newSequence", json!({"fromItem": first.0})) {
|
||||
app.ui.status = e.to_string();
|
||||
} else {
|
||||
let mut t = app.session.project.item(*first).map(|i| i.duration()).unwrap_or(Tick::ZERO);
|
||||
for item in rest {
|
||||
let params = json!({"item": item.0, "time": t.0, "insert": false});
|
||||
if let Err(e) = app.session.execute("timeline.place", params) {
|
||||
app.ui.status = e.to_string();
|
||||
} else {
|
||||
t = Tick(t.0.saturating_add(app.session.project.item(*item).map(|i| i.duration().0.max(0)).unwrap_or(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The through-edit mark: two small triangles pointing at the cut, centred on the track, with a
|
||||
|
||||
@@ -143,6 +143,43 @@ fn tone_dropped_on_a_video_row_goes_to_the_audio_track_without_error() {
|
||||
assert_eq!(clip_counts(&h), (0, 1), "status: {}", h.state().ui.status);
|
||||
}
|
||||
|
||||
/// Empty project: no sequence yet. Dropping on the empty Timeline must import *and* make a sequence.
|
||||
fn empty_harness() -> Harness<'static, FilmcraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1600.0, 980.0)).build_eframe(move |_cc| FilmcraftApp::new(Session::default()));
|
||||
for _ in 0..4 {
|
||||
step(&mut h);
|
||||
}
|
||||
h
|
||||
}
|
||||
|
||||
fn drop_on_empty_timeline(h: &mut Harness<'static, FilmcraftApp>, path: &Path) {
|
||||
let panel = control_rect(h, "panel.Timeline");
|
||||
pointer_to(h, panel.center());
|
||||
h.input_mut().dropped_files.push(std::sync::Arc::new(OsFile(path.to_path_buf())));
|
||||
step(h);
|
||||
h.input_mut().dropped_files.clear();
|
||||
step(h);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn still_dropped_on_empty_timeline_creates_a_sequence() {
|
||||
let mut h = empty_harness();
|
||||
assert!(h.state().session.active_sequence().is_none());
|
||||
drop_on_empty_timeline(&mut h, &still("drop_still_empty_timeline.png"));
|
||||
assert_eq!(h.state().session.project.items.len(), 2, "still plus the new sequence");
|
||||
assert!(h.state().session.active_sequence().is_some(), "status: {}", h.state().ui.status);
|
||||
assert_eq!(clip_counts(&h), (1, 0), "status: {}", h.state().ui.status);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_drop_import_off_empty_timeline_does_not_create_a_sequence() {
|
||||
let mut h = empty_harness();
|
||||
h.state_mut().session.prefs.timeline.drop_import_to_timeline = false;
|
||||
drop_on_empty_timeline(&mut h, &still("drop_still_empty_pref_off.png"));
|
||||
assert_eq!(h.state().session.project.items.len(), 1, "imported to the bin only");
|
||||
assert!(h.state().session.active_sequence().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn with_drop_import_off_the_file_is_only_imported() {
|
||||
let mut h = harness();
|
||||
|
||||
Reference in New Issue
Block a user