Drag & drop feature:
authorTon Roosendaal <ton@blender.org>
Fri, 17 Dec 2010 19:05:34 +0000 (19:05 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 17 Dec 2010 19:05:34 +0000 (19:05 +0000)
You now can drop a .blend inside blender window to open it.

Implementation notes:
- Added call to extract icon type for files. Code re-used from
  space_file
- External files that get dropped set icon types too.
  Drop box polls can check for this.
- Also enabled setting op-context for drop operators, this was
  needed to prevent filewindow to open.

source/blender/editors/include/ED_fileselect.h
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filelist.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_dragdrop.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_window.c

index 5001323..a7d763c 100644 (file)
@@ -93,5 +93,7 @@ void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile);
 
 void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile);
 
+int ED_file_extension_icon(char *relname);
+
 #endif /* ED_FILES_H */
 
index bcfddd0..0c49779 100644 (file)
@@ -64,6 +64,7 @@
 #include "RNA_define.h"
 
 #include "UI_interface.h"
+#include "UI_resources.h"
 
 #include "wm_window.h"
 
@@ -3014,6 +3015,7 @@ void SCENE_OT_delete(wmOperatorType *ot)
 
 /* ****************  Assigning operatortypes to global list, adding handlers **************** */
 
+
 /* called in spacetypes.c */
 void ED_operatortypes_screen(void)
 {
@@ -3087,9 +3089,27 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
        
 }
 
+static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+{
+       if(drag->type==WM_DRAG_PATH) {
+               if(drag->icon==ICON_FILE_BLEND)
+                  return 1;
+       }
+       return 0;
+}
+
+static void open_file_drop_copy(wmDrag *drag, wmDropBox *drop)
+{
+       /* copy drag path to properties */
+       RNA_string_set(drop->ptr, "filepath", drag->path);
+       drop->opcontext= WM_OP_EXEC_DEFAULT;
+}
+
+
 /* called in spacetypes.c */
 void ED_keymap_screen(wmKeyConfig *keyconf)
 {
+       ListBase *lb;
        wmKeyMap *keymap;
        //wmKeyMapItem *kmi;
        
@@ -3203,6 +3223,10 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", DOWNARROWKEY, KM_PRESS, KM_ALT, 0);
 #endif
 
+       /* dropbox for entire window */
+       lb= WM_dropboxmap_find("Window", 0, 0);
+       WM_dropbox_add(lb, "WM_OT_open_mainfile", open_file_drop_poll, open_file_drop_copy);
+       
        keymap_modal_set(keyconf);
 }
 
index 476a887..ce4b5bd 100644 (file)
 
 #include "PIL_time.h"
 
-
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "UI_resources.h"
+
 #include "filelist.h"
 
 /* max length of library group name within filesel */
@@ -360,7 +361,7 @@ void filelist_filter(FileList* filelist)
        }
 }
 
-void filelist_init_icons()
+void filelist_init_icons(void)
 {
        short x, y, k;
        ImBuf *bbuf;
@@ -383,7 +384,7 @@ void filelist_init_icons()
        }
 }
 
