Final 'FileBrowser First Stage' merge.

It basically rewrites most of filelist.c, with some more limited changes in other areas of filebrowser.

From user perspective, it:
* Removes some info in 'long' drawing mode (owner, permissions) - OS-specific data that do not really matter in Blender!
* Makes short/long display 'fixed' size (among four choices, like thumbnails mode).
* Allows to list several layers of dirtree at once, in a flat way (inside .blend files and/or real directories).
* Consequently, adds datablocks types filtering.
* Uses way less RAM when listing big directories, especially in thumbnail mode (we are talking of several hundred of MiB spared).
* Generates thumbnails way faster.

From code perspective, it:
* Is ready for asset engine needs (on data structure level in filebrowser's listing).
* Simplifies and makes 'generic' file listing much lighter.
* Separates file listing in three different aspects:
** 'generic' filelisting (in BLI), which becomes a shallow wrapper around stat struct.
** 'filebrowser drawing' filelisting, which only contains current visible subset of the whole list (sliding window), with extra drawing data (strings for size, date/time, preview, etc.).
** 'asset-ready' filelisting, which is used for operations common to 'basic' filehandling and future asset-related one.
* Uses uuid's to handle file selection/state in the browser, instead of using flags in filelisting items.
* Uses much lighter BLI_task handling for previews, instead of heavy 'job' system (using the new 'notifier' timer to handle UI refresh, in similar way to jobs).
* Moves .blend datablocks preview handling to IMB_thumbnail (necessary to avoid storing all datablock previews at once, and gives better consistency and performances too).

Revision: https://developer.blender.org/D1316

Thanks to Campbell & Sergey for the reviews. :)
This commit is contained in:
Bastien Montagne
2015-08-19 22:41:39 +02:00
parent 5c659574e6
commit f69e9681fa
21 changed files with 2776 additions and 1100 deletions

View File

@@ -117,6 +117,8 @@ static void file_free(SpaceLink *sl)
{
SpaceFile *sfile = (SpaceFile *) sl;
BLI_assert(sfile->previews_timer == NULL);
if (sfile->files) {
// XXXXX would need to do thumbnails_stop here, but no context available
filelist_freelib(sfile->files);
@@ -170,7 +172,12 @@ static void file_exit(wmWindowManager *wm, ScrArea *sa)
{
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
ED_fileselect_exit(wm, sfile);
if (sfile->previews_timer) {
WM_event_remove_timer_notifier(wm, NULL, sfile->previews_timer);
sfile->previews_timer = NULL;
}
ED_fileselect_exit(wm, sa, sfile);
}
static SpaceLink *file_duplicate(SpaceLink *sl)
@@ -211,13 +218,15 @@ static void file_refresh(const bContext *C, ScrArea *sa)
}
if (!sfile->files) {
sfile->files = filelist_new(params->type);
filelist_setdir(sfile->files, params->dir);
params->highlight_file = -1; /* added this so it opens nicer (ton) */
}
filelist_setdir(sfile->files, params->dir);
filelist_setrecursion(sfile->files, params->recursion_level);
filelist_setsorting(sfile->files, params->sort);
filelist_setfilter_options(sfile->files, params->flag & FILE_HIDE_DOT,
filelist_setfilter_options(sfile->files, (params->flag & FILE_HIDE_DOT) != 0,
false, /* TODO hide_parent, should be controllable? */
params->flag & FILE_FILTER ? params->filter : 0,
params->filter_id,
params->filter_glob,
params->filter_search);
@@ -227,39 +236,45 @@ static void file_refresh(const bContext *C, ScrArea *sa)
sfile->bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir);
sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir);
if (filelist_empty(sfile->files)) {
thumbnails_stop(wm, sfile->files);
filelist_readdir(sfile->files);
filelist_sort(sfile->files);
BLI_strncpy(params->dir, filelist_dir(sfile->files), FILE_MAX);
}
else if (filelist_need_sorting(sfile->files)) {
thumbnails_stop(wm, sfile->files);
filelist_sort(sfile->files);
if (filelist_force_reset(sfile->files)) {
filelist_readjob_stop(wm, sa);
filelist_clear(sfile->files);
}
if ((params->display == FILE_IMGDISPLAY) && filelist_need_thumbnails(sfile->files)) {
if (!thumbnails_running(wm, sfile->files)) {
thumbnails_start(sfile->files, C);
if (filelist_empty(sfile->files)) {
if (!filelist_pending(sfile->files)) {
filelist_readjob_start(sfile->files, C);
}
}
else {
/* stop any running thumbnail jobs if we're not displaying them - speedup for NFS */
thumbnails_stop(wm, sfile->files);
}
filelist_sort(sfile->files);
filelist_filter(sfile->files);
if (params->display == FILE_IMGDISPLAY) {
filelist_cache_previews_set(sfile->files, true);
}
else {
filelist_cache_previews_set(sfile->files, false);
if (sfile->previews_timer) {
WM_event_remove_timer_notifier(wm, CTX_wm_window(C), sfile->previews_timer);
sfile->previews_timer = NULL;
}
}
if (params->renamefile[0] != '\0') {
int idx = filelist_find(sfile->files, params->renamefile);
int idx = filelist_file_findpath(sfile->files, params->renamefile);
if (idx >= 0) {
struct direntry *file = filelist_file(sfile->files, idx);
FileDirEntry *file = filelist_file(sfile->files, idx);
if (file) {
file->selflag |= FILE_SEL_EDITING;
filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
}
}
BLI_strncpy(sfile->params->renameedit, sfile->params->renamefile, sizeof(sfile->params->renameedit));
params->renamefile[0] = '\0';
/* File listing is now async, do not clear renamefile if matching entry not found
* and dirlist is not finished! */
if (idx >= 0 || filelist_is_ready(sfile->files)) {
params->renamefile[0] = '\0';
}
}
if (sfile->layout) {
@@ -278,7 +293,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
{
/* SpaceFile *sfile = (SpaceFile *)sa->spacedata.first; */
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
/* context changes */
switch (wmn->category) {
@@ -292,6 +307,12 @@ static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
break;
case ND_SPACE_FILE_PREVIEW:
if (filelist_cache_previews_update(sfile->files)) {
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
break;
}
break;
}