diff options
author | Andrea Weikert <elubie@gmx.net> | 2009-01-18 21:24:11 +0300 |
---|---|---|
committer | Andrea Weikert <elubie@gmx.net> | 2009-01-18 21:24:11 +0300 |
commit | 2c5bf52214cd9a1c17f84de31fd1a4deee327afc (patch) | |
tree | 0a5cc47d92aa59b37f664f5a5b8aa9626a6fb8eb /source | |
parent | 332517957de480414048d86e0b01499932214020 (diff) |
2.5 filebrowser
* 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
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/space_file/file_draw.c | 79 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 36 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 121 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 3 |
7 files changed, 183 insertions, 65 deletions
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index c45993d71cb..93c9236cf13 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -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); } } diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index f5b93a84f39..9d52602a1f8 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -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 */ diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 49014a69b68..2754947b9a5 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -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 ) @@ -251,4 +251,34 @@ 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 diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index f03ea8d9456..e5fe3a787c5 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -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" @@ -90,6 +92,18 @@ /* 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); + } } } diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index ae3b38b4353..e71bcbddb86 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -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); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index aa364bfb093..b0eb444d62b 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -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 +} diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 45383f2fa34..33a45f76a22 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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; |