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
This commit is contained in:
parent
e413c80371
commit
70474e1a7c
@ -1266,6 +1266,9 @@ static void write_area_regions(BlendWriter *writer, ScrArea *area)
|
||||
if (sfile->params) {
|
||||
BLO_write_struct(writer, FileSelectParams, sfile->params);
|
||||
}
|
||||
if (sfile->asset_params) {
|
||||
BLO_write_struct(writer, FileAssetSelectParams, sfile->asset_params);
|
||||
}
|
||||
}
|
||||
else if (sl->spacetype == SPACE_SEQ) {
|
||||
BLO_write_struct(writer, SpaceSeq, sl);
|
||||
@ -1663,11 +1666,14 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
|
||||
* plus, it isn't saved to files yet!
|
||||
*/
|
||||
sfile->folders_prev = sfile->folders_next = NULL;
|
||||
BLI_listbase_clear(&sfile->folder_histories);
|
||||
sfile->files = NULL;
|
||||
sfile->layout = NULL;
|
||||
sfile->op = NULL;
|
||||
sfile->previews_timer = NULL;
|
||||
sfile->tags = 0;
|
||||
BLO_read_data_address(reader, &sfile->params);
|
||||
BLO_read_data_address(reader, &sfile->asset_params);
|
||||
}
|
||||
else if (sl->spacetype == SPACE_CLIP) {
|
||||
SpaceClip *sclip = (SpaceClip *)sl;
|
||||
@ -1751,8 +1757,11 @@ void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrAr
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_FILE:
|
||||
case SPACE_FILE: {
|
||||
SpaceFile *sfile = (SpaceFile *)sl;
|
||||
sfile->tags |= FILE_TAG_REBUILD_MAIN_FILES;
|
||||
break;
|
||||
}
|
||||
case SPACE_ACTION: {
|
||||
SpaceAction *saction = (SpaceAction *)sl;
|
||||
bDopeSheet *ads = &saction->ads;
|
||||
|
@ -2751,6 +2751,7 @@ static void lib_link_workspace_layout_restore(struct IDNameLib_Map *id_map,
|
||||
SpaceFile *sfile = (SpaceFile *)sl;
|
||||
sfile->op = NULL;
|
||||
sfile->previews_timer = NULL;
|
||||
sfile->tags = FILE_TAG_REBUILD_MAIN_FILES;
|
||||
}
|
||||
else if (sl->spacetype == SPACE_ACTION) {
|
||||
SpaceAction *saction = (SpaceAction *)sl;
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
|
||||
struct ARegion;
|
||||
struct FileSelectParams;
|
||||
struct FileAssetSelectParams;
|
||||
struct Scene;
|
||||
struct ScrArea;
|
||||
struct SpaceFile;
|
||||
@ -103,14 +104,14 @@ struct rcti;
|
||||
|
||||
struct FileSelectParams *ED_fileselect_ensure_active_params(struct SpaceFile *sfile);
|
||||
struct FileSelectParams *ED_fileselect_get_active_params(const struct SpaceFile *sfile);
|
||||
struct FileSelectParams *ED_fileselect_get_file_params(const struct SpaceFile *sfile);
|
||||
struct FileAssetSelectParams *ED_fileselect_get_asset_params(const struct SpaceFile *sfile);
|
||||
|
||||
void ED_fileselect_set_params_from_userdef(struct SpaceFile *sfile);
|
||||
void ED_fileselect_params_to_userdef(struct SpaceFile *sfile,
|
||||
const int temp_win_size[],
|
||||
const bool is_maximized);
|
||||
|
||||
void ED_fileselect_reset_params(struct SpaceFile *sfile);
|
||||
|
||||
void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *region);
|
||||
|
||||
FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *region);
|
||||
@ -142,6 +143,8 @@ void ED_fileselect_exit(struct wmWindowManager *wm,
|
||||
struct Scene *owner_scene,
|
||||
struct SpaceFile *sfile);
|
||||
|
||||
bool ED_fileselect_is_asset_browser(const struct SpaceFile *sfile);
|
||||
|
||||
void ED_fileselect_window_params_get(const struct wmWindow *win,
|
||||
int win_size[2],
|
||||
bool *is_maximized);
|
||||
|
@ -90,6 +90,7 @@ void file_sfile_to_operator(struct Main *bmain, struct wmOperator *op, struct Sp
|
||||
void file_operator_to_sfile(struct Main *bmain, struct SpaceFile *sfile, struct wmOperator *op);
|
||||
|
||||
/* filesel.c */
|
||||
void fileselect_refresh_params(struct SpaceFile *sfile);
|
||||
void fileselect_file_set(SpaceFile *sfile, const int index);
|
||||
bool file_attribute_column_type_enabled(const FileSelectParams *params,
|
||||
FileAttributeColumnType column);
|
||||
|
@ -930,6 +930,7 @@ void FILE_OT_select_all(wmOperatorType *ot)
|
||||
|
||||
/* Note we could get rid of this one, but it's used by some addon so...
|
||||
* Does not hurt keeping it around for now. */
|
||||
/* TODO disallow bookmark editing in assets mode? */
|
||||
static int bookmark_select_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
@ -1836,10 +1837,6 @@ static int file_previous_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
|
||||
if (params) {
|
||||
if (!sfile->folders_next) {
|
||||
sfile->folders_next = folderlist_new();
|
||||
}
|
||||
|
||||
folderlist_pushdir(sfile->folders_next, params->dir);
|
||||
folderlist_popdir(sfile->folders_prev, params->dir);
|
||||
folderlist_pushdir(sfile->folders_next, params->dir);
|
||||
@ -1874,10 +1871,6 @@ static int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
if (params) {
|
||||
if (!sfile->folders_next) {
|
||||
sfile->folders_next = folderlist_new();
|
||||
}
|
||||
|
||||
folderlist_pushdir(sfile->folders_prev, params->dir);
|
||||
folderlist_popdir(sfile->folders_next, params->dir);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,7 @@ extern "C" {
|
||||
struct BlendHandle;
|
||||
struct FileList;
|
||||
struct FileSelection;
|
||||
struct FileSelectAssetLibraryUID;
|
||||
struct wmWindowManager;
|
||||
|
||||
struct FileDirEntry;
|
||||
@ -46,14 +47,16 @@ typedef enum FileCheckType {
|
||||
CHECK_ALL = 3,
|
||||
} FileCheckType;
|
||||
|
||||
struct ListBase *folderlist_new(void);
|
||||
void folderlist_free(struct ListBase *folderlist);
|
||||
struct ListBase *folderlist_duplicate(ListBase *folderlist);
|
||||
void folderlist_popdir(struct ListBase *folderlist, char *dir);
|
||||
void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
|
||||
const char *folderlist_peeklastdir(struct ListBase *folderlist);
|
||||
int folderlist_clear_next(struct SpaceFile *sfile);
|
||||
|
||||
void folder_history_list_ensure_for_active_browse_mode(struct SpaceFile *sfile);
|
||||
void folder_history_list_free(struct SpaceFile *sfile);
|
||||
struct ListBase folder_history_list_duplicate(struct ListBase *listbase);
|
||||
|
||||
void filelist_setsorting(struct FileList *filelist, const short sort, bool invert_sort);
|
||||
void filelist_sort(struct FileList *filelist);
|
||||
|
||||
@ -63,17 +66,22 @@ void filelist_setfilter_options(struct FileList *filelist,
|
||||
const bool hide_parent,
|
||||
const uint64_t filter,
|
||||
const uint64_t filter_id,
|
||||
const bool filter_assets_only,
|
||||
const char *filter_glob,
|
||||
const char *filter_search);
|
||||
void filelist_filter(struct FileList *filelist);
|
||||
void filelist_setlibrary(struct FileList *filelist,
|
||||
const struct FileSelectAssetLibraryUID *asset_library);
|
||||
|
||||
void filelist_init_icons(void);
|
||||
void filelist_free_icons(void);
|
||||
struct ImBuf *filelist_getimage(struct FileList *filelist, const int index);
|
||||
struct ImBuf *filelist_file_getimage(const FileDirEntry *file);
|
||||
struct ImBuf *filelist_geticon_image(struct FileList *filelist, const int index);
|
||||
int filelist_geticon(struct FileList *filelist, const int index, const bool is_main);
|
||||
|
||||
struct FileList *filelist_new(short type);
|
||||
void filelist_settype(struct FileList *filelist, short type);
|
||||
void filelist_clear(struct FileList *filelist);
|
||||
void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection);
|
||||
void filelist_free(struct FileList *filelist);
|
||||
@ -83,15 +91,18 @@ bool filelist_is_dir(struct FileList *filelist, const char *path);
|
||||
void filelist_setdir(struct FileList *filelist, char *r_dir);
|
||||
|
||||
int filelist_files_ensure(struct FileList *filelist);
|
||||
int filelist_empty(struct FileList *filelist);
|
||||
int filelist_needs_reading(struct FileList *filelist);
|
||||
FileDirEntry *filelist_file(struct FileList *filelist, int index);
|
||||
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]);
|
||||
void filelist_file_cache_slidingwindow_set(struct FileList *filelist, size_t window_size);
|
||||
bool filelist_file_cache_block(struct FileList *filelist, const int index);
|
||||
|
||||
bool filelist_force_reset(struct FileList *filelist);
|
||||
bool filelist_needs_force_reset(struct FileList *filelist);
|
||||
void filelist_tag_force_reset(struct FileList *filelist);
|
||||
bool filelist_pending(struct FileList *filelist);
|
||||
bool filelist_needs_reset_on_main_changes(const struct FileList *filelist);
|
||||
bool filelist_is_ready(struct FileList *filelist);
|
||||
|
||||
unsigned int filelist_entry_select_set(const struct FileList *filelist,
|
||||
|
@ -56,7 +56,9 @@
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_preferences.h"
|
||||
|
||||
#include "BLF_api.h"
|
||||
|
||||
@ -77,14 +79,66 @@
|
||||
|
||||
#define VERTLIST_MAJORCOLUMN_WIDTH (25 * UI_UNIT_X)
|
||||
|
||||
FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile)
|
||||
static void fileselect_initialize_params_common(SpaceFile *sfile, FileSelectParams *params)
|
||||
{
|
||||
if (!sfile) {
|
||||
/* Sometimes called in poll before space type was checked. */
|
||||
return NULL;
|
||||
const char *blendfile_path = BKE_main_blendfile_path_from_global();
|
||||
|
||||
/* operator has no setting for this */
|
||||
params->active_file = -1;
|
||||
|
||||
if (!params->dir[0]) {
|
||||
if (blendfile_path[0] != '\0') {
|
||||
BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir));
|
||||
}
|
||||
else {
|
||||
const char *doc_path = BKE_appdir_folder_default();
|
||||
if (doc_path) {
|
||||
BLI_strncpy(params->dir, doc_path, sizeof(params->dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sfile->params;
|
||||
folder_history_list_ensure_for_active_browse_mode(sfile);
|
||||
folderlist_pushdir(sfile->folders_prev, params->dir);
|
||||
|
||||
/* Switching thumbnails needs to recalc layout T28809. */
|
||||
if (sfile->layout) {
|
||||
sfile->layout->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void fileselect_ensure_updated_asset_params(SpaceFile *sfile)
|
||||
{
|
||||
BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_ASSETS);
|
||||
BLI_assert(sfile->op == NULL);
|
||||
|
||||
FileAssetSelectParams *asset_params = sfile->asset_params;
|
||||
|
||||
if (!asset_params) {
|
||||
asset_params = sfile->asset_params = MEM_callocN(sizeof(*asset_params),
|
||||
"FileAssetSelectParams");
|
||||
asset_params->base_params.details_flags = U_default.file_space_data.details_flags;
|
||||
asset_params->asset_library.type = FILE_ASSET_LIBRARY_LOCAL;
|
||||
}
|
||||
|
||||
FileSelectParams *base_params = &asset_params->base_params;
|
||||
base_params->file[0] = '\0';
|
||||
base_params->filter_glob[0] = '\0';
|
||||
/* TODO this way of using filters to form categories is notably slower than specifying a
|
||||
* "group" to read. That's because all types are read and filtering is applied afterwards. Would
|
||||
* be nice if we could lazy-read individual groups. */
|
||||
base_params->flag |= U_default.file_space_data.flag | FILE_ASSETS_ONLY | FILE_FILTER;
|
||||
base_params->flag &= ~FILE_DIRSEL_ONLY;
|
||||
base_params->filter |= FILE_TYPE_BLENDERLIB;
|
||||
base_params->filter_id = FILTER_ID_OB | FILTER_ID_GR;
|
||||
base_params->display = FILE_IMGDISPLAY;
|
||||
base_params->sort = FILE_SORT_ALPHA;
|
||||
base_params->recursion_level = 1;
|
||||
/* 'SMALL' size by default. More reasonable since this is typically used as regular editor,
|
||||
* space is more of an issue here. */
|
||||
base_params->thumbnail_size = 96;
|
||||
|
||||
fileselect_initialize_params_common(sfile, base_params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,6 +146,8 @@ FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile)
|
||||
* the previously used settings to be used here rather than overriding them */
|
||||
static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile)
|
||||
{
|
||||
BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_FILES);
|
||||
|
||||
FileSelectParams *params;
|
||||
wmOperator *op = sfile->op;
|
||||
|
||||
@ -297,42 +353,102 @@ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile)
|
||||
params->filter_glob[0] = '\0';
|
||||
}
|
||||
|
||||
/* operator has no setting for this */
|
||||
params->active_file = -1;
|
||||
|
||||
/* initialize the list with previous folders */
|
||||
if (!sfile->folders_prev) {
|
||||
sfile->folders_prev = folderlist_new();
|
||||
}
|
||||
|
||||
if (!params->dir[0]) {
|
||||
if (blendfile_path[0] != '\0') {
|
||||
BLI_split_dir_part(blendfile_path, params->dir, sizeof(params->dir));
|
||||
}
|
||||
else {
|
||||
const char *doc_path = BKE_appdir_folder_default();
|
||||
if (doc_path) {
|
||||
BLI_strncpy(params->dir, doc_path, sizeof(params->dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
folderlist_pushdir(sfile->folders_prev, params->dir);
|
||||
|
||||
/* Switching thumbnails needs to recalc layout T28809. */
|
||||
if (sfile->layout) {
|
||||
sfile->layout->dirty = true;
|
||||
}
|
||||
fileselect_initialize_params_common(sfile, params);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* If needed, create and return the file select parameters for the active browse mode.
|
||||
*/
|
||||
FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile)
|
||||
{
|
||||
if (!sfile->params) {
|
||||
fileselect_ensure_updated_file_params(sfile);
|
||||
switch ((eFileBrowse_Mode)sfile->browse_mode) {
|
||||
case FILE_BROWSE_MODE_FILES:
|
||||
if (!sfile->params) {
|
||||
fileselect_ensure_updated_file_params(sfile);
|
||||
}
|
||||
return sfile->params;
|
||||
case FILE_BROWSE_MODE_ASSETS:
|
||||
if (!sfile->asset_params) {
|
||||
fileselect_ensure_updated_asset_params(sfile);
|
||||
}
|
||||
return &sfile->asset_params->base_params;
|
||||
}
|
||||
return sfile->params;
|
||||
|
||||
BLI_assert(!"Invalid browse mode set in file space.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file select parameters for the active browse mode.
|
||||
*/
|
||||
FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile)
|
||||
{
|
||||
if (!sfile) {
|
||||
/* Sometimes called in poll before space type was checked. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch ((eFileBrowse_Mode)sfile->browse_mode) {
|
||||
case FILE_BROWSE_MODE_FILES:
|
||||
return sfile->params;
|
||||
case FILE_BROWSE_MODE_ASSETS:
|
||||
return (FileSelectParams *)sfile->asset_params;
|
||||
}
|
||||
|
||||
BLI_assert(!"Invalid browse mode set in file space.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FileSelectParams *ED_fileselect_get_file_params(const SpaceFile *sfile)
|
||||
{
|
||||
return (sfile->browse_mode == FILE_BROWSE_MODE_FILES) ? sfile->params : NULL;
|
||||
}
|
||||
|
||||
FileAssetSelectParams *ED_fileselect_get_asset_params(const SpaceFile *sfile)
|
||||
{
|
||||
return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) ? sfile->asset_params : NULL;
|
||||
}
|
||||
|
||||
static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params)
|
||||
{
|
||||
FileSelectAssetLibraryUID *library = &asset_params->asset_library;
|
||||
FileSelectParams *base_params = &asset_params->base_params;
|
||||
bUserAssetLibrary *user_library = NULL;
|
||||
|
||||
/* Ensure valid repo, or fall-back to local one. */
|
||||
if (library->type == FILE_ASSET_LIBRARY_CUSTOM) {
|
||||
user_library = BKE_preferences_asset_library_find_from_name(
|
||||
&U, library->custom_library_identifier);
|
||||
if (!user_library) {
|
||||
library->type = FILE_ASSET_LIBRARY_LOCAL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (library->type) {
|
||||
case FILE_ASSET_LIBRARY_LOCAL:
|
||||
base_params->dir[0] = '\0';
|
||||
break;
|
||||
case FILE_ASSET_LIBRARY_CUSTOM:
|
||||
BLI_assert(user_library);
|
||||
BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir));
|
||||
break;
|
||||
}
|
||||
base_params->type = (library->type == FILE_ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET : FILE_LOADLIB;
|
||||
}
|
||||
|
||||
void fileselect_refresh_params(SpaceFile *sfile)
|
||||
{
|
||||
FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
|
||||
if (asset_params) {
|
||||
fileselect_refresh_asset_params(asset_params);
|
||||
}
|
||||
}
|
||||
|
||||
bool ED_fileselect_is_asset_browser(const SpaceFile *sfile)
|
||||
{
|
||||
return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS);
|
||||
}
|
||||
|
||||
/* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA
|
||||
@ -371,6 +487,8 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile)
|
||||
wmOperator *op = sfile->op;
|
||||
UserDef_FileSpaceData *sfile_udata = &U.file_space_data;
|
||||
|
||||
BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_FILES);
|
||||
|
||||
FileSelectParams *params = fileselect_ensure_updated_file_params(sfile);
|
||||
if (!op) {
|
||||
return;
|
||||
@ -438,15 +556,6 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile,
|
||||
}
|
||||
}
|
||||
|
||||
void ED_fileselect_reset_params(SpaceFile *sfile)
|
||||
{
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
params->type = FILE_UNIX;
|
||||
params->flag = 0;
|
||||
params->title[0] = '\0';
|
||||
params->active_file = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets FileSelectParams->file (name of selected file)
|
||||
*/
|
||||
@ -1046,8 +1155,7 @@ void ED_fileselect_exit(wmWindowManager *wm, Scene *owner_scene, SpaceFile *sfil
|
||||
sfile->op = NULL;
|
||||
}
|
||||
|
||||
folderlist_free(sfile->folders_prev);
|
||||
folderlist_free(sfile->folders_next);
|
||||
folder_history_list_free(sfile);
|
||||
|
||||
if (sfile->files) {
|
||||
ED_fileselect_clear(wm, owner_scene, sfile);
|
||||
|
@ -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;
|
||||
}
|
||||
folder_history_list_free(sfile);
|
||||
|
||||
if (sfile->folders_next) {
|
||||
folderlist_free(sfile->folders_next);
|
||||
MEM_freeN(sfile->folders_next);
|
||||
sfile->folders_next = NULL;
|
||||
}
|
||||
|
||||
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->asset_params) {
|
||||
sfilen->asset_params = MEM_dupallocN(sfileo->asset_params);
|
||||
}
|
||||
|
||||
if (sfileo->folders_prev) {
|
||||
sfilen->folders_prev = folderlist_duplicate(sfileo->folders_prev);
|
||||
}
|
||||
|
||||
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 = ®ion->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");
|
||||
|
@ -664,6 +664,23 @@ typedef enum eSpaceSeq_OverlayType {
|
||||
/** \name File Selector
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Information to identify a asset library. May be either one of the predefined types (current
|
||||
* 'Main', builtin library, project library), or a custom type as defined in the Preferences.
|
||||
*
|
||||
* If the type is set to #FILE_ASSET_LIBRARY_CUSTOM, idname must have the name to identify the
|
||||
* custom library. Otherwise idname is not used.
|
||||
*/
|
||||
typedef struct FileSelectAssetLibraryUID {
|
||||
short type;
|
||||
char _pad[6];
|
||||
/**
|
||||
* If showing a custom asset library (#FILE_ASSET_LIBRARY_CUSTOM), this name has to be set to
|
||||
* define which. Can be empty otherwise.
|
||||
*/
|
||||
char custom_library_identifier[64]; /* MAX_NAME */
|
||||
} FileSelectAssetLibraryUID;
|
||||
|
||||
/* Config and Input for File Selector */
|
||||
typedef struct FileSelectParams {
|
||||
/** Title, also used for the text of the execute button. */
|
||||
@ -708,6 +725,7 @@ typedef struct FileSelectParams {
|
||||
/** Details toggles (file size, creation date, etc.) */
|
||||
char details_flags;
|
||||
char _pad2[3];
|
||||
|
||||
/** Filter when (flags & FILE_FILTER) is true. */
|
||||
int filter;
|
||||
|
||||
@ -723,6 +741,32 @@ typedef struct FileSelectParams {
|
||||
/* XXX --- end unused -- */
|
||||
} FileSelectParams;
|
||||
|
||||
/**
|
||||
* File selection parameters for asset browsing mode, with #FileSelectParams as base.
|
||||
*/
|
||||
typedef struct FileAssetSelectParams {
|
||||
FileSelectParams base_params;
|
||||
|
||||
FileSelectAssetLibraryUID asset_library;
|
||||
} FileAssetSelectParams;
|
||||
|
||||
/**
|
||||
* A wrapper to store previous and next folder lists (#FolderList) for a specific browse mode
|
||||
* (#eFileBrowse_Mode).
|
||||
*/
|
||||
typedef struct FileFolderHistory {
|
||||
struct FileFolderLists *next, *prev;
|
||||
|
||||
/** The browse mode this prev/next folder-lists are created for. */
|
||||
char browse_mode; /* eFileBrowse_Mode */
|
||||
char _pad[7];
|
||||
|
||||
/** Holds the list of previous directories to show. */
|
||||
ListBase folders_prev;
|
||||
/** Holds the list of next directories (pushed from previous) to show. */
|
||||
ListBase folders_next;
|
||||
} FileFolderHistory;
|
||||
|
||||
/* File Browser */
|
||||
typedef struct SpaceFile {
|
||||
SpaceLink *next, *prev;
|
||||
@ -733,20 +777,42 @@ typedef struct SpaceFile {
|
||||
char _pad0[6];
|
||||
/* End 'SpaceLink' header. */
|
||||
|
||||
char _pad1[4];
|
||||
/** Is this a File Browser or an Asset Browser? */
|
||||
char browse_mode; /* eFileBrowse_Mode */
|
||||
char _pad1[1];
|
||||
|
||||
short tags;
|
||||
|
||||
int scroll_offset;
|
||||
|
||||
/** Config and input for file select. */
|
||||
struct FileSelectParams *params;
|
||||
/** Config and input for file select. One for each browse-mode, to keep them independent. */
|
||||
FileSelectParams *params;
|
||||
FileAssetSelectParams *asset_params;
|
||||
|
||||
/** Holds the list of files to show. */
|
||||
void *_pad2;
|
||||
|
||||
/**
|
||||
* Holds the list of files to show.
|
||||
* Currently recreated when browse-mode changes. Could be per browse-mode to avoid refreshes.
|
||||
*/
|
||||
struct FileList *files;
|
||||
|
||||
/** Holds the list of previous directories to show. */
|
||||
/**
|
||||
* Holds the list of previous directories to show. Owned by `folder_histories` below.
|
||||
*/
|
||||
ListBase *folders_prev;
|
||||
/** Holds the list of next directories (pushed from previous) to show. */
|
||||
/**
|
||||
* Holds the list of next directories (pushed from previous) to show. Owned by
|
||||
* `folder_histories` below.
|
||||
*/
|
||||
ListBase *folders_next;
|
||||
|
||||
/**
|
||||
* This actually owns the prev/next folder-lists above. On browse-mode change, the lists of the
|
||||
* new mode get assigned to the above.
|
||||
*/
|
||||
ListBase folder_histories; /* FileFolderHistory */
|
||||
|
||||
/* operator that is invoking fileselect
|
||||
* op->exec() will be called on the 'Load' button.
|
||||
* if operator provides op->cancel(), then this will be invoked
|
||||
@ -763,6 +829,30 @@ typedef struct SpaceFile {
|
||||
short systemnr, system_bookmarknr;
|
||||
} SpaceFile;
|
||||
|
||||
/* SpaceFile.browse_mode (File Space Browsing Mode) */
|
||||
typedef enum eFileBrowse_Mode {
|
||||
/* Regular Blender File Browser */
|
||||
FILE_BROWSE_MODE_FILES = 0,
|
||||
/* Asset Browser */
|
||||
FILE_BROWSE_MODE_ASSETS = 1,
|
||||
} eFileBrowse_Mode;
|
||||
|
||||
typedef enum eFileAssetLibrary_Type {
|
||||
/* For the future. Display assets bundled with Blender by default. */
|
||||
// FILE_ASSET_LIBRARY_BUNDLED = 0,
|
||||
/** Display assets from the current session (current "Main"). */
|
||||
FILE_ASSET_LIBRARY_LOCAL = 1,
|
||||
/* For the future. Display assets for the current project. */
|
||||
// FILE_ASSET_LIBRARY_PROJECT = 2,
|
||||
|
||||
/** Display assets from custom asset libraries, as defined in the preferences
|
||||
* (#bUserAssetLibrary). The name will be taken from #FileSelectParams.asset_library.idname
|
||||
* then.
|
||||
* In RNA, we add the index of the custom library to this to identify it by index. So keep
|
||||
* this last! */
|
||||
FILE_ASSET_LIBRARY_CUSTOM = 100,
|
||||
} eFileAssetLibrary_Type;
|
||||
|
||||
/* FileSelectParams.display */
|
||||
enum eFileDisplayType {
|
||||
/** Internal (not exposed to users): Keep whatever display type was used during the last File
|
||||
@ -792,6 +882,13 @@ enum eFileSortType {
|
||||
FILE_SORT_SIZE = 4,
|
||||
};
|
||||
|
||||
/* SpaceFile.tags */
|
||||
enum eFileTags {
|
||||
/** Tag the space as having to update files representing or containing main data. Must be set
|
||||
* after file read and undo/redo. */
|
||||
FILE_TAG_REBUILD_MAIN_FILES = (1 << 0),
|
||||
};
|
||||
|
||||
/* FileSelectParams.details_flags */
|
||||
enum eFileDetails {
|
||||
FILE_DETAILS_SIZE = (1 << 0),
|
||||
@ -810,6 +907,7 @@ enum eFileDetails {
|
||||
typedef enum eFileSelectType {
|
||||
FILE_LOADLIB = 1,
|
||||
FILE_MAIN = 2,
|
||||
FILE_MAIN_ASSET = 3,
|
||||
|
||||
FILE_UNIX = 8,
|
||||
FILE_BLENDER = 8, /* don't display relative paths */
|
||||
@ -842,6 +940,7 @@ typedef enum eFileSel_Params_Flag {
|
||||
FILE_SORT_INVERT = (1 << 11),
|
||||
FILE_HIDE_TOOL_PROPS = (1 << 12),
|
||||
FILE_CHECK_EXISTING = (1 << 13),
|
||||
FILE_ASSETS_ONLY = (1 << 14),
|
||||
} eFileSel_Params_Flag;
|
||||
|
||||
/* sfile->params->rename_flag */
|
||||
@ -885,6 +984,7 @@ typedef enum eFileSel_File_Types {
|
||||
FILE_TYPE_USD = (1 << 18),
|
||||
FILE_TYPE_VOLUME = (1 << 19),
|
||||
|
||||
FILE_TYPE_ASSET = (1 << 28),
|
||||
/** An FS directory (i.e. S_ISDIR on its path is true). */
|
||||
FILE_TYPE_DIR = (1 << 30),
|
||||
FILE_TYPE_BLENDERLIB = (1u << 31),
|
||||
@ -985,9 +1085,16 @@ typedef struct FileDirEntry {
|
||||
/** Optional argument for shortcuts, aliases etc. */
|
||||
char *redirection_path;
|
||||
|
||||
/** TODO: make this a real ID pointer? */
|
||||
void *poin;
|
||||
struct ImBuf *image;
|
||||
/** When showing local IDs (FILE_MAIN, FILE_MAIN_ASSET), ID this file represents. Note comment
|
||||
* for FileListInternEntry.local_data, the same applies here! */
|
||||
ID *id;
|
||||
/** If this file represents an asset, its asset data is here. Note that we may show assets of
|
||||
* external files in which case this is set but not the id above.
|
||||
* Note comment for FileListInternEntry.local_data, the same applies here! */
|
||||
struct AssetMetaData *asset_data;
|
||||
|
||||
/* The icon_id for the preview image. */
|
||||
int preview_icon_id;
|
||||
|
||||
/* Tags are for info only, most of filtering is done in asset engine. */
|
||||
char **tags;
|
||||
|
@ -253,7 +253,9 @@ extern StructRNA RNA_FModifierPython;
|
||||
extern StructRNA RNA_FModifierStepped;
|
||||
extern StructRNA RNA_FaceMap;
|
||||
extern StructRNA RNA_FieldSettings;
|
||||
extern StructRNA RNA_FileAssetSelectParams;
|
||||
extern StructRNA RNA_FileBrowserFSMenuEntry;
|
||||
extern StructRNA RNA_FileSelectEntry;
|
||||
extern StructRNA RNA_FileSelectParams;
|
||||
extern StructRNA RNA_FloatAttribute;
|
||||
extern StructRNA RNA_FloatAttributeValue;
|
||||
|
@ -56,6 +56,7 @@ extern const EnumPropertyItem rna_enum_mesh_select_mode_items[];
|
||||
extern const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[];
|
||||
extern const EnumPropertyItem rna_enum_mesh_delimit_mode_items[];
|
||||
extern const EnumPropertyItem rna_enum_space_graph_mode_items[];
|
||||
extern const EnumPropertyItem rna_enum_space_file_browse_mode_items[];
|
||||
extern const EnumPropertyItem rna_enum_space_sequencer_view_type_items[];
|
||||
extern const EnumPropertyItem rna_enum_space_type_items[];
|
||||
extern const EnumPropertyItem rna_enum_space_image_mode_items[];
|
||||
|
@ -170,6 +170,12 @@ const EnumPropertyItem rna_enum_space_sequencer_view_type_items[] = {
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_space_file_browse_mode_items[] = {
|
||||
{FILE_BROWSE_MODE_FILES, "FILES", ICON_FILEBROWSER, "File Browser", ""},
|
||||
{FILE_BROWSE_MODE_ASSETS, "ASSETS", ICON_ASSET_MANAGER, "Asset Browser", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
#define SACT_ITEM_DOPESHEET \
|
||||
{ \
|
||||
SACTCONT_DOPESHEET, "DOPESHEET", ICON_ACTION, "Dope Sheet", "Edit all keyframes in scene" \
|
||||
@ -504,6 +510,7 @@ static const EnumPropertyItem rna_enum_curve_display_handle_items[] = {
|
||||
# include "BKE_layer.h"
|
||||
# include "BKE_nla.h"
|
||||
# include "BKE_paint.h"
|
||||
# include "BKE_preferences.h"
|
||||
# include "BKE_scene.h"
|
||||
# include "BKE_screen.h"
|
||||
# include "BKE_workspace.h"
|
||||
@ -2462,13 +2469,159 @@ static PointerRNA rna_FileSelectParams_filter_id_get(PointerRNA *ptr)
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_FileSelectIDFilter, ptr->data);
|
||||
}
|
||||
|
||||
static PointerRNA rna_FileBrowser_params_get(PointerRNA *ptr)
|
||||
static int rna_FileAssetSelectParams_asset_library_get(PointerRNA *ptr)
|
||||
{
|
||||
FileAssetSelectParams *params = ptr->data;
|
||||
/* Just an extra sanity check to ensure this isn't somehow called for RNA_FileSelectParams. */
|
||||
BLI_assert(ptr->type == &RNA_FileAssetSelectParams);
|
||||
|
||||
/* Simple case: Predefined repo, just set the value. */
|
||||
if (params->asset_library.type < FILE_ASSET_LIBRARY_CUSTOM) {
|
||||
return params->asset_library.type;
|
||||
}
|
||||
|
||||
/* Note that the path isn't checked for validity here. If an invalid library path is used, the
|
||||
* Asset Browser can give a nice hint on what's wrong. */
|
||||
const bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_name(
|
||||
&U, params->asset_library.custom_library_identifier);
|
||||
const int index = BKE_preferences_asset_library_get_index(&U, user_library);
|
||||
if (index > -1) {
|
||||
return FILE_ASSET_LIBRARY_CUSTOM + index;
|
||||
}
|
||||
|
||||
BLI_assert(0);
|
||||
return FILE_ASSET_LIBRARY_LOCAL;
|
||||
}
|
||||
|
||||
static void rna_FileAssetSelectParams_asset_library_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
FileAssetSelectParams *params = ptr->data;
|
||||
|
||||
/* Simple case: Predefined repo, just set the value. */
|
||||
if (value < FILE_ASSET_LIBRARY_CUSTOM) {
|
||||
params->asset_library.type = value;
|
||||
params->asset_library.custom_library_identifier[0] = '\0';
|
||||
BLI_assert(ELEM(value, FILE_ASSET_LIBRARY_LOCAL));
|
||||
return;
|
||||
}
|
||||
|
||||
const bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
|
||||
&U, value - FILE_ASSET_LIBRARY_CUSTOM);
|
||||
|
||||
/* Note that the path isn't checked for validity here. If an invalid library path is used, the
|
||||
* Asset Browser can give a nice hint on what's wrong. */
|
||||
const bool is_valid = (user_library->name[0] && user_library->path[0]);
|
||||
if (user_library && is_valid) {
|
||||
BLI_strncpy(params->asset_library.custom_library_identifier,
|
||||
user_library->name,
|
||||
sizeof(params->asset_library.custom_library_identifier));
|
||||
params->asset_library.type = FILE_ASSET_LIBRARY_CUSTOM;
|
||||
}
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *rna_FileAssetSelectParams_asset_library_itemf(
|
||||
bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
|
||||
{
|
||||
const EnumPropertyItem predefined_items[] = {
|
||||
/* For the future. */
|
||||
// {FILE_ASSET_REPO_BUNDLED, "BUNDLED", 0, "Bundled", "Show the default user assets"},
|
||||
{FILE_ASSET_LIBRARY_LOCAL,
|
||||
"LOCAL",
|
||||
ICON_BLENDER,
|
||||
"Current File",
|
||||
"Show the assets currently available in this Blender session"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
EnumPropertyItem *item = NULL;
|
||||
int totitem = 0;
|
||||
|
||||
/* Add separator if needed. */
|
||||
if (!BLI_listbase_is_empty(&U.asset_libraries)) {
|
||||
const EnumPropertyItem sepr = {0, "", 0, "Custom", NULL};
|
||||
RNA_enum_item_add(&item, &totitem, &sepr);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (bUserAssetLibrary *user_library = U.asset_libraries.first; user_library;
|
||||
user_library = user_library->next, i++) {
|
||||
/* Note that the path itself isn't checked for validity here. If an invalid library path is
|
||||
* used, the Asset Browser can give a nice hint on what's wrong. */
|
||||
const bool is_valid = (user_library->name[0] && user_library->path[0]);
|
||||
if (!is_valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Use library path as description, it's a nice hint for users. */
|
||||
EnumPropertyItem tmp = {FILE_ASSET_LIBRARY_CUSTOM + i,
|
||||
user_library->name,
|
||||
ICON_NONE,
|
||||
user_library->name,
|
||||
user_library->path};
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
}
|
||||
|
||||
if (totitem) {
|
||||
const EnumPropertyItem sepr = {0, "", 0, "Built-in", NULL};
|
||||
RNA_enum_item_add(&item, &totitem, &sepr);
|
||||
}
|
||||
|
||||
/* Add predefined items. */
|
||||
RNA_enum_items_add(&item, &totitem, predefined_items);
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*r_free = true;
|
||||
return item;
|
||||
}
|
||||
|
||||
static void rna_FileBrowser_FileSelectEntry_name_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
const FileDirEntry *entry = ptr->data;
|
||||
strcpy(value, entry->name);
|
||||
}
|
||||
|
||||
static int rna_FileBrowser_FileSelectEntry_name_length(PointerRNA *ptr)
|
||||
{
|
||||
const FileDirEntry *entry = ptr->data;
|
||||
return (int)strlen(entry->name);
|
||||
}
|
||||
|
||||
static int rna_FileBrowser_FileSelectEntry_preview_icon_id_get(PointerRNA *ptr)
|
||||
{
|
||||
const FileDirEntry *entry = ptr->data;
|
||||
return entry->preview_icon_id;
|
||||
}
|
||||
|
||||
static PointerRNA rna_FileBrowser_FileSelectEntry_asset_data_get(PointerRNA *ptr)
|
||||
{
|
||||
const FileDirEntry *entry = ptr->data;
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_AssetMetaData, entry->asset_data);
|
||||
}
|
||||
|
||||
static StructRNA *rna_FileBrowser_params_typef(PointerRNA *ptr)
|
||||
{
|
||||
SpaceFile *sfile = ptr->data;
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
|
||||
if (params) {
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_FileSelectParams, params);
|
||||
if (params == ED_fileselect_get_file_params(sfile)) {
|
||||
return &RNA_FileSelectParams;
|
||||
}
|
||||
if (params == (void *)ED_fileselect_get_asset_params(sfile)) {
|
||||
return &RNA_FileAssetSelectParams;
|
||||
}
|
||||
|
||||
BLI_assert(!"Could not identify file select parameters");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PointerRNA rna_FileBrowser_params_get(PointerRNA *ptr)
|
||||
{
|
||||
SpaceFile *sfile = ptr->data;
|
||||
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
|
||||
StructRNA *params_struct = rna_FileBrowser_params_typef(ptr);
|
||||
|
||||
if (params && params_struct) {
|
||||
return rna_pointer_inherit_refine(ptr, params_struct, params);
|
||||
}
|
||||
|
||||
return rna_pointer_inherit_refine(ptr, NULL, NULL);
|
||||
@ -2784,6 +2937,14 @@ static void rna_FileBrowser_FSMenuRecent_active_range(
|
||||
rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_RECENT);
|
||||
}
|
||||
|
||||
static void rna_SpaceFileBrowser_browse_mode_update(Main *UNUSED(bmain),
|
||||
Scene *UNUSED(scene),
|
||||
PointerRNA *ptr)
|
||||
{
|
||||
ScrArea *area = rna_area_from_space(ptr);
|
||||
ED_area_tag_refresh(area);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static const EnumPropertyItem dt_uv_items[] = {
|
||||
@ -5794,6 +5955,44 @@ static void rna_def_fileselect_idfilter(BlenderRNA *brna)
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_def_fileselect_entry(BlenderRNA *brna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
StructRNA *srna = RNA_def_struct(brna, "FileSelectEntry", NULL);
|
||||
RNA_def_struct_sdna(srna, "FileDirEntry");
|
||||
RNA_def_struct_ui_text(srna, "File Select Entry", "A file viewable in the File Browser");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(prop,
|
||||
"rna_FileBrowser_FileSelectEntry_name_get",
|
||||
"rna_FileBrowser_FileSelectEntry_name_length",
|
||||
NULL);
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
|
||||
prop = RNA_def_int(
|
||||
srna,
|
||||
"preview_icon_id",
|
||||
0,
|
||||
INT_MIN,
|
||||
INT_MAX,
|
||||
"Icon ID",
|
||||
"Unique integer identifying the preview of this file as an icon (zero means invalid)",
|
||||
INT_MIN,
|
||||
INT_MAX);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_int_funcs(
|
||||
prop, "rna_FileBrowser_FileSelectEntry_preview_icon_id_get", NULL, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "asset_data", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "AssetMetaData");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_FileBrowser_FileSelectEntry_asset_data_get", NULL, NULL, NULL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Asset Data", "Asset data, valid if the file represents an asset");
|
||||
}
|
||||
|
||||
static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -5966,6 +6165,12 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
RNA_def_property_ui_icon(prop, ICON_BLENDER, 0);
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_filter_asset_only", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_ASSETS_ONLY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Only Assets", "Hide .blend files items that are not data-blocks with asset metadata");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "filter_id", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
RNA_def_property_struct_type(prop, "FileSelectIDFilter");
|
||||
@ -5997,6 +6202,25 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_fileselect_asset_params(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "FileAssetSelectParams", "FileSelectParams");
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Asset Select Parameters", "Settings for the file selection in Asset Browser mode");
|
||||
|
||||
prop = RNA_def_property(srna, "asset_library", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, DummyRNA_NULL_items);
|
||||
RNA_def_property_enum_funcs(prop,
|
||||
"rna_FileAssetSelectParams_asset_library_get",
|
||||
"rna_FileAssetSelectParams_asset_library_set",
|
||||
"rna_FileAssetSelectParams_asset_library_itemf");
|
||||
RNA_def_property_ui_text(prop, "Asset Library", "");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_filemenu_entry(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -6050,9 +6274,18 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
|
||||
|
||||
rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_UI));
|
||||
|
||||
prop = RNA_def_property(srna, "browse_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_space_file_browse_mode_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Browsing Mode",
|
||||
"Type of the File Editor view (regular file browsing or asset browsing)");
|
||||
RNA_def_property_update(prop, 0, "rna_SpaceFileBrowser_browse_mode_update");
|
||||
|
||||
prop = RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "FileSelectParams");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_FileBrowser_params_get", NULL, NULL, NULL);
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_FileBrowser_params_get", NULL, "rna_FileBrowser_params_typef", NULL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser");
|
||||
|
||||
@ -6800,7 +7033,9 @@ void RNA_def_space(BlenderRNA *brna)
|
||||
rna_def_space_image(brna);
|
||||
rna_def_space_sequencer(brna);
|
||||
rna_def_space_text(brna);
|
||||
rna_def_fileselect_entry(brna);
|
||||
rna_def_fileselect_params(brna);
|
||||
rna_def_fileselect_asset_params(brna);
|
||||
rna_def_fileselect_idfilter(brna);
|
||||
rna_def_filemenu_entry(brna);
|
||||
rna_def_space_filebrowser(brna);
|
||||
|
@ -198,6 +198,8 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
|
||||
ot->srna, "filter_blenlib", (filter & FILE_TYPE_BLENDERLIB) != 0, "Filter Blender IDs", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
||||
/* TODO asset only filter? */
|
||||
|
||||
prop = RNA_def_int(
|
||||
ot->srna,
|
||||
"filemode",
|
||||
|
Loading…
Reference in New Issue
Block a user