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:
authorSybren A. Stüvel <sybren@blender.org>2021-03-05 17:00:56 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-03-05 17:11:40 +0300
commitfe35551df2d874d51073b1dc4a582a1962255949 (patch)
tree7926ab181119dc64510e99695d4ab3ab634a6fde
parent0dd9a4a576452007da9d3f02a03499e50a8ddfae (diff)
Asset Browser Space API: add `activate_asset_by_id()` function
Add an RNA function `activate_asset_by_id(asset_id: ID, deferred: bool)` to the File Browser space type, which intended to be used to activate an asset's entry as identified by its `ID *`. Calling it changes the active asset, but only if the given ID can actually be found. The activation can be deferred (by passing `deferred=True`) until the next refresh operation has finished. This is necessary when an asset has just been added, as it will be loaded by the filebrowser in a background job. Reviewed By: Severin Differential Revision: https://developer.blender.org/D10549
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/editors/include/ED_fileselect.h7
-rw-r--r--source/blender/editors/space_file/file_intern.h15
-rw-r--r--source/blender/editors/space_file/filelist.c11
-rw-r--r--source/blender/editors/space_file/filelist.h2
-rw-r--r--source/blender/editors/space_file/filesel.c60
-rw-r--r--source/blender/editors/space_file/space_file.c51
-rw-r--r--source/blender/makesdna/DNA_space_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_internal.h1
-rw-r--r--source/blender/makesrna/intern/rna_space.c2
-rw-r--r--source/blender/makesrna/intern/rna_space_api.c21
-rw-r--r--source/blender/windowmanager/WM_types.h1
12 files changed, 166 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 8b911143668..623f3a349d8 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -1681,6 +1681,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
sfile->op = NULL;
sfile->previews_timer = NULL;
sfile->tags = 0;
+ sfile->runtime = NULL;
BLO_read_data_address(reader, &sfile->params);
BLO_read_data_address(reader, &sfile->asset_params);
}
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 7538dac1354..983ae94b637 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -145,6 +145,13 @@ void ED_fileselect_exit(struct wmWindowManager *wm,
struct SpaceFile *sfile);
bool ED_fileselect_is_asset_browser(const struct SpaceFile *sfile);
+struct ID *ED_fileselect_active_asset_get(const struct SpaceFile *sfile);
+
+/* Activate the file that corresponds to the given ID.
+ * Pass deferred=true to wait for the next refresh before activating. */
+void ED_fileselect_activate_by_id(struct SpaceFile *sfile,
+ struct ID *asset_id,
+ const bool deferred);
void ED_fileselect_window_params_get(const struct wmWindow *win,
int win_size[2],
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 56fb588776e..deb32812f44 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -112,6 +112,21 @@ int autocomplete_file(struct bContext *C, char *str, void *arg_v);
void file_params_renamefile_activate(struct SpaceFile *sfile, struct FileSelectParams *params);
+typedef void *onReloadFnData;
+typedef void (*onReloadFn)(struct SpaceFile *space_data, onReloadFnData custom_data);
+typedef struct SpaceFile_Runtime {
+ /* Called once after the file browser has reloaded. Reset to NULL after calling.
+ * Use file_on_reload_callback_register() to register a callback. */
+ onReloadFn on_reload;
+ onReloadFnData on_reload_custom_data;
+} SpaceFile_Runtime;
+
+/* Register an on-reload callback function. Note that there can only be one such function at a
+ * time; registering a new one will overwrite the previous one. */
+void file_on_reload_callback_register(struct SpaceFile *sfile,
+ onReloadFn callback,
+ onReloadFnData custom_data);
+
/* file_panels.c */
void file_tool_props_region_panels_register(struct ARegionType *art);
void file_execute_region_panels_register(struct ARegionType *art);
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 33c37875372..518fc777c67 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -1990,9 +1990,7 @@ static void filelist_file_release_entry(FileList *filelist, FileDirEntry *entry)
filelist_entry_free(entry);
}
-static FileDirEntry *filelist_file_ex(struct FileList *filelist,
- const int index,
- const bool use_request)
+FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const bool use_request)
{
FileDirEntry *ret = NULL, *old;
FileListEntryCache *cache = &filelist->filelist_cache;
@@ -3464,7 +3462,7 @@ void filelist_readjob_start(FileList *filelist, const bContext *C)
filelist_readjob_endjob(flrj);
filelist_readjob_free(flrj);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST | NA_JOB_FINISHED, NULL);
return;
}
@@ -3476,7 +3474,10 @@ void filelist_readjob_start(FileList *filelist, const bContext *C)
WM_JOB_PROGRESS,
WM_JOB_TYPE_FILESEL_READDIR);
WM_jobs_customdata_set(wm_job, flrj, filelist_readjob_free);
- WM_jobs_timer(wm_job, 0.01, NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST);
+ WM_jobs_timer(wm_job,
+ 0.01,
+ NC_SPACE | ND_SPACE_FILE_LIST,
+ NC_SPACE | ND_SPACE_FILE_LIST | NA_JOB_FINISHED);
WM_jobs_callbacks(
wm_job, filelist_readjob_startjob, NULL, filelist_readjob_update, filelist_readjob_endjob);
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 16984bb6e43..7eecd7a05de 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -93,6 +93,8 @@ void filelist_setdir(struct FileList *filelist, char *r_dir);
int filelist_files_ensure(struct FileList *filelist);
int filelist_needs_reading(struct FileList *filelist);
FileDirEntry *filelist_file(struct FileList *filelist, int index);
+FileDirEntry *filelist_file_ex(struct FileList *filelist, int index, bool use_request);
+
int filelist_file_findpath(struct FileList *filelist, const char *file);
struct ID *filelist_file_get_id(const struct FileDirEntry *file);
FileDirEntry *filelist_entry_find_uuid(struct FileList *filelist, const int uuid[4]);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 6917893ab5f..7015ca970a3 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -454,6 +454,66 @@ bool ED_fileselect_is_asset_browser(const SpaceFile *sfile)
return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS);
}
+struct ID *ED_fileselect_active_asset_get(const SpaceFile *sfile)
+{
+ if (!ED_fileselect_is_asset_browser(sfile)) {
+ return NULL;
+ }
+
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ const FileDirEntry *file = filelist_file(sfile->files, params->active_file);
+ if (file == NULL) {
+ return NULL;
+ }
+
+ return filelist_file_get_id(file);
+}
+
+static void on_reload_activate_by_id(SpaceFile *sfile, onReloadFnData custom_data)
+{
+ ID *asset_id = (ID *)custom_data;
+ ED_fileselect_activate_by_id(sfile, asset_id, false);
+}
+
+void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool deferred)
+{
+ if (!ED_fileselect_is_asset_browser(sfile)) {
+ return;
+ }
+
+ /* If there are filelist operations running now ("pending" true) or soon ("force reset" true),
+ * there is a fair chance that the to-be-activated ID will only be present after these operations
+ * have completed. Defer activation until then. */
+ if (deferred || filelist_pending(sfile->files) || filelist_needs_force_reset(sfile->files)) {
+ /* This should be thread-safe, as this function is likely called from the main thread, and
+ * notifiers (which cause a call to the on-reload callback function) are handled on the main
+ * thread as well. */
+ file_on_reload_callback_register(sfile, on_reload_activate_by_id, asset_id);
+ return;
+ }
+
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+ struct FileList *files = sfile->files;
+
+ const int num_files_filtered = filelist_files_ensure(files);
+ for (int file_index = 0; file_index < num_files_filtered; ++file_index) {
+ const FileDirEntry *file = filelist_file_ex(files, file_index, false);
+
+ if (filelist_file_get_id(file) != asset_id) {
+ filelist_entry_select_set(files, file, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
+ continue;
+ }
+
+ params->active_file = file_index;
+ filelist_entry_select_set(files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL);
+
+ /* Keep looping to deselect the other files. */
+ }
+
+ WM_main_add_notifier(NC_ASSET | NA_ACTIVATED, NULL);
+ WM_main_add_notifier(NC_ASSET | NA_SELECTED, NULL);
+}
+
/* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA
* may also be remembered, but only conditionally. */
#define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT)
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index b175844a710..2c9c2688e88 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -173,6 +173,7 @@ static void file_free(SpaceLink *sl)
MEM_SAFE_FREE(sfile->params);
MEM_SAFE_FREE(sfile->asset_params);
+ MEM_SAFE_FREE(sfile->runtime);
if (sfile->layout) {
MEM_freeN(sfile->layout);
@@ -188,6 +189,10 @@ static void file_init(wmWindowManager *UNUSED(wm), ScrArea *area)
if (sfile->layout) {
sfile->layout->dirty = true;
}
+
+ if (sfile->runtime == NULL) {
+ sfile->runtime = MEM_callocN(sizeof(*sfile->runtime), __func__);
+ }
}
static void file_exit(wmWindowManager *wm, ScrArea *area)
@@ -209,6 +214,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */
sfilen->op = NULL; /* file window doesn't own operators */
+ sfilen->runtime = NULL;
sfilen->previews_timer = NULL;
sfilen->smoothscroll_timer = NULL;
@@ -392,6 +398,26 @@ static void file_refresh(const bContext *C, ScrArea *area)
ED_area_tag_redraw(area);
}
+void file_on_reload_callback_register(SpaceFile *sfile,
+ onReloadFn callback,
+ onReloadFnData custom_data)
+{
+ sfile->runtime->on_reload = callback;
+ sfile->runtime->on_reload_custom_data = custom_data;
+}
+
+static void file_on_reload_callback_call(SpaceFile *sfile)
+{
+ if (sfile->runtime->on_reload == NULL) {
+ return;
+ }
+
+ sfile->runtime->on_reload(sfile, sfile->runtime->on_reload_custom_data);
+
+ sfile->runtime->on_reload = NULL;
+ sfile->runtime->on_reload_custom_data = NULL;
+}
+
static void file_listener(const wmSpaceTypeListenerParams *params)
{
ScrArea *area = params->area;
@@ -419,12 +445,26 @@ static void file_listener(const wmSpaceTypeListenerParams *params)
}
break;
}
+ switch (wmn->action) {
+ case NA_JOB_FINISHED:
+ file_on_reload_callback_call(sfile);
+ 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);
+ switch (wmn->action) {
+ case NA_SELECTED:
+ case NA_ACTIVATED:
+ ED_area_tag_refresh(area);
+ break;
+ case NA_ADDED:
+ case NA_REMOVED:
+ 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;
}
break;
}
@@ -464,8 +504,7 @@ static void file_main_region_listener(const wmRegionListenerParams *params)
}
break;
case NC_ID:
- if (ELEM(wmn->action, NA_RENAME)) {
- /* In case the filelist shows ID names. */
+ if (ELEM(wmn->action, NA_SELECTED, NA_ACTIVATED, NA_RENAME)) {
ED_region_tag_redraw(region);
}
break;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index dc1775b09c6..856fa569645 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -66,6 +66,9 @@ typedef struct SpaceProperties_Runtime SpaceProperties_Runtime;
/* Defined in `node_intern.h`. */
typedef struct SpaceNode_Runtime SpaceNode_Runtime;
+/* Defined in `file_intern.h`. */
+typedef struct SpaceFile_Runtime SpaceFile_Runtime;
+
/* -------------------------------------------------------------------- */
/** \name SpaceLink (Base)
* \{ */
@@ -846,6 +849,8 @@ typedef struct SpaceFile {
short recentnr, bookmarknr;
short systemnr, system_bookmarknr;
+
+ SpaceFile_Runtime *runtime;
} SpaceFile;
/* SpaceFile.browse_mode (File Space Browsing Mode) */
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index bfcb0039ca8..95972dd444f 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -424,6 +424,7 @@ void RNA_api_window(struct StructRNA *srna);
void RNA_api_wm(struct StructRNA *srna);
void RNA_api_space_node(struct StructRNA *srna);
void RNA_api_space_text(struct StructRNA *srna);
+void RNA_api_space_filebrowser(struct StructRNA *srna);
void RNA_api_region_view3d(struct StructRNA *srna);
void RNA_api_texture(struct StructRNA *srna);
void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop, const bool metastrip);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 409a2f097ed..5312aea9295 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -6569,6 +6569,8 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(
prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+ RNA_api_space_filebrowser(srna);
}
static void rna_def_space_info(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_space_api.c b/source/blender/makesrna/intern/rna_space_api.c
index e4c0ade1533..205a88edf84 100644
--- a/source/blender/makesrna/intern/rna_space_api.c
+++ b/source/blender/makesrna/intern/rna_space_api.c
@@ -27,6 +27,7 @@
# include "BKE_global.h"
+# include "ED_fileselect.h"
# include "ED_screen.h"
# include "ED_text.h"
@@ -115,4 +116,24 @@ void RNA_api_space_text(StructRNA *srna)
RNA_def_function_output(func, parm);
}
+void RNA_api_space_filebrowser(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func = RNA_def_function(srna, "activate_asset_by_id", "ED_fileselect_activate_by_id");
+ RNA_def_function_ui_description(func, "Activate the asset entry that represents the given ID");
+
+ parm = RNA_def_property(func, "id_to_activate", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(parm, "ID");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
+ parm = RNA_def_boolean(
+ func,
+ "deferred",
+ 0,
+ "",
+ "Whether to activate the ID immediately (false) or after the file browser refreshes (true)");
+}
+
#endif
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index f12832faa45..084ca2d2df5 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -461,6 +461,7 @@ typedef struct wmNotifier {
#define NA_SELECTED 6
#define NA_ACTIVATED 7
#define NA_PAINTING 8
+#define NA_JOB_FINISHED 9
/* ************** Gesture Manager data ************** */