2.5 filebrowser
authorAndrea Weikert <elubie@gmx.net>
Sun, 18 Jan 2009 18:24:11 +0000 (18:24 +0000)
committerAndrea Weikert <elubie@gmx.net>
Sun, 18 Jan 2009 18:24:11 +0000 (18:24 +0000)
* slightly improved drawing code
* temporarily added creation of thumbnails within thread in the background until thread job manager is available in WM.
* fixed missing icons in thumbnail view

source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/file_intern.h
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filelist.h
source/blender/editors/space_file/space_file.c
source/blender/makesdna/DNA_space_types.h

index c45993d..93c9236 100644 (file)
@@ -200,14 +200,14 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
 }
 
 
-static void draw_tile(short sx, short sy, short width, short height, int colorid)
+static void draw_tile(short sx, short sy, short width, short height, int colorid, int shade)
 {
        /* TODO: BIF_ThemeColor seems to need this to show the color, not sure why? - elubie */
        glEnable(GL_BLEND);
        glColor4ub(0, 0, 0, 100);
        glDisable(GL_BLEND);
        
-       UI_ThemeColor4(colorid);
+       UI_ThemeColorShade(colorid, shade);
        uiSetRoundBox(15);      
        glRecti(sx, sy - height, sx + width, sy);
 
@@ -264,14 +264,14 @@ static void file_draw_string(short sx, short sy, char* string, short width, shor
 static int file_view_rows(SpaceFile* sfile, View2D *v2d)
 {
        int height= (v2d->cur.ymax - v2d->cur.ymin - 2*sfile->tile_border_y);
-       return height / (sfile->tile_h + sfile->tile_border_y);
+       return height / (sfile->tile_h + 2*sfile->tile_border_y);
 }
 
 /* returns max number of columns in view */
 static int file_view_columns(SpaceFile* sfile, View2D *v2d)
 {
        int width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->tile_border_x);
-       return width / (sfile->tile_w + sfile->tile_border_x);
+       return width / (sfile->tile_w + 2*sfile->tile_border_x);
 }
 
 void file_calc_previews(const bContext *C, ARegion *ar)
@@ -285,16 +285,16 @@ void file_calc_previews(const bContext *C, ARegion *ar)
        if (params->display) {
                sfile->prv_w = 96;
                sfile->prv_h = 96;
-               sfile->tile_border_x = 8;
-               sfile->tile_border_y = 8;
+               sfile->tile_border_x = 4;
+               sfile->tile_border_y = 4;
                sfile->prv_border_x = 4;
                sfile->prv_border_y = 4;
                sfile->tile_w = sfile->prv_w + 2*sfile->prv_border_x;
-               sfile->tile_h = sfile->prv_h + 2*sfile->prv_border_y + U.fontsize*3/2;
+               sfile->tile_h = sfile->prv_h + 4*sfile->prv_border_y + U.fontsize*3/2;
                width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->tile_border_x);
                columns= file_view_columns(sfile, v2d);
                rows= filelist_numfiles(sfile->files)/columns + 1; // XXX dirty, modulo is zero
-               height= rows*(sfile->tile_h+sfile->tile_border_y) + sfile->tile_border_y*2;
+               height= rows*(sfile->tile_h+2*sfile->tile_border_y) + sfile->tile_border_y*2;
        } else {
                sfile->prv_w = 0;
                sfile->prv_h = 0;
@@ -307,7 +307,7 @@ void file_calc_previews(const bContext *C, ARegion *ar)
                height= v2d->cur.ymax - v2d->cur.ymin;
                rows = file_view_rows(sfile, v2d);
                columns = filelist_numfiles(sfile->files)/rows + 1; // XXX dirty, modulo is zero
-               width = columns * (sfile->tile_w + sfile->tile_border_x) + sfile->tile_border_x*2;
+               width = columns * (sfile->tile_w + 2*sfile->tile_border_x) + sfile->tile_border_x*2;
        }
 
        UI_view2d_totRect_set(v2d, width, height);
@@ -333,15 +333,12 @@ void file_draw_previews(const bContext *C, ARegion *ar)
        int todo;
        int offset;
        int columns;
-       
+       int rows;
+
        if (!files) return;
