diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2021-10-24 15:31:22 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2021-10-24 15:31:22 +0300 |
commit | 1aa953bd1913c81b22c80a00edbf4ad88a32c52f (patch) | |
tree | 7fa65e43d5a9bac6496555b723f37e0031e2737e /source/blender/editors/asset/intern/asset_ops.cc | |
parent | fc171c1be9da36485e892339b86dc8d4251914af (diff) | |
parent | 6ce383a9dfba5c49a48676c3a651804fde3dfe34 (diff) |
Merge branch 'master' into soc-2020-io-performance
Diffstat (limited to 'source/blender/editors/asset/intern/asset_ops.cc')
-rw-r--r-- | source/blender/editors/asset/intern/asset_ops.cc | 165 |
1 files changed, 126 insertions, 39 deletions
diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index bf532903c7c..e2ae3b3893b 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -18,10 +18,12 @@ * \ingroup edasset */ +#include "BKE_asset.h" #include "BKE_asset_catalog.hh" #include "BKE_asset_library.hh" #include "BKE_context.h" #include "BKE_lib_id.h" +#include "BKE_main.h" #include "BKE_report.h" #include "BLI_string_ref.hh" @@ -44,30 +46,6 @@ using namespace blender; using PointerRNAVec = blender::Vector<PointerRNA>; -static PointerRNAVec asset_operation_get_ids_from_context(const bContext *C); -static PointerRNAVec asset_operation_get_nonexperimental_ids_from_context(const bContext *C); -static bool asset_type_is_nonexperimental(const ID_Type id_type); - -static bool asset_operation_poll(bContext * /*C*/) -{ - /* At this moment only the pose library is non-experimental. Still, directly marking arbitrary - * Actions as asset is not part of the stable functionality; instead, the pose library "Create - * Pose Asset" operator should be used. Actions can still be marked as asset via - * `the_action.asset_mark()` (so a function call instead of this operator), which is what the - * pose library uses internally. */ - return U.experimental.use_extended_asset_browser; -} - -static bool asset_clear_poll(bContext *C) -{ - if (asset_operation_poll(C)) { - return true; - } - - PointerRNAVec pointers = asset_operation_get_nonexperimental_ids_from_context(C); - return !pointers.is_empty(); -} - /** * Return the IDs to operate on as PointerRNA vector. Either a single one ("id" context member) or * multiple ones ("selected_ids" context member). @@ -93,26 +71,51 @@ static PointerRNAVec asset_operation_get_ids_from_context(const bContext *C) return ids; } -static PointerRNAVec asset_operation_get_nonexperimental_ids_from_context(const bContext *C) +/** + * Information about what's contained in a #PointerRNAVec, returned by + * #asset_operation_get_id_vec_stats_from_context(). + */ +struct IDVecStats { + bool has_asset = false; + bool has_supported_type = false; + bool is_single = false; +}; + +/** + * Helper to report stats about the IDs in context. Operator polls use this, also to report a + * helpful disabled hint to the user. + */ +static IDVecStats asset_operation_get_id_vec_stats_from_context(const bContext *C) { - PointerRNAVec nonexperimental; PointerRNAVec pointers = asset_operation_get_ids_from_context(C); + IDVecStats stats; + + stats.is_single = pointers.size() == 1; + for (PointerRNA &ptr : pointers) { BLI_assert(RNA_struct_is_ID(ptr.type)); ID *id = static_cast<ID *>(ptr.data); - if (asset_type_is_nonexperimental(GS(id->name))) { - nonexperimental.append(ptr); + if (ED_asset_type_is_supported(id)) { + stats.has_supported_type = true; + } + if (ID_IS_ASSET(id)) { + stats.has_asset = true; } } - return nonexperimental; + + return stats; } -static bool asset_type_is_nonexperimental(const ID_Type id_type) +static const char *asset_operation_unsupported_type_msg(const bool is_single) { - /* At this moment only the pose library is non-experimental. For simplicity, allow asset - * operations on all Action datablocks (even though pose assets are limited to single frames). */ - return ELEM(id_type, ID_AC); + const char *msg_single = + "Data-block does not support asset operations - must be " + "a " ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING; + const char *msg_multiple = + "No data-block selected that supports asset operations - select at least " + "one " ED_ASSET_TYPE_IDS_NON_EXPERIMENTAL_UI_STRING; + return is_single ? msg_single : msg_multiple; } /* -------------------------------------------------------------------- */ @@ -145,7 +148,9 @@ void AssetMarkHelper::operator()(const bContext &C, PointerRNAVec &ids) continue; } - if (ED_asset_mark_id(&C, id)) { + if (ED_asset_mark_id(id)) { + ED_asset_generate_preview(&C, id); + stats.last_id = id; stats.tot_created++; } @@ -200,6 +205,18 @@ static int asset_mark_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static bool asset_mark_poll(bContext *C) +{ + IDVecStats ctx_stats = asset_operation_get_id_vec_stats_from_context(C); + + if (!ctx_stats.has_supported_type) { + CTX_wm_operator_poll_msg_set(C, asset_operation_unsupported_type_msg(ctx_stats.is_single)); + return false; + } + + return true; +} + static void ASSET_OT_mark(wmOperatorType *ot) { ot->name = "Mark as Asset"; @@ -209,7 +226,7 @@ static void ASSET_OT_mark(wmOperatorType *ot) ot->idname = "ASSET_OT_mark"; ot->exec = asset_mark_exec; - ot->poll = asset_operation_poll; + ot->poll = asset_mark_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } @@ -312,6 +329,24 @@ static int asset_clear_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static bool asset_clear_poll(bContext *C) +{ + IDVecStats ctx_stats = asset_operation_get_id_vec_stats_from_context(C); + + if (!ctx_stats.has_asset) { + const char *msg_single = "Data-block is not marked as asset"; + const char *msg_multiple = "No data-block selected that is marked as asset"; + CTX_wm_operator_poll_msg_set(C, ctx_stats.is_single ? msg_single : msg_multiple); + return false; + } + if (!ctx_stats.has_supported_type) { + CTX_wm_operator_poll_msg_set(C, asset_operation_unsupported_type_msg(ctx_stats.is_single)); + return false; + } + + return true; +} + static char *asset_clear_get_description(struct bContext *UNUSED(C), struct wmOperatorType *UNUSED(op), struct PointerRNA *values) @@ -383,7 +418,7 @@ static void ASSET_OT_list_refresh(struct wmOperatorType *ot) static bool asset_catalog_operator_poll(bContext *C) { const SpaceFile *sfile = CTX_wm_space_file(C); - return asset_operation_poll(C) && sfile && ED_fileselect_active_asset_library_get(sfile); + return sfile && ED_fileselect_active_asset_library_get(sfile); } static int asset_catalog_new_exec(bContext *C, wmOperator *op) @@ -396,7 +431,8 @@ static int asset_catalog_new_exec(bContext *C, wmOperator *op) MEM_freeN(parent_path); - WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr); + WM_event_add_notifier_ex( + CTX_wm_manager(C), CTX_wm_window(C), NC_ASSET | ND_ASSET_CATALOGS, nullptr); return OPERATOR_FINISHED; } @@ -434,7 +470,8 @@ static int asset_catalog_delete_exec(bContext *C, wmOperator *op) MEM_freeN(catalog_id_str); - WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr); + WM_event_add_notifier_ex( + CTX_wm_manager(C), CTX_wm_window(C), NC_ASSET | ND_ASSET_CATALOGS, nullptr); return OPERATOR_FINISHED; } @@ -458,7 +495,7 @@ static void ASSET_OT_catalog_delete(struct wmOperatorType *ot) static bke::AssetCatalogService *get_catalog_service(bContext *C) { const SpaceFile *sfile = CTX_wm_space_file(C); - if (!asset_operation_poll(C) || !sfile) { + if (!sfile) { return nullptr; } @@ -559,6 +596,55 @@ static void ASSET_OT_catalog_undo_push(struct wmOperatorType *ot) /* -------------------------------------------------------------------- */ +static bool asset_catalogs_save_poll(bContext *C) +{ + if (!asset_catalog_operator_poll(C)) { + return false; + } + + const Main *bmain = CTX_data_main(C); + if (!bmain->name[0]) { + CTX_wm_operator_poll_msg_set(C, "Cannot save asset catalogs before the Blender file is saved"); + return false; + } + + if (!BKE_asset_library_has_any_unsaved_catalogs()) { + CTX_wm_operator_poll_msg_set(C, "No changes to be saved"); + return false; + } + + return true; +} + +static int asset_catalogs_save_exec(bContext *C, wmOperator * /*op*/) +{ + const SpaceFile *sfile = CTX_wm_space_file(C); + ::AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile); + + ED_asset_catalogs_save_from_main_path(asset_library, CTX_data_main(C)); + + WM_event_add_notifier_ex( + CTX_wm_manager(C), CTX_wm_window(C), NC_ASSET | ND_ASSET_CATALOGS, nullptr); + + return OPERATOR_FINISHED; +} + +static void ASSET_OT_catalogs_save(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Save Asset Catalogs"; + ot->description = + "Make any edits to any catalogs permanent by writing the current set up to the asset " + "library"; + ot->idname = "ASSET_OT_catalogs_save"; + + /* api callbacks */ + ot->exec = asset_catalogs_save_exec; + ot->poll = asset_catalogs_save_poll; +} + +/* -------------------------------------------------------------------- */ + void ED_operatortypes_asset(void) { WM_operatortype_append(ASSET_OT_mark); @@ -566,6 +652,7 @@ void ED_operatortypes_asset(void) WM_operatortype_append(ASSET_OT_catalog_new); WM_operatortype_append(ASSET_OT_catalog_delete); + WM_operatortype_append(ASSET_OT_catalogs_save); WM_operatortype_append(ASSET_OT_catalog_undo); WM_operatortype_append(ASSET_OT_catalog_redo); WM_operatortype_append(ASSET_OT_catalog_undo_push); |