diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index b45a4a68392..145ea4e9e29 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -1581,7 +1581,6 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel): layout.prop(active_library, "path") layout.prop(active_library, "import_method", text="Import Method") layout.prop(active_library, "use_relative_path") - layout.prop(active_library, "is_default") class USERPREF_UL_asset_libraries(UIList): diff --git a/source/blender/editors/asset/intern/asset_menu_utils.cc b/source/blender/editors/asset/intern/asset_menu_utils.cc index f995c68e0e0..8f4ad604d17 100644 --- a/source/blender/editors/asset/intern/asset_menu_utils.cc +++ b/source/blender/editors/asset/intern/asset_menu_utils.cc @@ -89,7 +89,7 @@ static const asset_system::AssetRepresentation *get_local_asset_from_relative_id return matching_asset; } -static const asset_system::AssetRepresentation *find_asset_from_weak_ref( +const asset_system::AssetRepresentation *find_asset_from_weak_ref( const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports) { if (weak_ref.asset_library_type == ASSET_LIBRARY_LOCAL) { diff --git a/source/blender/editors/include/ED_asset_menu_utils.hh b/source/blender/editors/include/ED_asset_menu_utils.hh index 9ca3daa12e7..0021aca8a47 100644 --- a/source/blender/editors/include/ED_asset_menu_utils.hh +++ b/source/blender/editors/include/ED_asset_menu_utils.hh @@ -44,6 +44,9 @@ void operator_asset_reference_props_set(const asset_system::AssetRepresentation PointerRNA &ptr); void operator_asset_reference_props_register(StructRNA &srna); +const asset_system::AssetRepresentation *find_asset_from_weak_ref( + const bContext &C, const AssetWeakReference &weak_ref, ReportList *reports); + /** * Load all asset libraries to find an asset from the #operator_asset_reference_props_register * properties. The loading happens in the background, so there may be no result immediately. In diff --git a/source/blender/editors/sculpt_paint/paint_ops.cc b/source/blender/editors/sculpt_paint/paint_ops.cc index cea01e9a21b..4da234cd563 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_ops.cc @@ -788,19 +788,6 @@ static AssetWeakReference brush_asset_create_weakref_hack(const bUserAssetLibrar return asset_weak_ref; } -static const bUserAssetLibrary *brush_asset_get_default_library() -{ - if (BLI_listbase_is_empty(&U.asset_libraries)) { - return nullptr; - } - LISTBASE_FOREACH (const bUserAssetLibrary *, asset_library, &U.asset_libraries) { - if (asset_library->flag & ASSET_LIBRARY_DEFAULT) { - return asset_library; - } - } - return static_cast(U.asset_libraries.first); -} - static void refresh_asset_library(const bContext *C, const bUserAssetLibrary &user_library) { /* TODO: Should the all library reference be automatically cleared? */ @@ -827,6 +814,12 @@ static bool brush_asset_save_as_poll(bContext *C) if (paint == nullptr || brush == nullptr) { return false; } + if (!paint->brush_asset_reference) { + /* The brush should always be an imported asset. We use this asset reference to find + * which library and catalog the brush came from, as defaults for the popup. */ + BLI_assert_unreachable(); + return false; + } if (BLI_listbase_is_empty(&U.asset_libraries)) { CTX_wm_operator_poll_msg_set(C, "No asset library available to save to"); @@ -952,17 +945,74 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static std::optional library_to_library_ref( + const asset_system::AssetLibrary &library) +{ + for (const AssetLibraryReference &ref : asset_system::all_valid_asset_library_refs()) { + const std::string root_path = AS_asset_library_root_path_from_library_ref(ref); + /* Use #BLI_path_cmp_normalized because `library.root_path()` ends with a slash while + * `root_path` doesn't. */ + if (BLI_path_cmp_normalized(root_path.c_str(), library.root_path().c_str()) == 0) { + return ref; + } + } + return std::nullopt; +} + +static bool library_is_editable(const AssetLibraryReference &library) +{ + if (library.type == ASSET_LIBRARY_ESSENTIALS) { + return false; + } + return true; +} + static int brush_asset_save_as_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *brush = BKE_paint_brush(paint); + const AssetWeakReference &brush_weak_ref = *paint->brush_asset_reference; + const asset_system::AssetRepresentation *asset = asset::find_asset_from_weak_ref( + *C, brush_weak_ref, op->reports); + if (!asset) { + BLI_assert_unreachable(); + return OPERATOR_CANCELLED; + } + const asset_system::AssetLibrary &library = asset->owner_asset_library(); + const std::optional library_ref = library_to_library_ref(library); + if (!library_ref) { + BLI_assert_unreachable(); + return OPERATOR_CANCELLED; + } RNA_string_set(op->ptr, "name", brush->id.name + 2); - if (const bUserAssetLibrary *library = brush_asset_get_default_library()) { - const AssetLibraryReference library_ref = user_library_to_library_ref(*library); - const int enum_value = asset::library_reference_to_enum_value(&library_ref); - RNA_enum_set(op->ptr, "asset_library_reference", enum_value); + /* If the library isn't saved from the operator's last execution, find the current library or the + * first library if the current library isn't editable. */ + if (!RNA_struct_property_is_set_ex(op->ptr, "asset_library_reference", false)) { + if (library_is_editable(*library_ref)) { + RNA_enum_set(op->ptr, + "asset_library_reference", + asset::library_reference_to_enum_value(&*library_ref)); + } + else { + const AssetLibraryReference first_library = user_library_to_library_ref( + *static_cast(U.asset_libraries.first)); + RNA_enum_set(op->ptr, + "asset_library_reference", + asset::library_reference_to_enum_value(&first_library)); + } + } + + /* By default, put the new asset in the same catalog as the existing asset. */ + if (!RNA_struct_property_is_set(op->ptr, "catalog_path")) { + const asset_system::CatalogID catalog_id = asset->get_metadata().catalog_id; + const asset_system::AssetCatalog *catalog = library.catalog_service().find_catalog(catalog_id); + if (catalog == nullptr) { + BLI_assert_unreachable(); + return OPERATOR_CANCELLED; + } + RNA_string_set(op->ptr, "catalog_path", catalog->path.c_str()); } return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Save")); @@ -990,6 +1040,7 @@ static void visit_asset_catalog_for_search_fn( const char *edit_text, FunctionRef visit_fn) { + /* NOTE: Using the all library would also be a valid choice. */ const bUserAssetLibrary *user_library = get_asset_library_from_prop(*ptr); if (!user_library) { return; diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h index 7d23ad76475..5ae7c074772 100644 --- a/source/blender/makesdna/DNA_asset_types.h +++ b/source/blender/makesdna/DNA_asset_types.h @@ -117,7 +117,6 @@ typedef enum eAssetImportMethod { typedef enum eAssetLibrary_Flag { ASSET_LIBRARY_RELATIVE_PATH = (1 << 0), - ASSET_LIBRARY_DEFAULT = (1 << 1), } eAssetLibrary_Flag; /** diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index 3b47c079bd6..ebea4b45dab 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -361,18 +361,6 @@ static void rna_userdef_asset_library_path_set(PointerRNA *ptr, const char *valu BKE_preferences_asset_library_path_set(library, value); } -static void rna_UserAssetLibrary_is_default_set(PointerRNA *ptr, bool value) -{ - bUserAssetLibrary *library = static_cast(ptr->data); - if (!value) { - return; - } - LISTBASE_FOREACH (bUserAssetLibrary *, library_iter, &U.asset_libraries) { - library_iter->flag &= ~ASSET_LIBRARY_DEFAULT; - } - library->flag |= ASSET_LIBRARY_DEFAULT; -} - static void rna_userdef_extension_repo_name_set(PointerRNA *ptr, const char *value) { bUserExtensionRepo *repo = (bUserExtensionRepo *)ptr->data; @@ -6618,11 +6606,6 @@ static void rna_def_userdef_filepaths_asset_library(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, nullptr, "flag", ASSET_LIBRARY_RELATIVE_PATH); RNA_def_property_ui_text( prop, "Relative Path", "Use relative path when linking assets from this asset library"); - - prop = RNA_def_property(srna, "is_default", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, nullptr, "flag", ASSET_LIBRARY_DEFAULT); - RNA_def_property_boolean_funcs(prop, nullptr, "rna_UserAssetLibrary_is_default_set"); - RNA_def_property_ui_text(prop, "Default", "Use this library for saving new assets"); } static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)