Browse Source

improve drag and drop support

- any file type
- multiple files
- if session, only first is loaded
Alexander Rose 3 years ago
parent
commit
e4f630dbef
2 changed files with 26 additions and 9 deletions
  1. 4 1
      CHANGELOG.md
  2. 22 8
      src/mol-plugin-ui/plugin.tsx

+ 4 - 1
CHANGELOG.md

@@ -7,8 +7,11 @@ Note that since we don't clearly distinguish between a public and private interf
 ## [Unreleased]
 
 - Add ``bumpiness`` (per-object and per-group), ``bumpFrequency`` & ``bumpAmplitude`` (per-object) render parameters (#299)
-- Change ``label`` representation defaults: Use text border instead of rectangle background.
+- Change ``label`` representation defaults: Use text border instead of rectangle background
 - Add outline color option to renderer
+- Fix false positives in Model.isFromPdbArchive
+- Add drag and drop support for loading any file, including multiple at once
+    - If there are session files (.molx or .molj) among the dropped files, only the first session will be loaded
 
 ## [v3.0.0-dev.3] - 2021-12-4
 

+ 22 - 8
src/mol-plugin-ui/plugin.tsx

@@ -18,6 +18,8 @@ import { Toasts } from './toast';
 import { Viewport, ViewportControls } from './viewport';
 import { PluginCommands } from '../mol-plugin/commands';
 import { PluginUIContext } from './context';
+import { OpenFiles } from '../mol-plugin-state/actions/file';
+import { Asset } from '../mol-util/assets';
 
 export class Plugin extends React.Component<{ plugin: PluginUIContext }, {}> {
     region(kind: 'left' | 'right' | 'bottom' | 'main', element: JSX.Element) {
@@ -102,22 +104,34 @@ class Layout extends PluginUIComponent {
     onDrop = (ev: React.DragEvent<HTMLDivElement>) => {
         ev.preventDefault();
 
-        let file: File | undefined | null;
+        const files: File[] = [];
         if (ev.dataTransfer.items) {
             // Use DataTransferItemList interface to access the file(s)
             for (let i = 0; i < ev.dataTransfer.items.length; i++) {
                 if (ev.dataTransfer.items[i].kind !== 'file') continue;
-                file = ev.dataTransfer.items[i].getAsFile();
-                break;
+                const file = ev.dataTransfer.items[i].getAsFile();
+                if (file) files.push(file);
             }
         } else {
-            file = ev.dataTransfer.files[0];
+            for (let i = 0; i < ev.dataTransfer.files.length; i++) {
+                const file = ev.dataTransfer.files[0];
+                if (file) files.push(file);
+            }
         }
-        if (!file) return;
 
-        const fn = file?.name.toLowerCase() || '';
-        if (fn.endsWith('molx') || fn.endsWith('molj')) {
-            PluginCommands.State.Snapshots.OpenFile(this.plugin, { file });
+        const sessions = files.filter(f => {
+            const fn = f.name.toLowerCase();
+            return fn.endsWith('.molx') || fn.endsWith('.molj');
+        });
+
+        if (sessions.length > 0) {
+            PluginCommands.State.Snapshots.OpenFile(this.plugin, { file: sessions[0] });
+        } else {
+            this.plugin.runTask(this.plugin.state.data.applyAction(OpenFiles, {
+                files: files.map(f => Asset.File(f)),
+                format: { name: 'auto', params: {} },
+                visuals: true
+            }));
         }
     }