mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-26 02:57:34 -06:00
#678: dropped Photoshop files show the Import Photoshop File dialog
Problem: dropping a PSD/PSB file on the window imported it straight away. The drop handler always passed `importAs` (Settings > Import > Default Drag Import As) to `file.import`, and the Import Photoshop File form only opens when `importAs` is missing, so the dialog that File > Import > File... shows never appeared for drops. Fix: a drop that includes a Photoshop file leaves `importAs` out, so the form asks (other drops keep passing the preference). For dropped files the form's Import Kind starts at Default Drag Import As; File > Import keeps starting at Composition. The engine already falls back to the preference for `drag` imports without `importAs`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9a7d3e7699
commit
f9db3afd34
@@ -215,16 +215,15 @@ pub fn open_form(app: &mut EffectcraftApp, id: &str, p: &Value) -> bool {
|
||||
let lt = layer.map(|l| l.layer_time(t)).unwrap_or(t);
|
||||
let base = p.clone();
|
||||
let (title, fields): (String, Vec<Field>) = match id {
|
||||
// Photoshop files: Import Kind (Footage / Composition / – Retain Layer Sizes).
|
||||
"file.import" if !has(p, &["importAs"]) && is_layered(p) => (
|
||||
"Import Photoshop File".into(),
|
||||
vec![Field::choice(
|
||||
"importAs",
|
||||
"Import Kind",
|
||||
&[("Footage", json!("footage")), ("Composition", json!("composition")), ("Composition - Retain Layer Sizes", json!("compositionLayerSizes"))],
|
||||
1,
|
||||
)],
|
||||
),
|
||||
// Photoshop files: Import Kind (Footage / Composition / – Retain Layer Sizes). Dropped
|
||||
// files start at Settings ▸ Import ▸ Default Drag Import As.
|
||||
"file.import" if !has(p, &["importAs"]) && is_layered(p) => {
|
||||
let kinds =
|
||||
[("Footage", json!("footage")), ("Composition", json!("composition")), ("Composition - Retain Layer Sizes", json!("compositionLayerSizes"))];
|
||||
let drag = p.get("drag").and_then(Value::as_bool).unwrap_or(false);
|
||||
let sel = if drag { kinds.iter().position(|(_, v)| v.as_str() == Some(s.prefs.drag_import_as())).unwrap_or(0) } else { 1 };
|
||||
("Import Photoshop File".into(), vec![Field::choice("importAs", "Import Kind", &kinds, sel)])
|
||||
}
|
||||
// PDF / Illustrator files: Import Kind and the page.
|
||||
"file.import" if !has(p, &["importAs", "page"]) && is_pdf(p) => (
|
||||
"Import PDF / Illustrator File".into(),
|
||||
|
||||
@@ -91,14 +91,19 @@ pub fn dropped_files(app: &mut EffectcraftApp, ui: &egui::Ui, bounds: Rect) {
|
||||
// Dropped files import as stills and folders' numbered stills as sequences; Alt-drag
|
||||
// imports a folder's files one by one (After Effects).
|
||||
let alt = ctx.input(|i| i.modifiers.alt);
|
||||
// A dropped Photoshop file asks how to import it (the Import Photoshop File dialog, its
|
||||
// Import Kind starting at Default Drag Import As), as File ▸ Import ▸ File… does (#678).
|
||||
let layered = rest.iter().any(|p| p.rsplit('.').next().is_some_and(|e| matches!(e.to_ascii_lowercase().as_str(), "psd" | "psb")));
|
||||
let mut params = json!({
|
||||
"paths": rest,
|
||||
"drag": true,
|
||||
"importAs": app.session.prefs.drag_import_as(),
|
||||
"addToComp": at.is_some(),
|
||||
"position": at,
|
||||
"background": true
|
||||
});
|
||||
if !layered {
|
||||
params["importAs"] = json!(app.session.prefs.drag_import_as());
|
||||
}
|
||||
if alt {
|
||||
params["sequence"] = json!(false);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use effectcraft_ui_egui::dock::PanelKind;
|
||||
use effectcraft_ui_egui::panels::viewer::{comp_to_screen, last_fit};
|
||||
use egui::{Event, Modifiers, Pos2, Rect, pos2, vec2};
|
||||
use egui_kittest::Harness;
|
||||
use egui_kittest::kittest::Queryable;
|
||||
use serde_json::json;
|
||||
|
||||
/// Comp "Main" (4 s at 30 fps, current time 1 s) with solids Top, Middle and Bottom, and comp
|
||||
@@ -379,6 +380,35 @@ fn dropped_file_on_viewer_imports_and_adds_layer_at_pointer() {
|
||||
assert!((p[0] - 80.0).abs() <= tol && (p[1] - 45.0).abs() <= tol, "{p:?}");
|
||||
}
|
||||
|
||||
/// #678: a dropped Photoshop file asks how to import it, as File ▸ Import ▸ File… does; the
|
||||
/// Import Kind starts at Settings ▸ Import ▸ Default Drag Import As, and OK imports the drop.
|
||||
#[test]
|
||||
fn dropped_photoshop_file_shows_the_import_photoshop_file_dialog() {
|
||||
let (mut h, _) = harness();
|
||||
h.state_mut().session.importer = Some(Arc::new(Gated { started: AtomicUsize::new(0), allow: Arc::new(AtomicUsize::new(usize::MAX)) }));
|
||||
h.state_mut().session.prefs.import.drag_import_as = "compLayerSizes".into();
|
||||
h.event(Event::PointerMoved(rect(&h, "panel.Project").center()));
|
||||
h.step();
|
||||
h.input_mut().dropped_files.push(Arc::new(Dropped(std::env::temp_dir().join("Layers.PSD"))));
|
||||
h.run_steps(2);
|
||||
assert_eq!(h.state().dialog, Some(effectcraft_ui_egui::Dialog::Form), "the drop asks first");
|
||||
h.run_steps(2);
|
||||
assert!(h.query_by_label("Import Photoshop File").is_some());
|
||||
assert!(h.query_by_value("Composition - Retain Layer Sizes").is_some(), "Import Kind starts at Default Drag Import As");
|
||||
assert!(!h.state().session.project.items.values().any(|i| i.name == "Layers.PSD"), "nothing imported before OK");
|
||||
click_id(&mut h, "form.cancel");
|
||||
assert_eq!(h.state().dialog, None);
|
||||
|
||||
// With Default Drag Import As at Footage, OK imports the file as one item.
|
||||
h.state_mut().session.prefs.import.drag_import_as = "footage".into();
|
||||
h.input_mut().dropped_files.push(Arc::new(Dropped(std::env::temp_dir().join("Layers.PSD"))));
|
||||
h.run_steps(4);
|
||||
assert_eq!(h.state().dialog, Some(effectcraft_ui_egui::Dialog::Form));
|
||||
assert!(h.query_by_value("Footage").is_some());
|
||||
click_id(&mut h, "form.ok");
|
||||
step_until(&mut h, |h| h.state().session.project.items.values().any(|i| i.name == "Layers.PSD"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_unsupported_drop_reports_the_error_and_keeps_valid_files() {
|
||||
let (mut h, _) = harness();
|
||||
|
||||
Reference in New Issue
Block a user