Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-12-14 15:50:36 +0300
committerJulian Eisel <julian@blender.org>2020-12-15 19:03:48 +0300
commit70474e1a7cc45a1b1cc08d39b3e472c88c8d3225 (patch)
tree1f973b96e0b6c78e4b30e4413517a994e59ff744 /source/blender/editors/space_file/space_file.c
parente413c80371c1714d80262034d0e83b4e10e6cbe5 (diff)
Asset System: Prepare File Browser backend for the Asset Browser
The Asset Browser will be a sub-editor of the File Browser. This prepares the File Browser code for that. **File-Lists** * Support loading assets with metadata read from external files into the file-list. * New main based file-list type, for the "Current File" asset library. * Refresh file-list when switching between browse modes or asset libraries. * Support empty file-lists (asset library with no assets). * Store file previews as icons, so scripts can reference them via icon-id. See previous commit. **Space Data** * Introduce "browse mode" to differeniate between file and asset browsing. * Add `FileAssetSelectParams` to `SpaceFile`, with `FileSelectParams` as base. Makes sure data is separated between asset and file browsing when switching between them. The active params can be obtained through `ED_fileselect_get_active_params()`. * `FileAssetSelectParams` stores the currently visible asset library ID. * Introduce file history abstraction so file and asset browsing can keep a separate history (previous and next directories). **General** * Option to only show asset data-blocks while file browsing (not exposed here). * Add "active_file" context member, so scripts can get and display info about the active file. * Add "active_id" context member, so `ED_OT_lib_id_load_custom_preview` can set a custom ID preview. (Only for "Current File" asset library) * Expose some of `FileDirEntry` in RNA as (non-editable). That way scripts can obtain name, preview icon and asset-data. Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1 project milestone on developer.blender.org. Differential Revision: https://developer.blender.org/D9724 Reviewed by: Bastien Montagne
Diffstat (limited to 'source/blender/editors/space_file/space_file.c')
-rw-r--r--source/blender/editors/space_file/space_file.c139
1 files changed, 110 insertions, 29 deletions
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index c72ca58abba..f1d72387791 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -35,6 +35,8 @@
#include "BKE_screen.h"
#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_message.h"
@@ -149,22 +151,10 @@ static void file_free(SpaceLink *sl)
sfile->files = NULL;
}
- if (sfile->folders_prev) {
- folderlist_free(sfile->folders_prev);
- MEM_freeN(sfile->folders_prev);
- sfile->folders_prev = NULL;
- }
-
- if (sfile->folders_next) {
- folderlist_free(sfile->folders_next);
- MEM_freeN(sfile->folders_next);
- sfile->folders_next = NULL;
- }
+ folder_history_list_free(sfile);
- if (sfile->params) {
- MEM_freeN(sfile->params);
- sfile->params = NULL;
- }
+ MEM_SAFE_FREE(sfile->params);
+ MEM_SAFE_FREE(sfile->asset_params);
if (sfile->layout) {
MEM_freeN(sfile->layout);
@@ -205,19 +195,20 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
sfilen->previews_timer = NULL;
sfilen->smoothscroll_timer = NULL;
+ FileSelectParams *active_params_old = ED_fileselect_get_active_params(sfileo);
+ if (active_params_old) {
+ sfilen->files = filelist_new(active_params_old->type);
+ filelist_setdir(sfilen->files, active_params_old->dir);
+ }
+
if (sfileo->params) {
- sfilen->files = filelist_new(sfileo->params->type);
sfilen->params = MEM_dupallocN(sfileo->params);
- filelist_setdir(sfilen->files, sfilen->params->dir);
}
-
- if (sfileo->folders_prev) {
- sfilen->folders_prev = folderlist_duplicate(sfileo->folders_prev);
+ if (sfileo->asset_params) {
+ sfilen->asset_params = MEM_dupallocN(sfileo->asset_params);
}
- if (sfileo->folders_next) {
- sfilen->folders_next = folderlist_duplicate(sfileo->folders_next);
- }
+ sfilen->folder_histories = folder_history_list_duplicate(&sfileo->folder_histories);
if (sfileo->layout) {
sfilen->layout = MEM_dupallocN(sfileo->layout);
@@ -265,24 +256,42 @@ static void file_ensure_valid_region_state(bContext *C,
}
}
+/**
+ * Tag the space to recreate the file-list.
+ */
+static void file_tag_reset_list(ScrArea *area, SpaceFile *sfile)
+{
+ filelist_tag_force_reset(sfile->files);
+ ED_area_tag_refresh(area);
+}
+
static void file_refresh(const bContext *C, ScrArea *area)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_ensure_active_params(sfile);
+ FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
struct FSMenu *fsmenu = ED_fsmenu_get();
- if (!sfile->folders_prev) {
- sfile->folders_prev = folderlist_new();
+ fileselect_refresh_params(sfile);
+ folder_history_list_ensure_for_active_browse_mode(sfile);
+
+ if (sfile->files && (sfile->tags & FILE_TAG_REBUILD_MAIN_FILES) &&
+ filelist_needs_reset_on_main_changes(sfile->files)) {
+ filelist_tag_force_reset(sfile->files);
}
+ sfile->tags &= ~FILE_TAG_REBUILD_MAIN_FILES;
+
if (!sfile->files) {
sfile->files = filelist_new(params->type);
params->highlight_file = -1; /* added this so it opens nicer (ton) */
}
+ filelist_settype(sfile->files, params->type);
filelist_setdir(sfile->files, params->dir);
filelist_setrecursion(sfile->files, params->recursion_level);
filelist_setsorting(sfile->files, params->sort, params->flag & FILE_SORT_INVERT);
+ filelist_setlibrary(sfile->files, asset_params ? &asset_params->asset_library : NULL);
filelist_setfilter_options(
sfile->files,
(params->flag & FILE_FILTER) != 0,
@@ -290,6 +299,7 @@ static void file_refresh(const bContext *C, ScrArea *area)
true, /* Just always hide parent, prefer to not add an extra user option for this. */
params->filter,
params->filter_id,
+ (params->flag & FILE_ASSETS_ONLY) != 0,
params->filter_glob,
params->filter_search);
@@ -300,12 +310,12 @@ static void file_refresh(const bContext *C, ScrArea *area)
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_force_reset(sfile->files)) {
+ if (filelist_needs_force_reset(sfile->files)) {
filelist_readjob_stop(wm, CTX_data_scene(C));
filelist_clear(sfile->files);
}
- if (filelist_empty(sfile->files)) {
+ if (filelist_needs_reading(sfile->files)) {
if (!filelist_pending(sfile->files)) {
filelist_readjob_start(sfile->files, C);
}
@@ -365,6 +375,14 @@ static void file_listener(wmWindow *UNUSED(win),
break;
}
break;
+ case NC_ASSET: {
+ if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) {
+ /* Full refresh of the file list if local asset data was changed. Refreshing this view is
+ * cheap and users expect this to be updated immediately. */
+ file_tag_reset_list(area, sfile);
+ }
+ break;
+ }
}
}
@@ -442,6 +460,22 @@ static void file_main_region_message_subscribe(const struct bContext *UNUSED(C),
}
}
+static bool file_main_region_needs_refresh_before_draw(SpaceFile *sfile)
+{
+ /* Needed, because filelist is not initialized on loading */
+ if (!sfile->files || filelist_needs_reading(sfile->files)) {
+ return true;
+ }
+
+ /* File reading tagged the space because main data changed that may require a filelist reset. */
+ if (filelist_needs_reset_on_main_changes(sfile->files) &&
+ (sfile->tags & FILE_TAG_REBUILD_MAIN_FILES)) {
+ return true;
+ }
+
+ return false;
+}
+
static void file_main_region_draw(const bContext *C, ARegion *region)
{
/* draw entirely, view changes should be handled here */
@@ -450,8 +484,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
View2D *v2d = &region->v2d;
- /* Needed, because filelist is not initialized on loading */
- if (!sfile->files || filelist_empty(sfile->files)) {
+ if (file_main_region_needs_refresh_before_draw(sfile)) {
file_refresh(C, NULL);
}
@@ -681,6 +714,52 @@ static void file_dropboxes(void)
WM_dropbox_add(lb, "FILE_OT_filepath_drop", filepath_drop_poll, filepath_drop_copy);
}
+const char *file_context_dir[] = {"active_file", "active_id", NULL};
+
+static int /*eContextResult*/ file_context(const bContext *C,
+ const char *member,
+ bContextDataResult *result)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+
+ BLI_assert(!ED_area_is_global(CTX_wm_area(C)));
+
+ if (CTX_data_dir(member)) {
+ CTX_data_dir_set(result, file_context_dir);
+ return CTX_RESULT_OK;
+ }
+ else if (CTX_data_equals(member, "active_file")) {
+ FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+ CTX_data_pointer_set(result, &screen->id, &RNA_FileSelectEntry, file);
+ return CTX_RESULT_OK;
+ }
+ else if (CTX_data_equals(member, "active_id")) {
+ const FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+
+ ID *id = filelist_file_get_id(file);
+ if (id) {
+ CTX_data_id_pointer_set(result, id);
+ }
+ return CTX_RESULT_OK;
+ }
+ return CTX_RESULT_MEMBER_NOT_FOUND;
+}
+
+static void file_id_remap(ScrArea *area, SpaceLink *sl, ID *UNUSED(old_id), ID *UNUSED(new_id))
+{
+ SpaceFile *sfile = (SpaceFile *)sl;
+
+ /* If the file shows main data (IDs), tag it for reset. */
+ if (sfile->files && filelist_needs_reset_on_main_changes(sfile->files)) {
+ /* Full refresh of the file list if main data was changed, don't even attempt remap pointers.
+ * We could give file list types a id-remap callback, but it's probably not worth it.
+ * Refreshing local file lists is relatively cheap. */
+ file_tag_reset_list(area, sfile);
+ }
+}
+
/* only called once, from space/spacetypes.c */
void ED_spacetype_file(void)
{
@@ -700,6 +779,8 @@ void ED_spacetype_file(void)
st->operatortypes = file_operatortypes;
st->keymap = file_keymap;
st->dropboxes = file_dropboxes;
+ st->context = file_context;
+ st->id_remap = file_id_remap;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");