image viewer: Allow dropping images on pane (#21803)

Bennet Bo Fenner created

Partially addresses #21484


https://github.com/user-attachments/assets/777da5de-15c3-4af3-a597-1835c0155326

Release Notes:

- Support opening images by dropping them onto a pane

Change summary

crates/image_viewer/src/image_viewer.rs | 11 ++++++-----
crates/project/src/image_store.rs       | 12 ++++++++++--
2 files changed, 16 insertions(+), 7 deletions(-)

Detailed changes

crates/image_viewer/src/image_viewer.rs 🔗

@@ -108,10 +108,11 @@ impl Item for ImageView {
             params.text_color()
         };
 
-        let title = project_path
-            .path
-            .file_name()
-            .unwrap_or_else(|| project_path.path.as_os_str())
+        let title = self
+            .image_item
+            .read(cx)
+            .file
+            .file_name(cx)
             .to_string_lossy()
             .to_string();
         Label::new(title)
@@ -160,7 +161,7 @@ impl Item for ImageView {
 }
 
 fn breadcrumbs_text_for_image(project: &Project, image: &ImageItem, cx: &AppContext) -> String {
-    let path = image.path();
+    let path = image.file.file_name(cx);
     if project.visible_worktrees(cx).count() <= 1 {
         return path.to_string_lossy().to_string();
     }

crates/project/src/image_store.rs 🔗

@@ -123,9 +123,17 @@ impl ProjectItem for ImageItem {
         let path = path.clone();
         let project = project.clone();
 
-        let ext = path
-            .path
+        let worktree_abs_path = project
+            .read(cx)
+            .worktree_for_id(path.worktree_id, cx)?
+            .read(cx)
+            .abs_path();
+
+        // Resolve the file extension from either the worktree path (if it's a single file)
+        // or from the project path's subpath.
+        let ext = worktree_abs_path
             .extension()
+            .or_else(|| path.path.extension())
             .and_then(OsStr::to_str)
             .map(str::to_lowercase)
             .unwrap_or_default();