diff options
author | Julian Eisel <julian@blender.org> | 2021-07-07 20:24:06 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2021-07-07 20:24:06 +0300 |
commit | f4cb3ccd9c070dce24db98436ccf2e0e70000077 (patch) | |
tree | 11bdbb53e466224db234bf35ef73e0fff67dac70 /source/blender | |
parent | fb98f22ddd5c814c01facacb48284acdfe8099fd (diff) |
Assets: Keep assets active after renaming, ensure they are scrolled into view
When renaming an ID somewhere in the UI after marking it as asset, it would
often get lost in the Asset Browser (scrolled out of view). It would also get
deactivated.
This patch makes sure that if an asset is active whose ID gets renamed, it is
kept active and visible. That is important for a fast, uninterrupted asset
creation workflow, where users often rename assets while working in the asset
browser.
Old code stored the new file-name to identify a file after re-reading the
file-list after the rename. For assets that doesn't work because there may be
multiple assets with the same name. Here the simple solution of just storing
the pointer to the renamed ID is chosen, rather than relying on the file-name
in this case. (Should be fine with undo, since the ID * reference is short
lived, it's not stored over possible undo steps. If it turns out to have
issues, I rather switch to a rename_id_uuid, but keep that separate from the
file->uid).
Reviewed by: Sybren Stüvel
Differential Revision: https://developer.blender.org/D11119
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/screen.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 32 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 17 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 12 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 7 |
7 files changed, 67 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index a2809543b95..73658c3184e 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -1734,6 +1734,12 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area) sfile->runtime = NULL; BLO_read_data_address(reader, &sfile->params); BLO_read_data_address(reader, &sfile->asset_params); + if (sfile->params) { + sfile->params->rename_id = NULL; + } + if (sfile->asset_params) { + sfile->asset_params->base_params.rename_id = NULL; + } } else if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index aeb6c7fd521..995383d9d0e 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -2340,6 +2340,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) /* If we don't enter the directory directly, remember file to jump into editing. */ if (do_diropen == false) { + BLI_assert(params->rename_id == NULL || !"File rename handling should immediately clear rename_id when done, because otherwise it will keep taking precedence over renamefile."); BLI_strncpy(params->renamefile, name, FILE_MAXFILE); rename_flag = FILE_PARAMS_RENAME_PENDING; } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index fe545aa5bf2..ab3a2bf041e 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -2016,19 +2016,21 @@ FileDirEntry *filelist_file(struct FileList *filelist, int index) return filelist_file_ex(filelist, index, true); } -int filelist_file_findpath(struct FileList *filelist, const char *filename) +/** + * Find a file from a file name, or more precisely, its file-list relative path, inside the + * filtered items. \return The index of the found file or -1. + */ +int filelist_file_find_path(struct FileList *filelist, const char *filename) { - int fidx = -1; - if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { - return fidx; + return -1; } /* XXX TODO: Cache could probably use a ghash on paths too? Not really urgent though. * This is only used to find again renamed entry, * annoying but looks hairy to get rid of it currently. */ - for (fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { + for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx]; if (STREQ(entry->relpath, filename)) { return fidx; @@ -2039,6 +2041,26 @@ int filelist_file_findpath(struct FileList *filelist, const char *filename) } /** + * Find a file representing \a id. + * \return The index of the found file or -1. + */ +int filelist_file_find_id(const FileList *filelist, const ID *id) +{ + if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) { + return -1; + } + + for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) { + FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx]; + if (entry->local_data.id == id) { + return fidx; + } + } + + return -1; +} + +/** * Get the ID a file represents (if any). For #FILE_MAIN, #FILE_MAIN_ASSET. */ ID *filelist_file_get_id(const FileDirEntry *file) diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index e6c4b8e1a07..0aace74e621 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -97,7 +97,8 @@ 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); +int filelist_file_find_path(struct FileList *filelist, const char *file); +int filelist_file_find_id(const struct FileList *filelist, const struct ID *id); struct ID *filelist_file_get_id(const struct FileDirEntry *file); bool filelist_uid_is_set(const FileUID uid); void filelist_uid_unset(FileUID *r_uid); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 6be957539aa..e8ce6f280e1 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -1284,9 +1284,17 @@ void file_params_rename_end(wmWindowManager *wm, void file_params_renamefile_clear(FileSelectParams *params) { params->renamefile[0] = '\0'; + params->rename_id = NULL; params->rename_flag = 0; } +static int file_params_find_renamed(const FileSelectParams *params, struct FileList *filelist) +{ + /* Find the file either through the local ID/asset it represents or its relative path. */ + return (params->rename_id != NULL) ? filelist_file_find_id(filelist, params->rename_id) : + filelist_file_find_path(filelist, params->renamefile); +} + /** * Helper used by both main update code, and smooth-scroll timer, * to try to enable rename editing from #FileSelectParams.renamefile name. @@ -1300,13 +1308,16 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) return; } - BLI_assert(params->renamefile[0] != '\0'); + BLI_assert(params->renamefile[0] != '\0' || params->rename_id != NULL); - const int idx = filelist_file_findpath(sfile->files, params->renamefile); + const int idx = file_params_find_renamed(params, sfile->files); if (idx >= 0) { FileDirEntry *file = filelist_file(sfile->files, idx); BLI_assert(file != NULL); + params->active_file = idx; + filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); + if ((params->rename_flag & FILE_PARAMS_RENAME_PENDING) != 0) { filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL); params->rename_flag = FILE_PARAMS_RENAME_ACTIVE; @@ -1316,7 +1327,7 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) filelist_entry_select_set( sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED, CHECK_ALL); params->active_file = idx; - params->renamefile[0] = '\0'; + file_params_renamefile_clear(params); params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE; } } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 64b43ac74a5..05d484d8e2e 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -32,6 +32,7 @@ #include "BKE_appdir.h" #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_main.h" #include "BKE_screen.h" #include "RNA_access.h" @@ -469,10 +470,19 @@ static void file_listener(const wmSpaceTypeListenerParams *listener_params) break; case NC_ID: { switch (wmn->action) { - case NA_RENAME: + case NA_RENAME: { + const ID *active_file_id = ED_fileselect_active_asset_get(sfile); + /* If a renamed ID is active in the file browser, update scrolling to keep it in view. */ + if (active_file_id && (wmn->reference == active_file_id)) { + FileSelectParams *params = ED_fileselect_get_active_params(sfile); + params->rename_id = active_file_id; + file_params_invoke_rename_postscroll(G_MAIN->wm.first, listener_params->window, sfile); + } + /* Force list to update sorting (with a full reset for now). */ file_reset_filelist_showing_main_data(area, sfile); break; + } } break; } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 557343f79cd..73a44ec16bb 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -727,6 +727,12 @@ typedef struct FileSelectParams { char renamefile[256]; short rename_flag; + char _pad[4]; + /** An ID that was just renamed. Used to identify a renamed asset file over re-reads, similar to + * `renamefile` but for local IDs (takes precedence). Don't keep this stored across handlers! + * Would break on undo. */ + const ID *rename_id; + void *_pad3; /** List of filetypes to filter (FILE_MAXFILE). */ char filter_glob[256]; @@ -734,7 +740,6 @@ typedef struct FileSelectParams { /** Text items name must match to be shown. */ char filter_search[64]; /** Same as filter, but for ID types (aka library groups). */ - int _pad0; uint64_t filter_id; /** Active file used for keyboard navigation. */ |