-       /* Reload directory */
-       BLI_strncpy(params->dir, filelist_dir(files), FILE_MAX);        
-       
-       type = filelist_gettype(files); 
 
+       type = filelist_gettype(files); 
        filelist_imgsize(files,sfile->prv_w,sfile->prv_h);
-
        numfiles = filelist_numfiles(files);
        
        todo = 0;
@@ -350,26 +347,26 @@ void file_draw_previews(const bContext *C, ARegion *ar)
        sx = v2d->cur.xmin + sfile->tile_border_x;
        sy = v2d->cur.ymax - sfile->tile_border_y;
        columns = file_view_columns(sfile, v2d);
-       offset = columns*(-v2d->cur.ymax+sfile->tile_border_y)/sfile->tile_h;
+       rows = file_view_rows(sfile, v2d);
+
+       offset = columns*(-v2d->cur.ymax-sfile->tile_border_y)/(sfile->tile_h+sfile->tile_border_y);
        offset = (offset/columns-1)*columns;
        if (offset<0) offset=0;
-       for (i=offset; (i < numfiles); ++i)
+       for (i=offset; (i < numfiles) && (i < (offset+(rows+2)*columns)); ++i)
        {
-               sx = v2d->tot.xmin + sfile->tile_border_x + ((i)%columns)*(sfile->tile_w+sfile->tile_border_x);
-               sy = v2d->tot.ymax - sfile->tile_border_y - ((i)/columns)*(sfile->tile_h+sfile->tile_border_y);
+               sx = v2d->tot.xmin + sfile->tile_border_x + ((i)%columns)*(sfile->tile_w+2*sfile->tile_border_x);
+               sy = v2d->tot.ymax - sfile->tile_border_y - ((i)/columns)*(sfile->tile_h+2*sfile->tile_border_y);
                file = filelist_file(files, i);                         
 
                if (params->active_file == i) {
                        colorid = TH_ACTIVE;
-                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
+                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid,0);
                } else if (file->flags & ACTIVE) {
                        colorid = TH_HILITE;
-                       draw_tile(sx, sy+sfile->tile_border_y, sfile->tile_w, sfile->tile_h-sfile->tile_border_y, colorid);
+                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid,0);
                } else {
-                       /*
-                       colorid = TH_PANEL;
-                       draw_tile(simasel, sx, sy, tilewidth, tileheight, colorid);
-                       */
+                       colorid = TH_BACK;
+                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid, -5);
                }
 
 #if 0
@@ -413,7 +410,7 @@ void file_draw_previews(const bContext *C, ARegion *ar)
                                float fx = ((float)sfile->prv_w - (float)imb->x)/2.0f;
                                float fy = ((float)sfile->prv_h - (float)imb->y)/2.0f;
                                short dx = (short)(fx + 0.5f + sfile->prv_border_x);
-                               short dy = (short)(fy + 0.5f + sfile->prv_border_y);
+                               short dy = (short)(fy + 0.5f - sfile->prv_border_y);
                                
                                glEnable(GL_BLEND);
                                glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);                                                                                                     
@@ -453,18 +450,13 @@ void file_draw_previews(const bContext *C, ARegion *ar)
                        }
                }
                        
-               file_draw_string(sx + sfile->prv_border_x, sy, file->relname, sfile->tile_w, sfile->tile_h);
-#if 0
-               if(do_load && (PIL_check_seconds_timer() - lasttime > 0.3)) {
-                       lasttime= PIL_check_seconds_timer();
-                       do_load = 0;
-               }
-#endif
+               file_draw_string(sx + sfile->prv_border_x, sy+U.fontsize*3/2, file->relname, sfile->tile_w, sfile->tile_h);
+
+               if (!sfile->loadimage_timer)
+                       sfile->loadimage_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0);  /* max 30 frames/sec. */
+
        }
-#if 0 // XXX solve with threads        or add notifier ??
-       if (!do_load && todo > 0) /* we broke off loading */
-               addafterqueue(sa->win, RENDERPREVIEW, 1);
-#endif
+
 }
 
 
@@ -481,6 +473,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
        short type;
        int i;
        int rows;
+       float sw;
 
        numfiles = filelist_numfiles(files);
        type = filelist_gettype(files); 