-void filelist_free_icons()
+void filelist_free_icons(void)
 {
        int i;
        for (i=0; i < SPECIAL_IMG_MAX; ++i) {
@@ -720,6 +721,87 @@ void filelist_setfilter_types(struct FileList* filelist, const char *filter_glob
        BLI_strncpy(filelist->filter_glob, filter_glob, sizeof(filelist->filter_glob));
 }
 
+static int file_extension_type(char *relname)
+{
+       if(BLO_has_bfile_extension(relname)) {
+               return BLENDERFILE;
+       } else if(BLI_testextensie(relname, ".py")) {
+               return PYSCRIPTFILE;
+       } else if(BLI_testextensie(relname, ".txt")
+                         || BLI_testextensie(relname, ".glsl")
+                         || BLI_testextensie(relname, ".data")) {
+               return TEXTFILE;
+       } else if( BLI_testextensie(relname, ".ttf")
+                         || BLI_testextensie(relname, ".ttc")
+                         || BLI_testextensie(relname, ".pfb")
+                         || BLI_testextensie(relname, ".otf")
+                         || BLI_testextensie(relname, ".otc")) {
+               return FTFONTFILE;                      
+       } else if(BLI_testextensie(relname, ".btx")) {
+               return BTXFILE;
+       } else if(BLI_testextensie(relname, ".dae")) {
+               return COLLADAFILE;
+       } else if(BLI_testextensie_array(relname, imb_ext_image)
+                         || (G.have_quicktime && BLI_testextensie_array(relname, imb_ext_image_qt))) {
+               return IMAGEFILE;                       
+       } else if(BLI_testextensie_array(relname, imb_ext_movie)) {
+               return MOVIEFILE;                       
+       } else if(BLI_testextensie_array(relname, imb_ext_audio)) {
+               return SOUNDFILE;
+       } 
+       return 0;
+}
+
+int ED_file_extension_icon(char *relname)
+{
+       int type= file_extension_type(relname);
+       
+       if (type == BLENDERFILE)
+               return ICON_FILE_BLEND;
+       else if (type ==  IMAGEFILE)
+               return ICON_FILE_IMAGE;
+       else if (type ==  MOVIEFILE)
+               return ICON_FILE_MOVIE;
+       else if (type ==  PYSCRIPTFILE)
+               return ICON_FILE_SCRIPT;
+       else if (type ==  PYSCRIPTFILE)
+               return ICON_FILE_SCRIPT;
+       else if (type ==  SOUNDFILE) 
+               return ICON_FILE_SOUND;
+       else if (type ==  FTFONTFILE) 
+               return ICON_FILE_FONT;
+       else if (type ==  BTXFILE) 
+               return ICON_FILE_BLANK;
+       else if (type ==  COLLADAFILE) 
+               return ICON_FILE_BLANK;
+       
+       return ICON_FILE_BLANK;
+}
+
+void filelist_setfiletypes(struct FileList* filelist)
+{
+       struct direntry *file;
+       int num;
+       
+       file= filelist->filelist;
+       
+       for(num=0; num<filelist->numfiles; num++, file++) {
+               file->type= file->s.st_mode;    /* restore the mess below */ 
+               
+               /* Don't check extensions for directories */ 
+               if (file->type & S_IFDIR) {
+                       continue;
+               }
+               file->flags = file_extension_type(file->relname);
+               
+               if(filelist->filter_glob
+                  && BLI_testextensie_glob(file->relname, filelist->filter_glob)) {
+                       file->flags= OPERATORFILE;
+               }
+               
+       }
+}
+
 static void filelist_read_dir(struct FileList* filelist)
 {
        char wdir[FILE_MAX];
@@ -734,7 +816,7 @@ static void filelist_read_dir(struct FileList* filelist)
        filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist));
 
        if(!chdir(wdir)) {} /* fix warning about not checking return value */
-       filelist_setfiletypes(filelist, G.have_quicktime);
+       filelist_setfiletypes(filelist);
        filelist_filter(filelist);
 }
 
@@ -790,53 +872,6 @@ void filelist_parent(struct FileList* filelist)
        filelist_readdir(filelist);
 }
 
