diff options
Diffstat (limited to 'source/blender/src/editimasel.c')
-rw-r--r-- | source/blender/src/editimasel.c | 1297 |
1 files changed, 983 insertions, 314 deletions
diff --git a/source/blender/src/editimasel.c b/source/blender/src/editimasel.c index f3f9aa31d07..bb56eb37288 100644 --- a/source/blender/src/editimasel.c +++ b/source/blender/src/editimasel.c @@ -43,411 +43,1080 @@ #include <sys/times.h> #endif -#include "PIL_time.h" +#include "MEM_guardedalloc.h" + +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_depsgraph.h" +#include "BKE_utildefines.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_storage_types.h" -#include "DNA_screen_types.h" +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include "DNA_armature_types.h" +#include "DNA_action_types.h" +#include "DNA_curve_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" +#include "DNA_texture_types.h" #include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "DNA_userdef_types.h" +#include "DNA_vfont_types.h" +#include "DNA_view3d_types.h" -#include "BKE_global.h" -#include "BIF_fsmenu.h" +#include "BIF_filelist.h" +#include "BIF_space.h" #include "BIF_screen.h" #include "BIF_interface.h" -#include "BIF_imasel.h" #include "BIF_mywindow.h" +#include "BIF_imasel.h" +#include "BIF_gl.h" +#include "BIF_fsmenu.h" +#include "BIF_editview.h" #include "BIF_toolbox.h" -#include "BSE_filesel.h" +#include "BLO_readfile.h" + +#include "BPI_script.h" + +#include "BSE_drawipo.h" #include "BSE_drawimasel.h" +#include "BSE_edit.h" -#include "BDR_editcurve.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" #include "blendef.h" #include "mydevice.h" -#define XIC 20 -#define YIC 21 +/* for events */ +#define NOTACTIVE 0 +#define ACTIVATE 1 +#define INACTIVATE 2 +/* for state of file */ +#define ACTIVE 2 -/* GLOBALS */ -extern char *fsmenu; +static void imasel_select_objects(SpaceImaSel *simasel); -void winqreadimaselspace(ScrArea *, void *, BWinEvent *); +static int imasel_has_func(SpaceImaSel *simasel) +{ + if(simasel->returnfunc || simasel->returnfunc_event || simasel->returnfunc_args) + return 1; + return 0; +} -void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt) +/* ugly, needs to be moved to platform specific files - elubie */ +#if defined WIN32 || defined __BeOS +static int fnmatch(const char *pattern, const char *string, int flags) +{ + return 0; +} +#else + #include <fnmatch.h> +#endif + +/**************** IMAGESELECT ******************************/ + +/* the complete call; pulldown menu, and three callback types */ +static void activate_imageselect_(int type, char *title, char *file, short *menup, char *pupmenu, + void (*func)(char *), + void (*func_event)(unsigned short), + void (*func_args)(char *, void *arg1, void *arg2), + void *arg1, void *arg2) { - unsigned short event= evt->event; - short val= evt->val; SpaceImaSel *simasel; + char group[24], name[FILE_MAX], temp[FILE_MAX]; - short mval[2]; - short area_event; - short queredraw = 0; - int ret = 0; - char name[256]; - char *selname; - static double prevtime=0; + if(curarea==0) return; + if(curarea->win==0) return; + newspace(curarea, SPACE_IMASEL); + scrarea_queue_winredraw(curarea); + + /* sometime double, when area already is SPACE_IMASEL with a different file name */ + if(curarea->headwin) addqueue(curarea->headwin, CHANGED, 1); + + name[2]= 0; + BLI_strncpy(name, file, sizeof(name)); - if(val==0) return; simasel= curarea->spacedata.first; + + simasel->returnfunc= func; + simasel->returnfunc_event= func_event; + simasel->returnfunc_args= func_args; + simasel->arg1= arg1; + simasel->arg2= arg2; - area_event = 0; - getmouseco_areawin(mval); - simasel->mx= mval[0]; - simasel->my= mval[1]; + simasel->type= type; + simasel->scrollpos = 0.0f; + + if(simasel->pupmenu) + MEM_freeN(simasel->pupmenu); + simasel->pupmenu= pupmenu; + simasel->menup= menup; + + /* sfile->act is used for databrowse: double names of library objects */ + simasel->active_file= -1; + + if(!simasel->files) { + simasel->files = BIF_filelist_new(); + } + + if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->flag |= FILE_STRINGCODE; + else simasel->flag &= ~FILE_STRINGCODE; + + if (U.uiflag & USER_HIDE_DOT) + simasel->flag |= FILE_HIDE_DOT; + + if(type==FILE_MAIN) { + char *groupname; + + BLI_strncpy(simasel->file, name+2, sizeof(simasel->file)); + + groupname = BLO_idcode_to_name( GS(name) ); + if (groupname) { + BLI_strncpy(simasel->dir, groupname, sizeof(simasel->dir) - 1); + strcat(simasel->dir, "/"); + } + + /* free all */ + if (simasel->files) { + BIF_filelist_freelib(simasel->files); + BIF_filelist_free(simasel->files); + BIF_filelist_setdir(simasel->files, simasel->dir); + BIF_filelist_settype(simasel->files, type); + } + } + else if(type==FILE_LOADLIB) { + BLI_strncpy(simasel->dir, name, sizeof(simasel->dir)); + BIF_filelist_setdir(simasel->files, simasel->dir); + if( BIF_filelist_islibrary(simasel->files, temp, group) ) { + /* force a reload of the library-filelist */ + BIF_filelist_free(simasel->files); + BIF_filelist_freelib(simasel->files); + BIF_filelist_setdir(simasel->files, simasel->dir); + BIF_filelist_settype(simasel->files, type); + } + else { + BLI_split_dirfile(file, temp, name); + BLI_strncpy(simasel->dir, temp, sizeof(simasel->dir)); + BIF_filelist_setdir(simasel->files, simasel->dir); + BIF_filelist_free(simasel->files); + BIF_filelist_freelib(simasel->files); + BIF_filelist_settype(simasel->files, type); + } + } + else { /* FILE_BLENDER */ + BLI_split_dirfile(file, temp, name); + BIF_filelist_free(simasel->files); + BIF_filelist_setdir(simasel->files, temp); + BIF_filelist_settype(simasel->files, type); + + BLI_cleanup_dir(G.sce, simasel->dir); + + /* free: filelist and libfiledata became incorrect */ + BIF_filelist_freelib(simasel->files); + } + BLI_strncpy(simasel->title, title, sizeof(simasel->title)); + /* filetoname= 1; */ /* TODO: elubie - check what this means */ +} + +void activate_imageselect(int type, char *title, char *file, void (*func)(char *)) +{ + activate_imageselect_(type, title, file, NULL, NULL, func, NULL, NULL, NULL, NULL); +} + +void activate_imageselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *)) +{ + activate_imageselect_(type, title, file, menup, pupmenu, func, NULL, NULL, NULL, NULL); +} + +void activate_imageselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2) +{ + activate_imageselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2); +} + +void activate_databrowse_imasel(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short)) +{ + ListBase *lb; + SpaceImaSel *simasel; + char str[32]; - if (simasel->desx > 0){ - if ( (mval[0] > simasel->dssx) && (mval[0] < simasel->dsex) && (mval[1] > simasel->dssy) && (mval[1] < simasel->dsey) ) area_event = IMS_INDIRSLI; - if ( (mval[0] > simasel->desx) && (mval[0] < simasel->deex) && (mval[1] > simasel->desy) && (mval[1] < simasel->deey) ) area_event = IMS_INDIR; + if(id==NULL) { + lb= wich_libbase(G.main, idcode); + id= lb->first; } - if (simasel->fesx > 0){ - if ( (mval[0] > simasel->fssx) && (mval[0] < simasel->fsex) && (mval[1] > simasel->fssy) && (mval[1] < simasel->fsey) ) area_event = IMS_INFILESLI; - if ( (mval[0] > simasel->fesx) && (mval[0] < simasel->feex) && (mval[1] > simasel->fesy) && (mval[1] < simasel->feey) ) area_event = IMS_INFILE; - } - if( event!=RETKEY && event!=PADENTER) - if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; - - switch(event) { - case AFTERPIBREAD: - get_pib_file(simasel); - queredraw = 1; - break; - - case AFTERIMASELIMA: - if (bitset(simasel->fase, IMS_DOTHE_INF)){ - get_file_info(simasel); - - if (!bitset(simasel->fase, IMS_KNOW_INF)){ - addafterqueue(curarea->win, AFTERIMASELIMA, 1); - - }else{ - simasel->subfase = 0; - simasel->imafase = 0; - simasel->fase |= IMS_DOTHE_IMA; - addafterqueue(curarea->win, AFTERIMASELGET, 1); + if(id) BLI_strncpy(str, id->name, sizeof(str)); + else return; + + activate_imageselect_(FILE_MAIN, "SELECT DATABLOCK", str, menup, NULL, NULL, func, NULL, NULL, NULL); + + simasel= curarea->spacedata.first; + simasel->retval= retval; + simasel->menup= menup; + + BIF_filelist_setipotype(simasel->files, fromcode); + BIF_filelist_hasfunc(simasel->files, imasel_has_func(simasel)); +} + + +static void set_active_file(SpaceImaSel *simasel, short x, short y) +{ + short tilex, tiley; + int active_tile; + int active_file; + int stridex; + struct direntry* file; + rcti viewrect = simasel->viewrect; + int fileoffset; + int rowoffset; + int rowleftover; + float scrollofs; + int numfiles; + int tilewidth = simasel->prv_w + TILE_BORDER_X*4; + int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize; + + numfiles = BIF_filelist_numfiles(simasel->files); + + if (simasel->numtilesx > 0) { + fileoffset = numfiles*(simasel->scrollpos / simasel->scrollarea) + 0.5; + rowoffset = (fileoffset / simasel->numtilesx)*simasel->numtilesx; + rowleftover = fileoffset % simasel->numtilesx; + scrollofs = (float)tileheight*(float)rowleftover/(float)simasel->numtilesx; + + stridex = (viewrect.xmax - viewrect.xmin) / (tilewidth); + tilex = ( (x-viewrect.xmin)) / (tilewidth); + tiley = (viewrect.ymax - viewrect.ymin + scrollofs - y) / (tileheight); + if (tilex >= simasel->numtilesx) tilex = simasel->numtilesx-1; + if (tiley >= simasel->numtilesy+1) tiley = simasel->numtilesy; + if (tilex < 0) tilex=0; + if (tiley < 0) tiley = 0; + active_tile = tilex + stridex*tiley; + active_file = rowoffset + active_tile; + + if (active_file >= 0 && active_file < BIF_filelist_numfiles(simasel->files) ) + { + simasel->active_file = active_file; + if (simasel->selstate & ACTIVATE) { + file = BIF_filelist_file(simasel->files, simasel->active_file); + file->flags |= ACTIVE; } + } else { + simasel->active_file = -1; + } + } else { + simasel->active_file = -1; + } +} + +static void set_active_bookmark(SpaceImaSel *simasel, short y) +{ + int nentries = fsmenu_get_nentries(); + short posy = simasel->bookmarkrect.ymax - U.fontsize*3/2 - TILE_BORDER_Y - y; + simasel->active_bookmark = ((float)posy / (U.fontsize*3.0f/2.0f)) + 0.5; + if (simasel->active_bookmark < 0 || simasel->active_bookmark > nentries) { + simasel->active_bookmark = -1; + } +} + +static void imasel_prevspace() +{ + SpaceImaSel *simasel; + + simasel= curarea->spacedata.first; + + /* cleanup */ + if(simasel->spacetype==SPACE_IMASEL) { + if(simasel->pupmenu) { + MEM_freeN(simasel->pupmenu); + simasel->pupmenu= NULL; + } + } + + if(simasel->next) { + + BLI_remlink(&curarea->spacedata, simasel); + BLI_addtail(&curarea->spacedata, simasel); + + simasel= curarea->spacedata.first; + + if (simasel->spacetype == SPACE_SCRIPT) { + SpaceScript *sc = (SpaceScript *)simasel; + if (sc->script) sc->script->flags &=~SCRIPT_FILESEL; } - break; - case AFTERIMASELGET: - if (bitset(simasel->fase, IMS_DOTHE_IMA)){ - get_next_image(simasel); - if (simasel->ima_redraw > 0){ - double newtime = PIL_check_seconds_timer(); - if ((newtime - prevtime) > 0.03) { - simasel->ima_redraw = 0; - queredraw = 1; - prevtime = newtime; + + newspace(curarea, simasel->spacetype); + } + else newspace(curarea, SPACE_INFO); +} + +static void free_imasel_spec(char *dir) +{ + /* all filesels with 'dir' are freed */ + bScreen *sc; + + sc= G.main->screen.first; + while(sc) { + ScrArea *sa= sc->areabase.first; + while(sa) { + SpaceLink *sl= sa->spacedata.first; + while(sl) { + if(sl->spacetype==SPACE_FILE) { + SpaceImaSel *simasel= (SpaceImaSel*) sl; + if (BLI_streq(simasel->dir, dir)) { + BIF_filelist_free(simasel->files); + } } - + sl= sl->next; } - if (!bitset(simasel->fase, IMS_KNOW_IMA)){ - addafterqueue(curarea->win, AFTERIMASELGET, 1); - }else{ - simasel->ima_redraw = 0; - simasel->subfase = 0; - simasel->imafase = 0; - addqueue(curarea->win, AFTERIMAWRITE, 1); - queredraw = 1; + sa= sa->next; + } + sc= sc->id.next; + } +} + +static void do_library_append(SpaceImaSel *simasel) +{ + Library *lib; + char dir[FILE_MAXDIR], group[32]; + + if ( BIF_filelist_islibrary(simasel->files, dir, group)==0 ) { + error("Not a library"); + } else if (!BIF_filelist_lib(simasel->files) ) { + error("Library not loaded"); + } else if (group[0]==0) { + error("Nothing indicated"); + } else if (BLI_streq(G.main->name, dir)) { + error("Cannot use current file as library"); + } else { + Object *ob; + int idcode = BIF_groupname_to_code(group); + + if((simasel->flag & FILE_LINK)==0) { + /* tag everything, all untagged data can be made local */ + ID *id; + ListBase *lbarray[MAX_LIBARRAY]; + int a; + + a= set_listbasepointers(G.main, lbarray); + while(a--) { + for(id= lbarray[a]->first; id; id= id->next) id->flag |= LIB_APPEND_TAG; } } - break; - case AFTERIMAWRITE: - if (bitset(simasel->fase, IMS_KNOW_IMA)){ - write_new_pib(simasel); - queredraw = 1; + + BIF_filelist_append_library(simasel->files, dir, simasel->file, simasel->flag, idcode); + + /* DISPLISTS? */ + ob= G.main->object.first; + while(ob) { + if(ob->id.lib) { + ob->recalc |= OB_RECALC; + } + ob= ob->id.next; } - break; - case RIGHTMOUSE: - if ((area_event == IMS_INFILE) && (simasel->hilite_ima)){ - select_ima_files(simasel); - queredraw = 1; + /* and now find the latest append lib file */ + lib= G.main->library.first; + while(lib) { + if (BLI_streq(dir, lib->filename)) break; + lib= lib->id.next; } - break; - case UI_BUT_EVENT: - /* bug: blender's interface kit also returns a '4'... what is it! */ + /* make local */ + if(lib) { + if((simasel->flag & FILE_LINK)==0) + all_local(lib,1); + } - switch(val) { - case 13: /* 'P' */ - imadir_parent(simasel); - queredraw = 1; - - case 1: /* dir entry */ - BLI_cleanup_dir(G.sce, simasel->dir); - clear_ima_dir(simasel); - queredraw = 1; - break; + DAG_scene_sort(G.scene); + + /* in sfile->dir is the whole lib name */ + BLI_strncpy(G.lib, simasel->dir, sizeof(G.lib) ); - case 3: /* fsmenu */ - selname= fsmenu_get_entry(simasel->fileselmenuitem-1); - if (selname) { - strcpy(simasel->dir, selname); - BLI_cleanup_dir(G.sce, simasel->dir); - clear_ima_dir(simasel); - queredraw = 1; - } - break; + } +} - case 5: - if (simasel->returnfunc) { - char name[256]; - strcpy(name, simasel->dir); - strcat(name, simasel->file); - filesel_prevspace(); - simasel->returnfunc(name); +/* NOTE: this is called for file read, after the execfunc no UI memory is valid! */ +static void imasel_execute(SpaceImaSel *simasel) +{ + struct direntry *file; + char name[FILE_MAX]; + int a; + int n; + + imasel_prevspace(); + + if(simasel->type==FILE_LOADLIB) { + if(simasel->flag & FILE_STRINGCODE) { + if (!G.relbase_valid) { + okee("You have to save the .blend file before using relative paths! Using absolute path instead."); + simasel->flag &= ~FILE_STRINGCODE; } - break; - case 6: - filesel_prevspace(); - break; - } - break; - - case LEFTMOUSE: - case MIDDLEMOUSE: + + do_library_append(simasel); + BIF_undo_push("Append from file"); + allqueue(REDRAWALL, 1); + } + else if(imasel_has_func(simasel)) { + fsmenu_insert_entry(simasel->dir, 1, 0); - /* No button pressed */ - switch (area_event){ - case IMS_INDIRSLI: - move_imadir_sli(simasel); - queredraw = 1; - break; - case IMS_INFILESLI: - move_imafile_sli(simasel); - queredraw = 1; - break; - case IMS_INDIR: - if (simasel->hilite > -1){ - change_imadir(simasel); - queredraw = 1; - } - break; - case IMS_INFILE: - if (simasel->hilite_ima){ - strcpy(simasel->fole, simasel->hilite_ima->file_name); - strcpy(simasel->file, simasel->hilite_ima->file_name); - - if (event == LEFTMOUSE) addqueue(curarea->win, IMALEFTMOUSE, 1); - - if ((event == MIDDLEMOUSE)&&(simasel->returnfunc)){ - strcpy(name, simasel->dir); - strcat(name, simasel->file); - - if(simasel->mode & IMS_STRINGCODE) BLI_makestringcode(G.sce, name); + if(simasel->type==FILE_MAIN) { /* DATABROWSE */ + if (simasel->menup) { /* with value pointing to ID block index */ + int notfound = 1; + + /* Need special handling since hiding .* datablocks means that + simasel->active_file is no longer the same as files->nr. + + Also, toggle HIDE_DOT on and off can make simasel->active_file not longer + correct (meaning it doesn't point to the correct item in the filelist. - filesel_prevspace(); - simasel->returnfunc(name); + simasel->file is always correct, so first with check if, for the item + corresponding to simasel->active_file, the name is the same. + + If it isn't (or if simasel->active_file is not good), go over filelist and take + the correct one. + + This means that selecting a datablock than hiding it makes it + unselectable. Not really a problem. + + - theeth + */ + + *simasel->menup= -1; + n = BIF_filelist_numfiles(simasel->files); + if(simasel->files) { + if( (simasel->active_file>=0) && (simasel->active_file < n) ) { + file = BIF_filelist_file(simasel->files, simasel->active_file); + if ( strcmp(file->relname, simasel->file)==0) { + notfound = 0; + *simasel->menup= file->nr; + } + } + if (notfound) { + for(a=0; a<n; a++) { + file = BIF_filelist_file(simasel->files, a); + if( strcmp(file->relname, simasel->file)==0) { + *simasel->menup= file->nr; + break; + } + } + } } - queredraw = 1; } - break; + if(simasel->returnfunc_event) + simasel->returnfunc_event(simasel->retval); + else if(simasel->returnfunc_args) + simasel->returnfunc_args(NULL, simasel->arg1, simasel->arg2); + } + else { + if(strncmp(simasel->title, "Save", 4)==0) free_imasel_spec(simasel->dir); + if(strncmp(simasel->title, "Export", 6)==0) free_imasel_spec(simasel->dir); + + BLI_strncpy(name, simasel->dir, sizeof(name)); + strcat(name, simasel->file); + + if(simasel->flag & FILE_STRINGCODE) { + if (!G.relbase_valid) { + /* skip save */ + if(strncmp(simasel->title, "Save", 4)) { + okee("You have to save the .blend file before using relative paths! Using absolute path instead."); + simasel->flag &= ~FILE_STRINGCODE; + } + } + else { + BLI_makestringcode(G.sce, name); + } + } + if(simasel->returnfunc) + simasel->returnfunc(name); + else if(simasel->returnfunc_args) + simasel->returnfunc_args(name, simasel->arg1, simasel->arg2); } - break; + } +} + +static void do_imasel_buttons(short event, SpaceImaSel *simasel) +{ + char butname[FILE_MAX]; - case MOUSEX: - case MOUSEY: - getmouseco_areawin(mval); /* local screen coordinates */ - calc_hilite(simasel); - if (simasel->mouse_move_redraw ){ - simasel->mouse_move_redraw = 0; - queredraw = 1; + if (event == B_FS_FILENAME) { + if (strchr(simasel->file, '*') || strchr(simasel->file, '?') || strchr(simasel->file, '[')) { + int i, match = FALSE; + struct direntry *file; + int n = BIF_filelist_numfiles(simasel->files); + for (i = 2; i < n; i++) { + file = BIF_filelist_file(simasel->files, i); + if (fnmatch(simasel->file, file->relname, 0) == 0) { + file->flags |= ACTIVE; + match = TRUE; + } + } + if (match) simasel->file[0] = '\0'; + if(simasel->type==FILE_MAIN) imasel_select_objects(simasel); + scrarea_queue_winredraw(curarea); } - break; + } + else if(event== B_FS_DIRNAME) { + /* reuse the butname variable */ + BLI_cleanup_dir(G.sce, simasel->dir); + + BLI_make_file_string(G.sce, butname, simasel->dir, ""); + BLI_strncpy(simasel->dir, butname, sizeof(simasel->dir)); + + /* strip the trailing slash if its a real dir */ + if (strlen(butname)!=1) + butname[strlen(butname)-1]=0; - case WHEELUPMOUSE: - case WHEELDOWNMOUSE: - switch(area_event){ - case IMS_INDIRSLI: - case IMS_INDIR: - if (simasel->dirsli){ - if (event == WHEELUPMOUSE) simasel->topdir -= U.wheellinescroll; - if (event == WHEELDOWNMOUSE) simasel->topdir += U.wheellinescroll; - queredraw = 1; + /* updating the directory in the filelist */ + BIF_filelist_setdir(simasel->files, simasel->dir); + + if(simasel->type & FILE_UNIX) { + if (!BLI_exists(butname)) { + if (okee("Makedir")) { + BLI_recurdir_fileops(butname); + if (!BLI_exists(butname)) { + BIF_filelist_parent(simasel->files); + BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80); + } + } else { + BIF_filelist_parent(simasel->files); + BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80); + } } - break; - case IMS_INFILESLI: - case IMS_INFILE: - if(simasel->imasli){ - if (event == WHEELUPMOUSE) simasel->image_slider -= 0.2 * simasel->slider_height; - if (event == WHEELDOWNMOUSE) simasel->image_slider += 0.2 * simasel->slider_height; - - if(simasel->image_slider < 0.0) simasel->image_slider = 0.0; - if(simasel->image_slider > 1.0) simasel->image_slider = 1.0; - queredraw = 1; - } - break; } - break; - - case PAGEUPKEY: - case PAGEDOWNKEY: - switch(area_event){ - case IMS_INDIRSLI: - case IMS_INDIR: - if (simasel->dirsli){ - if (event == PAGEUPKEY) simasel->topdir -= (simasel->dirsli_lines - 1); - if (event == PAGEDOWNKEY) simasel->topdir += (simasel->dirsli_lines - 1); - queredraw = 1; - } - break; - case IMS_INFILESLI: - case IMS_INFILE: - if(simasel->imasli){ - if (event == PAGEUPKEY) simasel->image_slider -= simasel->slider_height; - if (event == PAGEDOWNKEY) simasel->image_slider += simasel->slider_height; - - if(simasel->image_slider < 0.0) simasel->image_slider = 0.0; - if(simasel->image_slider > 1.0) simasel->image_slider = 1.0; - queredraw = 1; - } - break; + BIF_filelist_free(simasel->files); + simasel->file[0] = '\0'; + simasel->scrollpos = 0; + simasel->active_file = -1; + scrarea_queue_winredraw(curarea); + } + else if(event== B_FS_DIR_MENU) { + char *selected= fsmenu_get_entry(simasel->menu-1); + + /* which string */ + if (selected) { + BLI_strncpy(simasel->dir, selected, sizeof(simasel->dir)); + BLI_make_exist(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); + BIF_filelist_free(simasel->files); + BIF_filelist_setdir(simasel->files, simasel->dir); + simasel->file[0] = '\0'; + simasel->scrollpos = 0; + simasel->active_file = -1; + scrarea_queue_winredraw(curarea); } - break; + + simasel->active_file = -1; + + } + else if(event== B_FS_PARDIR) { + BIF_filelist_free(simasel->files); + BIF_filelist_parent(simasel->files); + BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80); + simasel->file[0] = '\0'; + simasel->active_file = -1; + simasel->scrollpos = 0; + scrarea_queue_winredraw(curarea); + } + else if(event== B_FS_LOAD) { + if(simasel->type) + imasel_execute(simasel); + } + else if(event== B_FS_CANCEL) + imasel_prevspace(); + else if(event== B_FS_LIBNAME) { + Library *lib= BLI_findlink(&G.main->library, simasel->menu); + if(lib) { + BLI_strncpy(simasel->dir, lib->filename, sizeof(simasel->dir)); + BLI_make_exist(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); + BIF_filelist_free(simasel->files); + BIF_filelist_setdir(simasel->files, simasel->dir); + simasel->file[0] = '\0'; + simasel->scrollpos = 0; + simasel->active_file = -1; + scrarea_queue_winredraw(curarea); + } + } else if(event== B_FS_BOOKMARK) { + char name[FILE_MAX]; + BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs"); + fsmenu_insert_entry(simasel->dir, 1, 1); + scrarea_queue_winredraw(curarea); + fsmenu_write_file(name); + } + +} + +static void imasel_home(ScrArea *sa, SpaceImaSel *simasel) +{ + simasel->v2d.cur.xmin= simasel->v2d.cur.ymin= 0.0f; + simasel->v2d.cur.xmax= sa->winx; + simasel->v2d.cur.ymax= sa->winy; - case HOMEKEY: - simasel->image_slider = 0.0; - queredraw = 1; - break; - - case ENDKEY: - simasel->image_slider = 1.0; - queredraw = 1; - break; + simasel->v2d.tot= simasel->v2d.cur; + test_view2d(G.v2d, sa->winx, sa->winy); + +} + +static struct direntry* get_hilited_entry(SpaceImaSel *simasel) +{ + struct direntry *file; + file = BIF_filelist_file(simasel->files, simasel->active_file); + return file; +} + +static void do_filescroll(SpaceImaSel *simasel) +{ + short mval[2], oldy, yo; + float scrollarea, scrollstep; + + /* for beauty */ + scrarea_do_windraw(curarea); + screen_swapbuffers(); + + getmouseco_areawin(mval); + oldy= yo= mval[1]; + + while(get_mbut()&L_MOUSE) { + getmouseco_areawin(mval); + + if(yo!=mval[1]) { + scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin); + scrollstep = yo - mval[1]; + simasel->scrollpos += scrollstep; - case AKEY: - if (G.qual == 0){ - ima_select_all(simasel); - queredraw = 1; - } - break; + if (simasel->scrollpos<0) + simasel->scrollpos=0; + if (simasel->scrollpos > scrollarea - simasel->scrollheight) + simasel->scrollpos = scrollarea - simasel->scrollheight; + scrarea_do_windraw(curarea); + screen_swapbuffers(); - case IKEY: - if ((G.qual == 0)&&(simasel->file)){ - sprintf(name, "$IMAGEEDITOR %s%s", simasel->dir, simasel->file); - system(name); - queredraw = 1; + yo= mval[1]; } + else BIF_wait_for_statechange(); + } - break; + /* for beauty */ + scrarea_do_windraw(curarea); + screen_swapbuffers(); - case PKEY: - if(G.qual & LR_SHIFTKEY) { - extern char bprogname[]; /* usiblender.c */ -#ifdef WIN32 - sprintf(name, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file); -#else - sprintf(name, "\"%s\" -a \"%s%s\"", bprogname, simasel->dir, simasel->file); -#endif - system(name); - } - if(G.qual & LR_CTRLKEY) { - if(bitset(simasel->fase, IMS_KNOW_IMA)) pibplay(simasel); +} + +/* ******************* DATA SELECT ********************* */ + +static void imasel_select_objects(SpaceImaSel *simasel) +{ + Object *ob; + Base *base; + Scene *sce; + struct direntry* file; + int a; + int totfile; + + /* only when F4 DATABROWSE */ + if(imasel_has_func(simasel)) return; + + totfile = BIF_filelist_numfiles(simasel->files); + + if( strcmp(simasel->dir, "Object/")==0 ) { + for(a=0; a<totfile; a++) { + file = BIF_filelist_file(simasel->files, a); + ob= (Object *)file->poin; + + if(ob) { + if(file->flags & ACTIVE) ob->flag |= SELECT; + else ob->flag &= ~SELECT; + } + } - if (G.qual == 0){ - imadir_parent(simasel); - BLI_cleanup_dir(G.sce, simasel->dir); - clear_ima_dir(simasel); - queredraw = 1; + base= FIRSTBASE; + while(base) { + base->flag= base->object->flag; + base= base->next; } - break; + countall(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + } + else if( strcmp(simasel->dir, "Scene/")==0 ) { - case RKEY: - case XKEY: - if (simasel->hilite_ima){ - strcpy(name, simasel->dir); - strcat(name, simasel->hilite_ima->file_name); - - if( okee("Delete %s", name) ) { - ret = BLI_delete(name, 0, 0); - if (ret) { - error("Command failed, see console"); - } else { - clear_ima_dir(simasel); - queredraw = 1; - } + for(a=0; a<totfile; a++) { + file = BIF_filelist_file(simasel->files, a); + sce= (Scene *)file->poin; + if(sce) { + if(file->flags & ACTIVE) sce->r.scemode |= R_BG_RENDER; + else sce->r.scemode &= ~R_BG_RENDER; } + } - break; + allqueue(REDRAWBUTSSCENE, 0); + } +} - case PADPLUSKEY: - case EQUALKEY: - BLI_newname(simasel->file, +1); - queredraw = 1; - break; - - case PADMINUS: - case MINUSKEY: - BLI_newname(simasel->file, -1); - queredraw = 1; - break; - - case BACKSLASHKEY: - case SLASHKEY: -#ifdef WIN32 - strcpy(simasel->dir, "\\"); -#else - strcpy(simasel->dir, "/"); -#endif - clear_ima_dir(simasel); - simasel->image_slider = 0.0; - queredraw = 1; - break; - - case PERIODKEY: - clear_ima_dir(simasel); - queredraw = 1; - break; +static void active_imasel_object(SpaceImaSel *simasel) +{ + Object *ob; + struct direntry* file; + + /* only when F4 DATABROWSE */ + if(imasel_has_func(simasel)) return; - case ESCKEY: - filesel_prevspace(); - break; - - case PADENTER: - case RETKEY: - if (simasel->returnfunc){ - strcpy(name, simasel->dir); - strcat(name, simasel->file); - filesel_prevspace(); - simasel->returnfunc(name); + if( strcmp(simasel->dir, "Object/")==0 ) { + int n = BIF_filelist_numfiles(simasel->files); + if(simasel->active_file >= 0 && simasel->active_file < n) { + file = BIF_filelist_file(simasel->files, simasel->active_file); + ob= (Object *)file->poin; + + if(ob) { + set_active_object(ob); + if(BASACT && BASACT->object==ob) { + BASACT->flag |= SELECT; + file->flags |= ACTIVE; + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWOOPS, 0); + scrarea_queue_winredraw(curarea); + } + } } - break; } +} + + + +void winqreadimaselspace(ScrArea *, void *, BWinEvent *); + + +void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt) +{ + unsigned short event= evt->event; + short val= evt->val; + SpaceImaSel *simasel; + char str[FILE_MAXDIR+FILE_MAXFILE+12]; + short mval[2]; + short do_draw = 0; + int numfiles; + struct direntry *file; + float scrollstep = 0; + float scrollarea; + + // if(val==0) return; + simasel= curarea->spacedata.first; + + if (!simasel->files) + return; + + if (BIF_filelist_empty(simasel->files)) + return; + + numfiles = BIF_filelist_numfiles(simasel->files); + + /* calc_scrollrcts(sa, &(simasel->v2d), sa->winx, sa->winy); */ + calc_imasel_rcts(simasel, sa->winx, sa->winy); + + /* prevent looping */ + if(simasel->selstate && !(get_mbut() & R_MOUSE)) simasel->selstate= 0; + + if(val) { + + if( event!=RETKEY && event!=PADENTER) + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + switch(event) { - if (queredraw) scrarea_queue_winredraw(curarea); + case UI_BUT_EVENT: + do_imasel_buttons(val, simasel); + break; + case RENDERPREVIEW: + do_draw= 1; + /* draw_imasel_previews(sa, simasel); */ + break; + case REDRAWIMASEL: + do_draw= 1; + break; + case WHEELDOWNMOUSE: + numfiles = BIF_filelist_numfiles(simasel->files); + scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin); + scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)*simasel->numtilesx; + simasel->scrollpos += scrollstep; + if (simasel->scrollpos > scrollarea - simasel->scrollheight) + simasel->scrollpos = scrollarea - simasel->scrollheight; + do_draw= 1; + break; + case WHEELUPMOUSE: + numfiles = BIF_filelist_numfiles(simasel->files); + scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin); + scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)*simasel->numtilesx; + simasel->scrollpos -= scrollstep; + if (simasel->scrollpos<0) + simasel->scrollpos=0; + do_draw= 1; + break; + case PAGEUPKEY: + numfiles = BIF_filelist_numfiles(simasel->files); + scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin); + scrollstep = ((scrollarea-simasel->scrollheight)/numfiles) + *simasel->numtilesx*simasel->numtilesy; + simasel->scrollpos -= scrollstep; + if (simasel->scrollpos<0) + simasel->scrollpos=0; + do_draw= 1; + break; + case PAGEDOWNKEY: + numfiles = BIF_filelist_numfiles(simasel->files); + scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin); + scrollstep = ((scrollarea-simasel->scrollheight)/numfiles) + * simasel->numtilesx*simasel->numtilesy; + simasel->scrollpos += scrollstep; + if (simasel->scrollpos > scrollarea - simasel->scrollheight) + simasel->scrollpos = scrollarea - simasel->scrollheight; + do_draw= 1; + break; + case HOMEKEY: + simasel->scrollpos=0; + imasel_home(sa, simasel); + do_draw= 1; + break; + case ENDKEY: + simasel->scrollpos = simasel->scrollarea; + do_draw= 1; + break; + + case ESCKEY: + BIF_filelist_free(simasel->files); + imasel_prevspace(); + break; + case PERIODKEY: + BIF_filelist_free(simasel->files); + simasel->active_file = -1; + do_draw = 1; + break; + case LEFTMOUSE: + case MIDDLEMOUSE: + getmouseco_areawin(mval); + if(mval[0]>simasel->v2d.vert.xmin && mval[0]<simasel->v2d.vert.xmax && mval[1]>simasel->v2d.vert.ymin && mval[1]<simasel->v2d.vert.ymax) { + do_filescroll(simasel); + } + else if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax + && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) { + set_active_file(simasel, mval[0], mval[1]); + if (simasel->active_file >= 0 && simasel->active_file < numfiles) { + file = BIF_filelist_file(simasel->files, simasel->active_file); + + if(file && S_ISDIR(file->type)) { + + BIF_filelist_appenddir(simasel->files, file->relname); + BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), FILE_MAXDIR); + strcat(simasel->dir,"/"); + simasel->file[0] = '\0'; + BLI_cleanup_dir(G.sce, simasel->dir); + BIF_filelist_free(simasel->files); + simasel->active_file = -1; + simasel->scrollpos = 0; + do_draw = 1; + + } + else if (file) + { + if (file->relname) { + if (simasel->img) { + IMB_freeImBuf(simasel->img); + simasel->img = NULL; + } + BLI_strncpy(simasel->file, file->relname, FILE_MAXFILE); + if(event==MIDDLEMOUSE && BIF_filelist_gettype(simasel->files)) + imasel_execute(simasel); + } + + } + if(BIF_filelist_gettype(simasel->files)==FILE_MAIN) { + active_imasel_object(simasel); + } + + do_draw = 1; + } + } + else { + simasel->active_file = -1; + if (simasel->flag & FILE_BOOKMARKS) { + if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) { + int nentries = fsmenu_get_nentries(); + + set_active_bookmark(simasel, mval[1]); + if (simasel->active_bookmark >= 0 && simasel->active_bookmark < nentries) { + char *selected= fsmenu_get_entry(simasel->active_bookmark); + /* which string */ + if (selected) { + BLI_strncpy(simasel->dir, selected, sizeof(simasel->dir)); + BLI_make_exist(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); + BIF_filelist_free(simasel->files); + BIF_filelist_setdir(simasel->files, simasel->dir); + simasel->file[0] = '\0'; + simasel->scrollpos = 0; + simasel->active_file = -1; + scrarea_queue_winredraw(curarea); + } + } + } else { + simasel->active_bookmark = -1; + } + do_draw= 1; + } + } + break; + case RIGHTMOUSE: + getmouseco_areawin(mval); + if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax + && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) { + set_active_file(simasel, mval[0], mval[1]); + if(simasel->active_file >=0 && simasel->active_file<numfiles) { + simasel->selstate = NOTACTIVE; + file = BIF_filelist_file(simasel->files, simasel->active_file); + if (file->flags & ACTIVE) { + file->flags &= ~ACTIVE; + simasel->selstate = INACTIVATE; + } + else { + file->flags |= ACTIVE; + simasel->selstate = ACTIVATE; + } + do_draw= 1; + } + } + break; + case MOUSEY: + case MOUSEX: + getmouseco_areawin(mval); + if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) { + set_active_file(simasel, mval[0], mval[1]); + if(simasel->active_file >=0 && simasel->active_file<numfiles) { + file = BIF_filelist_file(simasel->files, simasel->active_file); + if (simasel->selstate == INACTIVATE) { + file->flags &= ~ACTIVE; + } + else if (simasel->selstate == ACTIVATE) { + file->flags |= ACTIVE; + } + do_draw= 1; + } + } else { + simasel->active_file = -1; + if (simasel->flag & FILE_BOOKMARKS) { + if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) { + set_active_bookmark(simasel, mval[1]); + do_draw= 1; + } else { + simasel->active_bookmark = -1; + } + } + } + break; + case AKEY: + BIF_filelist_swapselect(simasel->files); + if(simasel->type==FILE_MAIN) imasel_select_objects(simasel); + do_draw= 1; + break; + case BKEY: + toggle_blockhandler(sa, IMASEL_HANDLER_IMAGE, UI_PNL_UNSTOW); + scrarea_queue_winredraw(sa); + break; + case PKEY: + if(G.qual & LR_SHIFTKEY) { + extern char bprogname[]; /* usiblender.c */ + + sprintf(str, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file); + system(str); + } + else + { + BIF_filelist_free(simasel->files); + BIF_filelist_parent(simasel->files); + BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80); + simasel->file[0] = '\0'; + simasel->active_file = -1; + simasel->scrollpos = 0; + } + do_draw = 1; + break; + case XKEY: + getmouseco_areawin(mval); + if (simasel->flag & FILE_BOOKMARKS) { + if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) { + int nentries = fsmenu_get_nentries(); + set_active_bookmark(simasel, mval[1]); + if (simasel->active_bookmark >= 0 && simasel->active_bookmark < nentries) { + fsmenu_remove_entry(simasel->active_bookmark); + simasel->active_bookmark = -1; + do_draw = 1; + } + } + } + break; + } + } + else if(event==RIGHTMOUSE) { + simasel->selstate = NOTACTIVE; + if(simasel->type==FILE_MAIN) imasel_select_objects(simasel); + } + else if(event==LEFTMOUSE) { + if(simasel->type==FILE_MAIN) { + getmouseco_areawin(mval); + set_active_file(simasel, mval[0], mval[1]); + } + } + /* XXX, stupid patch, curarea can become undone + * because of file loading... fixme zr + */ + if(do_draw && curarea) scrarea_queue_winredraw(curarea); } +/* copied from filesel.c */ void clever_numbuts_imasel() { SpaceImaSel *simasel; - static char orgname[FILE_MAXDIR+FILE_MAXFILE+12]; - static char filename[FILE_MAXDIR+FILE_MAXFILE+12]; - static char newname[FILE_MAXDIR+FILE_MAXFILE+12]; + char orgname[FILE_MAXDIR+FILE_MAXFILE+12]; + char filename[FILE_MAXDIR+FILE_MAXFILE+12]; + char newname[FILE_MAXDIR+FILE_MAXFILE+12]; + struct direntry *file; int len; simasel= curarea->spacedata.first; + + if(BIF_filelist_gettype(simasel->files)==FILE_MAIN) return; + len = 110; + file = get_hilited_entry(simasel); + + if (file != NULL && !(S_ISDIR(file->type))){ + + BLI_make_file_string(G.sce, orgname, simasel->dir, file->relname); + BLI_strncpy(filename, file->relname, sizeof(filename)); - if (simasel->hilite_ima){ - BLI_make_file_string(G.sce, orgname, simasel->dir, simasel->hilite_ima->file_name); - strcpy(filename, simasel->hilite_ima->file_name); + add_numbut(0, TEX, "", 0, len, filename, "Rename File"); - add_numbut(0, TEX, "", 0, len, filename, "Rename Image"); - if( do_clever_numbuts("Rename Image", 1, REDRAW) ) { + if( do_clever_numbuts("Rename File", 1, REDRAW) ) { BLI_make_file_string(G.sce, newname, simasel->dir, filename); if( strcmp(orgname, newname) != 0 ) { BLI_rename(orgname, newname); - - clear_ima_dir(simasel); + BIF_filelist_free(simasel->files); } } |