@@ -512,10 +505,10 @@ void file_draw_list(const bContext *C, ARegion *ar)
 
                if (params->active_file == i) {
                        colorid = TH_ACTIVE;
-                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
+                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid,0);
                } else if (file->flags & ACTIVE) {
                        colorid = TH_HILITE;
-                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
+                       draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid,0);
                } else {
                        /*
                        colorid = TH_PANEL;
@@ -548,10 +541,10 @@ void file_draw_list(const bContext *C, ARegion *ar)
                                }
                        }
                }
-
-               file_draw_string(sx, sy, file->relname, sfile->tile_w, sfile->tile_h);
-               file_draw_string(sx + sfile->tile_w - UI_GetStringWidth(G.font, file->size, 0), sy,
-                       file->size, sfile->tile_w - UI_GetStringWidth(G.font, file->size, 0), sfile->tile_h);
+               
+               sw = UI_GetStringWidth(G.font, file->size, 0);
+               file_draw_string(sx, sy, file->relname, sfile->tile_w - sw - 2, sfile->tile_h);
+               file_draw_string(sx + sfile->tile_w - sw, sy, file->size, sfile->tile_w - sw, sfile->tile_h);
        }
 }
 
index f5b93a8..9d52602 100644 (file)
@@ -49,5 +49,7 @@ void file_draw_fsmenu(const bContext *C, ARegion *ar);
 struct wmOperatorType;
 void ED_FILE_OT_select(struct wmOperatorType *ot);
 void ED_FILE_OT_select_bookmark(struct wmOperatorType *ot);
+void ED_FILE_OT_loadimages(struct wmOperatorType *ot);
+
 #endif /* ED_FILE_INTERN_H */
 
index 49014a6..2754947 100644 (file)
@@ -73,9 +73,9 @@ static void set_active_file_thumbs(SpaceFile *sfile, FileSelectParams* params, s
        View2D* v2d = &ar->v2d;
        UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
        
-       offsetx = (x - (v2d->cur.xmin+sfile->tile_border_x))/(sfile->tile_w + sfile->tile_border_x);
-       offsety = (-y+sfile->tile_border_y)/(sfile->tile_h + sfile->tile_border_y);
-       columns = (v2d->cur.xmax - v2d->cur.xmin) / (sfile->tile_w+ sfile->tile_border_x);
+       offsetx = (x - (v2d->cur.xmin+sfile->tile_border_x))/(sfile->tile_w + 2*sfile->tile_border_x);
+       offsety = (v2d->tot.ymax - sfile->tile_border_y - y)/(sfile->tile_h + 2*sfile->tile_border_y);
+       columns = (v2d->cur.xmax - v2d->cur.xmin) / (sfile->tile_w+ 2*sfile->tile_border_x);
        active_file = offsetx + columns*offsety;
 
        if (active_file >= 0 && active_file < numfiles )
@@ -250,5 +250,35 @@ void ED_FILE_OT_select_bookmark(wmOperatorType *ot)
        
        /* api callbacks */
        ot->invoke= bookmark_select_invoke;
+       ot->poll= ED_operator_file_active;
+}
+
+
+static int loadimages_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       ScrArea *sa= CTX_wm_area(C);
+       ARegion *ar= CTX_wm_region(C);
+       SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+       if (sfile->files) {
+               filelist_loadimage_timer(sfile->files);
+               if (filelist_changed(sfile->files)) {
+                       ED_area_tag_redraw(sa);
+               }
+       }
+
+       
+       return OPERATOR_FINISHED;
+}
+
+void ED_FILE_OT_loadimages(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Load Images";
+       ot->idname= "ED_FILE_OT_loadimages";
+       
+       /* api callbacks */
+       ot->invoke= loadimages_invoke;
+       
        ot->poll= ED_operator_file_active;
 }
\ No newline at end of file
index f03ea8d..e5fe3a7 100644 (file)
@@ -49,6 +49,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_linklist.h"
 #include "BLI_storage_types.h"
+#include "BLI_threads.h"
 
 #ifdef WIN32
 #include "BLI_winstuff.h"