-void filelist_setfiletypes(struct FileList* filelist, short has_quicktime)
-{
-       struct direntry *file;
-       int num;
-
-       file= filelist->filelist;
-
-       for(num=0; num<filelist->numfiles; num++, file++) {
-               file->flags= 0;
-               file->type= file->s.st_mode;    /* restore the mess below */ 
-
-                       /* Don't check extensions for directories */ 
-               if (file->type & S_IFDIR) {
-                       continue;
-               }
-
-               if(BLO_has_bfile_extension(file->relname)) {
-                       file->flags |= BLENDERFILE;
-               } else if(BLI_testextensie(file->relname, ".py")) {
-                               file->flags |= PYSCRIPTFILE;
-               } else if(BLI_testextensie(file->relname, ".txt")
-                                       || BLI_testextensie(file->relname, ".glsl")
-                                       || BLI_testextensie(file->relname, ".data")) {
-                               file->flags |= TEXTFILE;
-               } else if( BLI_testextensie(file->relname, ".ttf")
-                                       || BLI_testextensie(file->relname, ".ttc")
-                                       || BLI_testextensie(file->relname, ".pfb")
-                                       || BLI_testextensie(file->relname, ".otf")
-                                       || BLI_testextensie(file->relname, ".otc")) {
-                               file->flags |= FTFONTFILE;                      
-               } else if(BLI_testextensie(file->relname, ".btx")) {
-                               file->flags |= BTXFILE;
-               } else if(BLI_testextensie(file->relname, ".dae")) {
-                       file->flags |= COLLADAFILE;
-               } else if(BLI_testextensie_array(file->relname, imb_ext_image)
-                                       || (has_quicktime && BLI_testextensie_array(file->relname, imb_ext_image_qt))) {
-                               file->flags |= IMAGEFILE;                       
-               } else if(BLI_testextensie_array(file->relname, imb_ext_movie)) {
-                       file->flags |= MOVIEFILE;                       
-               } else if(BLI_testextensie_array(file->relname, imb_ext_audio)) {
-                       file->flags |= SOUNDFILE;
-               } else if(filelist->filter_glob
-                                       && BLI_testextensie_glob(file->relname, filelist->filter_glob)) {
-                       file->flags |= OPERATORFILE;
-               }
-       }
-}
 
 void filelist_swapselect(struct FileList* filelist)
 {
index eb1c46d..6ea9174 100644 (file)
@@ -69,7 +69,6 @@ void                          filelist_readdir(struct FileList* filelist);
 
 int                                    filelist_empty(struct FileList* filelist);
 void                           filelist_parent(struct FileList* filelist);
-void                           filelist_setfiletypes(struct FileList* filelist, short has_quicktime);
 
 
 int                                    filelist_islibrary (struct FileList* filelist, char* dir, char* group);
index ea06395..0ca8c5e 100644 (file)
@@ -504,7 +504,8 @@ typedef struct wmDropBox {
        
        /* if poll survives, operator is called */
        wmOperatorType *ot;                             /* not saved in file, so can be pointer */
-
+       short opcontext;                                /* default invoke */
+       
        struct IDProperty *properties;                  /* operator properties, assigned to ptr->data and can be written to a file */
        struct PointerRNA *ptr;                 /* rna pointer to access properties */
 
index 6cf2c7a..a19499b 100644 (file)
@@ -75,6 +75,7 @@ typedef struct wmDropBoxMap {
        
 } wmDropBoxMap;
 
+/* spaceid/regionid is zero for window drop maps */
 ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
 {
        wmDropBoxMap *dm;
@@ -103,6 +104,7 @@ wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext
        drop->poll= poll;
        drop->copy= copy;
        drop->ot= WM_operatortype_find(idname, 0);
+       drop->opcontext= WM_OP_INVOKE_DEFAULT;
        
        if(drop->ot==NULL) {
                MEM_freeN(drop);
index 0a1f303..9c8bd3f 100644 (file)
@@ -1468,8 +1468,14 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
                                                                if(drop->poll(C, drag, event)) {
                                                                        drop->copy(drag, drop);
                                                                        
-                                                                       wm_operator_invoke(C, drop->ot, event, drop->ptr, NULL, FALSE);
+                                                                       WM_operator_name_call(C, drop->ot->idname, drop->opcontext, drop->ptr);
+                                                                       //wm_operator_invoke(C, drop->ot, event, drop->ptr, NULL, FALSE);
                                                                        action |= WM_HANDLER_BREAK;
+                                                                       
+                                                                       /* prevent hanging on file read */
+                                                                       BLI_freelistN(event->customdata);
+                                                                       event->customdata= NULL;
+                                                                       event->custom= 0;
                                                                }
                                                        }
                                                }
index c962ee8..723286b 100644 (file)
@@ -60,6 +60,7 @@
 #include "wm_event_system.h"
 
 #include "ED_screen.h"
+#include "ED_fileselect.h"
 
 #include "PIL_time.h"
 
@@ -413,6 +414,11 @@ void wm_window_add_ghostwindows(bContext* C, wmWindowManager *wm)
                keymap= WM_keymap_find(wm->defaultconf, "Screen Editing", 0, 0);
                WM_event_add_keymap_handler(&win->modalhandlers, keymap);
                
+               /* add drop boxes */
+               {
+                       ListBase *lb= WM_dropboxmap_find("Window", 0, 0);
+                       WM_event_add_dropbox_handler(&win->handlers, lb);
+               }
                wm_window_title(wm, win);
        }
 }
@@ -820,15 +826,17 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                /* printf("Drop detected\n"); */
                                
                                /* add drag data to wm for paths: */
-                               /* need icon type, some dropboxes check for that... see filesel code for this */
                                
                                if(ddd->dataType == GHOST_kDragnDropTypeFilenames) {
                                        GHOST_TStringArray *stra= ddd->data;
-                                       int a;
+                                       int a, icon;
                                        
                                        for(a=0; a<stra->count; a++) {
                                                printf("drop file %s\n", stra->strings[a]);
-                                               WM_event_start_drag(C, 0, WM_DRAG_PATH, stra->strings[a], 0.0);
+                                               /* try to get icon type from extension */
+                                               icon= ED_file_extension_icon((char *)stra->strings[a]);
+                                               
+                                               WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0);
                                                /* void poin should point to string, it makes a copy */
                                                break; // only one drop element supported now 
                                        }