@@ -65,6 +66,7 @@
 #include "DNA_ipo_types.h"
 #include "DNA_ID.h"
 #include "DNA_object_types.h"
+#include "DNA_listbase.h"
 #include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_texture_types.h"
 /* max length of library group name within filesel */
 #define GROUP_MAX 32
 
+static void *exec_loadimages(void *list_v);
+
+struct FileList;
+
+typedef struct FileImage {
+       struct FileImage *next, *prev;
+       int index;
+       short lock;
+       short done;
+       struct FileList* filelist;
+} FileImage;
+
 typedef struct FileList
 {
        struct direntry *filelist;
@@ -106,6 +120,9 @@ typedef struct FileList
        short prv_h;
        short hide_dot;
        unsigned int filter;
+       short changed;
+       ListBase loadimages;
+       ListBase threads;
 } FileList;
 
 int BIF_groupname_to_code(char *group)
@@ -325,7 +342,6 @@ void filelist_filter(FileList* filelist)
 
 void filelist_init_icons()
 {
-#if 0 /* XXX add icons here */
        short x, y, k;
        ImBuf *bbuf;
        ImBuf *ibuf;
@@ -345,7 +361,6 @@ void filelist_init_icons()
                }
                IMB_freeImBuf(bbuf);
        }
-#endif
 }
 
 void filelist_free_icons()
@@ -392,6 +407,9 @@ void filelist_free(struct FileList* filelist)
                return;
        }
 
+       BLI_end_threads(&filelist->threads);
+       BLI_freelistN(&filelist->loadimages);
+       
        if (filelist->fidx) {
                MEM_freeN(filelist->fidx);
                filelist->fidx = NULL;
@@ -450,6 +468,63 @@ void filelist_imgsize(struct FileList* filelist, short w, short h)
        filelist->prv_h = h;
 }
 
+
+static void *exec_loadimages(void *list_v)
+{
+       FileImage* img = (FileImage*)list_v;
+       struct FileList *filelist = img->filelist;
+
+       ImBuf *imb = NULL;
+       int fidx = img->index;
+       
+       if ( filelist->filelist[fidx].flags & IMAGEFILE ) {                             
+               imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_IMAGE);
+       } else if ( filelist->filelist[fidx].flags & MOVIEFILE ) {                              
+               imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_MOVIE);
+               if (!imb) {
+                       /* remember that file can't be loaded via IMB_open_anim */
+                       filelist->filelist[fidx].flags &= ~MOVIEFILE;
+                       filelist->filelist[fidx].flags |= MOVIEFILE_ICON;
+               }
+       }
+       if (imb) {
+               IMB_freeImBuf(imb);
+       }
+       img->done=1;
+}
+
+short filelist_changed(struct FileList* filelist)
+{
+       return filelist->changed;
+}
+
+void filelist_loadimage_timer(struct FileList* filelist)
+{
+       FileImage *limg = filelist->loadimages.first;
+       short refresh=0;
+
+       // as long as threads are available and there is work to do
+       while (limg) {
+               if (BLI_available_threads(&filelist->threads)>0) {
+                       if (!limg->lock) {
+                               limg->lock=1;
+                               BLI_insert_thread(&filelist->threads, limg);
+                       }
+               }
+               if (limg->done) {
+                       FileImage *oimg = limg;
+                       BLI_remlink(&filelist->loadimages, oimg);
+                       BLI_remove_thread(&filelist->threads, oimg);
+                       limg = oimg->next;
+                       MEM_freeN(oimg);
+                       refresh = 1;
+               } else {
+                       limg= limg->next;
+               }
+       }
+       filelist->changed=refresh;
+}
+
 void filelist_loadimage(struct FileList* filelist, int index)
 {
        ImBuf *imb = NULL;
@@ -468,16 +543,9 @@ void filelist_loadimage(struct FileList* filelist, int index)
        {
                if (filelist->type != FILE_MAIN)
                {
-                       if ( filelist->filelist[fidx].flags & IMAGEFILE ) {                             
-                               imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_IMAGE);
-                       } else if ( filelist->filelist[fidx].flags & MOVIEFILE ) {                              
-                               imb = IMB_thumb_manage(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL, THB_SOURCE_MOVIE);
-                               if (!imb) {
-                                       /* remember that file can't be loaded via IMB_open_anim */
-                                       filelist->filelist[fidx].flags &= ~MOVIEFILE;
-                                       filelist->filelist[fidx].flags |= MOVIEFILE_ICON;
-                               }
-                       }
+                       if ( (filelist->filelist[fidx].flags & IMAGEFILE) || (filelist->filelist[fidx].flags & MOVIEFILE) ) {                           
+                               imb = IMB_thumb_read(filelist->dir, filelist->filelist[fidx].relname, THB_NORMAL);
+                       } 
                        if (imb) {
                                if (imb->x > imb->y) {
                                        scaledx = (float)imgwidth;
@@ -494,10 +562,26 @@ void filelist_loadimage(struct FileList* filelist, int index)
                                dy = imgheight - ey;
                                
                                IMB_scaleImBuf(imb, ex, ey);
-
-                       } 
-                       filelist->filelist[fidx].image = imb;
-                       
+                               filelist->filelist[fidx].image = imb;
+                       } else {
+                               /* prevent loading image twice */
+                               FileImage* limg = filelist->loadimages.first;
+                               short found= 0;
+                               while(limg) {
+                                       if (limg->index == fidx) {
+                                               found= 1;
+                                               break;
+                                       }
+                                       limg= limg->next;
+                               }
+                               if (!found) {
+                                       FileImage* limg = MEM_callocN(sizeof(struct FileImage), "loadimage");
+                                       limg->index= fidx;
+                                       limg->lock= 0;
+                                       limg->filelist= filelist;
+                                       BLI_addtail(&filelist->loadimages, limg);
+                               }
+                       }               
                }
        }
 }
@@ -621,7 +705,10 @@ void filelist_readdir(struct FileList* filelist)
                chdir(wdir);
                filelist_setfiletypes(filelist, G.have_quicktime);
                filelist_filter(filelist);
-
+               
+               if (!filelist->threads.first) {
+                       BLI_init_threads(&filelist->threads, exec_loadimages, 2);
+               }
        }
 }
 
index ae3b38b..e71bcbd 100644 (file)
@@ -60,8 +60,9 @@ void                          filelist_filter(struct FileList* filelist);
 void                           filelist_swapselect(struct FileList* filelist);
 void                           filelist_imgsize(struct FileList* filelist, short w, short h);
 void                           filelist_loadimage(struct FileList* filelist, int index);
+void                           filelist_loadimage_timer(struct FileList* filelist);
 struct ImBuf *         filelist_getimage(struct FileList* filelist, int index);
-
+short                          filelist_changed(struct FileList* filelist);
 void                           filelist_readdir(struct FileList* filelist);
 
 int                                    filelist_empty(struct FileList* filelist);
index aa364bf..b0eb444 100644 (file)
@@ -246,12 +246,14 @@ void file_operatortypes(void)
 {
        WM_operatortype_append(ED_FILE_OT_select);
        WM_operatortype_append(ED_FILE_OT_select_bookmark);
+       WM_operatortype_append(ED_FILE_OT_loadimages);
 }
 
 void file_keymap(struct wmWindowManager *wm)
 {
        ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
        WM_keymap_add_item(keymap, "ED_FILE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_add_item(keymap, "ED_FILE_OT_loadimages", TIMER1, KM_ANY, KM_ANY, 0);
 
        keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
        WM_keymap_add_item(keymap, "ED_FILE_OT_select_bookmark", SELECTMOUSE, KM_PRESS, 0, 0);
@@ -406,4 +408,4 @@ void ED_file_exit(void)
 {
        fsmenu_free();
        filelist_free_icons();
-}
\ No newline at end of file
+}
index 45383f2..33a45f7 100644 (file)
@@ -53,6 +53,7 @@ struct FileList;
 struct bGPdata;
 struct FileSelectParams;
 struct wmOperator;
+struct wmTimer;
 
        /**
         * The base structure all the other spaces
@@ -175,6 +176,8 @@ typedef struct SpaceFile {
        */
        struct wmOperator *op; 
 
+       struct wmTimer *loadimage_timer;
+
        /* view settings - XXX - move into own struct */
        short prv_w;
        short prv_h;