diff --git a/scripts/startup/bl_ui/properties_paint_common.py b/scripts/startup/bl_ui/properties_paint_common.py index 2b6189015f7..6ea6cbc261c 100644 --- a/scripts/startup/bl_ui/properties_paint_common.py +++ b/scripts/startup/bl_ui/properties_paint_common.py @@ -6,7 +6,7 @@ from bpy.types import Menu class BrushAssetShelf: - bl_options = {'DEFAULT_VISIBLE', 'NO_ASSET_DRAG'} + bl_options = {'DEFAULT_VISIBLE', 'NO_ASSET_DRAG', 'STORE_ENABLED_CATALOGS_IN_PREFERENCES'} bl_default_preview_size = 48 @classmethod diff --git a/source/blender/blenkernel/BKE_asset.hh b/source/blender/blenkernel/BKE_asset.hh index a98a157384d..0b6eda3345c 100644 --- a/source/blender/blenkernel/BKE_asset.hh +++ b/source/blender/blenkernel/BKE_asset.hh @@ -78,3 +78,13 @@ void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data) void BKE_asset_weak_reference_write(BlendWriter *writer, const AssetWeakReference *weak_ref); void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference *weak_ref); + +void BKE_asset_catalog_path_list_free(ListBase &catalog_path_list); +ListBase BKE_asset_catalog_path_list_duplicate(const ListBase &catalog_path_list); +void BKE_asset_catalog_path_list_blend_write(BlendWriter *writer, + const ListBase &catalog_path_list); +void BKE_asset_catalog_path_list_blend_read_data(BlendDataReader *reader, + ListBase &catalog_path_list); +bool BKE_asset_catalog_path_list_has_path(const ListBase &catalog_path_list, + const char *catalog_path); +void BKE_asset_catalog_path_list_add_path(ListBase &catalog_path_list, const char *catalog_path); diff --git a/source/blender/blenkernel/BKE_preferences.h b/source/blender/blenkernel/BKE_preferences.h index 4f788637845..7238a07fd5c 100644 --- a/source/blender/blenkernel/BKE_preferences.h +++ b/source/blender/blenkernel/BKE_preferences.h @@ -18,6 +18,7 @@ extern "C" { struct UserDef; struct bUserExtensionRepo; struct bUserAssetLibrary; +struct bUserAssetShelfSettings; /* -------------------------------------------------------------------- */ /** \name Assert Libraries @@ -122,6 +123,27 @@ int BKE_preferences_extension_repo_get_index(const UserDef *userdef, /** \} */ +/* -------------------------------------------------------------------- */ +/** \name #bUserAssetShelvesSettings + * \{ */ + +bUserAssetShelfSettings *BKE_preferences_asset_shelf_settings_get(const UserDef *userdef, + const char *shelf_idname); +bool BKE_preferences_asset_shelf_settings_is_catalog_path_enabled(const UserDef *userdef, + const char *shelf_idname, + const char *catalog_path); +/** + * Enable a catalog path for a asset shelf identified by \a shelf_idname. Will create the shelf + * settings in the Preferences if necessary. + * \return Return true if the catalog was newly enabled. The Preferences should be tagged as dirty + * then. + */ +bool BKE_preferences_asset_shelf_settings_ensure_catalog_path_enabled(UserDef *userdef, + const char *shelf_idname, + const char *catalog_path); + +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_screen.hh b/source/blender/blenkernel/BKE_screen.hh index 90bae65272f..b499618c286 100644 --- a/source/blender/blenkernel/BKE_screen.hh +++ b/source/blender/blenkernel/BKE_screen.hh @@ -523,6 +523,7 @@ enum AssetShelfTypeFlag { * keymap items then. */ ASSET_SHELF_TYPE_FLAG_NO_ASSET_DRAG = (1 << 0), ASSET_SHELF_TYPE_FLAG_DEFAULT_VISIBLE = (1 << 1), + ASSET_SHELF_TYPE_FLAG_STORE_CATALOGS_IN_PREFS = (1 << 2), ASSET_SHELF_TYPE_FLAG_MAX }; diff --git a/source/blender/blenkernel/intern/asset_weak_reference.cc b/source/blender/blenkernel/intern/asset_weak_reference.cc index 95e979251c1..89447e719e7 100644 --- a/source/blender/blenkernel/intern/asset_weak_reference.cc +++ b/source/blender/blenkernel/intern/asset_weak_reference.cc @@ -118,3 +118,58 @@ void BKE_asset_weak_reference_read(BlendDataReader *reader, AssetWeakReference * BLO_read_string(reader, &weak_ref->asset_library_identifier); BLO_read_string(reader, &weak_ref->relative_asset_identifier); } + +void BKE_asset_catalog_path_list_free(ListBase &catalog_path_list) +{ + LISTBASE_FOREACH_MUTABLE (AssetCatalogPathLink *, catalog_path, &catalog_path_list) { + MEM_delete(catalog_path->path); + BLI_freelinkN(&catalog_path_list, catalog_path); + } + BLI_assert(BLI_listbase_is_empty(&catalog_path_list)); +} + +ListBase BKE_asset_catalog_path_list_duplicate(const ListBase &catalog_path_list) +{ + ListBase duplicated_list = {nullptr}; + + LISTBASE_FOREACH (AssetCatalogPathLink *, catalog_path, &catalog_path_list) { + AssetCatalogPathLink *copied_path = MEM_cnew(__func__); + copied_path->path = BLI_strdup(catalog_path->path); + + BLI_addtail(&duplicated_list, copied_path); + } + + return duplicated_list; +} + +void BKE_asset_catalog_path_list_blend_write(BlendWriter *writer, + const ListBase &catalog_path_list) +{ + LISTBASE_FOREACH (const AssetCatalogPathLink *, catalog_path, &catalog_path_list) { + BLO_write_struct(writer, AssetCatalogPathLink, catalog_path); + BLO_write_string(writer, catalog_path->path); + } +} + +void BKE_asset_catalog_path_list_blend_read_data(BlendDataReader *reader, + ListBase &catalog_path_list) +{ + BLO_read_struct_list(reader, AssetCatalogPathLink, &catalog_path_list); + LISTBASE_FOREACH (AssetCatalogPathLink *, catalog_path, &catalog_path_list) { + BLO_read_data_address(reader, &catalog_path->path); + } +} + +bool BKE_asset_catalog_path_list_has_path(const ListBase &catalog_path_list, + const char *catalog_path) +{ + return BLI_findstring_ptr( + &catalog_path_list, catalog_path, offsetof(AssetCatalogPathLink, path)) != nullptr; +} + +void BKE_asset_catalog_path_list_add_path(ListBase &catalog_path_list, const char *catalog_path) +{ + AssetCatalogPathLink *new_path = MEM_cnew(__func__); + new_path->path = BLI_strdup(catalog_path); + BLI_addtail(&catalog_path_list, new_path); +} diff --git a/source/blender/blenkernel/intern/blender.cc b/source/blender/blenkernel/intern/blender.cc index 24841cae1b7..21e554ae367 100644 --- a/source/blender/blenkernel/intern/blender.cc +++ b/source/blender/blenkernel/intern/blender.cc @@ -22,6 +22,7 @@ #include "IMB_moviecache.hh" #include "BKE_addon.h" +#include "BKE_asset.hh" #include "BKE_blender.hh" /* own include */ #include "BKE_blender_user_menu.hh" /* own include */ #include "BKE_blender_version.h" /* own include */ @@ -340,6 +341,12 @@ void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts) BLI_freelistN(&userdef->script_directories); BLI_freelistN(&userdef->asset_libraries); BLI_freelistN(&userdef->extension_repos); + LISTBASE_FOREACH_MUTABLE (bUserAssetShelfSettings *, settings, &userdef->asset_shelves_settings) + { + BKE_asset_catalog_path_list_free(settings->enabled_catalog_paths); + MEM_freeN(settings); + } + BLI_listbase_clear(&userdef->asset_shelves_settings); BLI_freelistN(&userdef->uistyles); BLI_freelistN(&userdef->uifonts); diff --git a/source/blender/blenkernel/intern/preferences.cc b/source/blender/blenkernel/intern/preferences.cc index 14d8b784893..f7f0e36d288 100644 --- a/source/blender/blenkernel/intern/preferences.cc +++ b/source/blender/blenkernel/intern/preferences.cc @@ -20,10 +20,12 @@ #include "BLI_string_utils.hh" #include "BKE_appdir.hh" +#include "BKE_asset.hh" #include "BKE_preferences.h" #include "BLT_translation.hh" +#include "DNA_asset_types.h" #include "DNA_defaults.h" #include "DNA_userdef_types.h" @@ -399,5 +401,67 @@ int BKE_preferences_extension_repo_get_index(const UserDef *userdef, { return BLI_findindex(&userdef->extension_repos, repo); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #bUserAssetShelfSettings + * \{ */ + +static bUserAssetShelfSettings *asset_shelf_settings_new(UserDef *userdef, + const char *shelf_idname) +{ + bUserAssetShelfSettings *settings = DNA_struct_default_alloc(bUserAssetShelfSettings); + BLI_addtail(&userdef->asset_shelves_settings, settings); + STRNCPY(settings->shelf_idname, shelf_idname); + BLI_assert(BLI_listbase_is_empty(&settings->enabled_catalog_paths)); + return settings; +} + +static bUserAssetShelfSettings *asset_shelf_settings_ensure(UserDef *userdef, + const char *shelf_idname) +{ + if (bUserAssetShelfSettings *settings = BKE_preferences_asset_shelf_settings_get(userdef, + shelf_idname)) + { + return settings; + } + return asset_shelf_settings_new(userdef, shelf_idname); +} + +bUserAssetShelfSettings *BKE_preferences_asset_shelf_settings_get(const UserDef *userdef, + const char *shelf_idname) +{ + return static_cast( + BLI_findstring(&userdef->asset_shelves_settings, + shelf_idname, + offsetof(bUserAssetShelfSettings, shelf_idname))); +} + +bool BKE_preferences_asset_shelf_settings_is_catalog_path_enabled(const UserDef *userdef, + const char *shelf_idname, + const char *catalog_path) +{ + const bUserAssetShelfSettings *settings = BKE_preferences_asset_shelf_settings_get(userdef, + shelf_idname); + if (!settings) { + return false; + } + return BKE_asset_catalog_path_list_has_path(settings->enabled_catalog_paths, catalog_path); +} + +bool BKE_preferences_asset_shelf_settings_ensure_catalog_path_enabled(UserDef *userdef, + const char *shelf_idname, + const char *catalog_path) +{ + if (BKE_preferences_asset_shelf_settings_is_catalog_path_enabled( + userdef, shelf_idname, catalog_path)) + { + return false; + } + + bUserAssetShelfSettings *settings = asset_shelf_settings_ensure(userdef, shelf_idname); + BKE_asset_catalog_path_list_add_path(settings->enabled_catalog_paths, catalog_path); + return true; +} /** \} */ diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index a9fa0582f46..ae5b5ee21f8 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3376,6 +3376,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) BLO_read_struct_list(reader, bUserScriptDirectory, &user->script_directories); BLO_read_struct_list(reader, bUserAssetLibrary, &user->asset_libraries); BLO_read_struct_list(reader, bUserExtensionRepo, &user->extension_repos); + BLO_read_struct_list(reader, bUserAssetShelfSettings, &user->asset_shelves_settings); LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) { keymap->modal_items = nullptr; @@ -3423,6 +3424,10 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) IDP_BlendDataRead(reader, &addon->prop); } + LISTBASE_FOREACH (bUserAssetShelfSettings *, shelf_settings, &user->asset_shelves_settings) { + BKE_asset_catalog_path_list_blend_read_data(reader, shelf_settings->enabled_catalog_paths); + } + /* XXX */ user->uifonts.first = user->uifonts.last = nullptr; diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index 768c72717da..bfa31405a0a 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -100,6 +100,7 @@ #include "MEM_guardedalloc.h" /* MEM_freeN */ +#include "BKE_asset.hh" #include "BKE_blender_version.h" #include "BKE_bpath.hh" #include "BKE_global.hh" /* For #Global `G`. */ @@ -934,6 +935,12 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef) LISTBASE_FOREACH (const bUserExtensionRepo *, repo_ref, &userdef->extension_repos) { BLO_write_struct(writer, bUserExtensionRepo, repo_ref); } + LISTBASE_FOREACH ( + const bUserAssetShelfSettings *, shelf_settings, &userdef->asset_shelves_settings) + { + BLO_write_struct(writer, bUserAssetShelfSettings, shelf_settings); + BKE_asset_catalog_path_list_blend_write(writer, shelf_settings->enabled_catalog_paths); + } LISTBASE_FOREACH (const uiStyle *, style, &userdef->uistyles) { BLO_write_struct(writer, uiStyle, style); diff --git a/source/blender/editors/asset/intern/asset_shelf.cc b/source/blender/editors/asset/intern/asset_shelf.cc index 54c966cca73..dc8cf578cdc 100644 --- a/source/blender/editors/asset/intern/asset_shelf.cc +++ b/source/blender/editors/asset/intern/asset_shelf.cc @@ -680,9 +680,10 @@ static uiBut *add_tab_button(uiBlock &block, StringRefNull name) return but; } -static void add_catalog_tabs(AssetShelfSettings &shelf_settings, uiLayout &layout) +static void add_catalog_tabs(AssetShelf &shelf, uiLayout &layout) { uiBlock *block = uiLayoutGetBlock(&layout); + AssetShelfSettings &shelf_settings = shelf.settings; /* "All" tab. */ { @@ -699,18 +700,17 @@ static void add_catalog_tabs(AssetShelfSettings &shelf_settings, uiLayout &layou uiItemS(&layout); /* Regular catalog tabs. */ - settings_foreach_enabled_catalog_path( - shelf_settings, [&](const asset_system::AssetCatalogPath &path) { - uiBut *but = add_tab_button(*block, path.name()); + settings_foreach_enabled_catalog_path(shelf, [&](const asset_system::AssetCatalogPath &path) { + uiBut *but = add_tab_button(*block, path.name()); - UI_but_func_set(but, [&shelf_settings, path](bContext &C) { - settings_set_active_catalog(shelf_settings, path); - send_redraw_notifier(C); - }); - UI_but_func_pushed_state_set(but, [&shelf_settings, path](const uiBut &) -> bool { - return settings_is_active_catalog(shelf_settings, path); - }); - }); + UI_but_func_set(but, [&shelf_settings, path](bContext &C) { + settings_set_active_catalog(shelf_settings, path); + send_redraw_notifier(C); + }); + UI_but_func_pushed_state_set(but, [&shelf_settings, path](const uiBut &) -> bool { + return settings_is_active_catalog(shelf_settings, path); + }); + }); } /** \} */ @@ -737,7 +737,7 @@ static void asset_shelf_header_draw(const bContext *C, Header *header) PointerRNA shelf_ptr = active_shelf_ptr_from_context(C); if (AssetShelf *shelf = static_cast(shelf_ptr.data)) { - add_catalog_tabs(shelf->settings, *layout); + add_catalog_tabs(*shelf, *layout); } uiItemSpacer(layout); diff --git a/source/blender/editors/asset/intern/asset_shelf.hh b/source/blender/editors/asset/intern/asset_shelf.hh index 56185db3fc4..ceea9358613 100644 --- a/source/blender/editors/asset/intern/asset_shelf.hh +++ b/source/blender/editors/asset/intern/asset_shelf.hh @@ -11,12 +11,16 @@ #include "BLI_function_ref.hh" struct ARegion; +struct ARegionType; struct AssetLibraryReference; struct AssetShelf; +struct AssetShelfType; struct AssetShelfSettings; struct bContext; struct BlendDataReader; struct BlendWriter; +struct RegionAssetShelf; +struct SpaceType; struct uiLayout; namespace blender::asset_system { @@ -55,20 +59,24 @@ void regiondata_blend_read_data(BlendDataReader *reader, RegionAssetShelf **shel void settings_blend_write(BlendWriter *writer, const AssetShelfSettings &settings); void settings_blend_read_data(BlendDataReader *reader, AssetShelfSettings &settings); -void settings_clear_enabled_catalogs(AssetShelfSettings &settings); void settings_set_active_catalog(AssetShelfSettings &settings, const asset_system::AssetCatalogPath &path); void settings_set_all_catalog_active(AssetShelfSettings &settings); bool settings_is_active_catalog(const AssetShelfSettings &settings, const asset_system::AssetCatalogPath &path); bool settings_is_all_catalog_active(const AssetShelfSettings &settings); -bool settings_is_catalog_path_enabled(const AssetShelfSettings &settings, +/** + * Clears the list of enabled catalogs in either the Preferences (if any) or the asset shelf + * settings (if any), depending on the #ASSET_SHELF_TYPE_FLAG_STORE_CATALOGS_IN_PREFS flag. + */ +void settings_clear_enabled_catalogs(AssetShelf &shelf); +bool settings_is_catalog_path_enabled(const AssetShelf &shelf, const asset_system::AssetCatalogPath &path); -void settings_set_catalog_path_enabled(AssetShelfSettings &settings, +void settings_set_catalog_path_enabled(AssetShelf &shelf, const asset_system::AssetCatalogPath &path); void settings_foreach_enabled_catalog_path( - const AssetShelfSettings &settings, + const AssetShelf &shelf, FunctionRef fn); } // namespace blender::ed::asset::shelf diff --git a/source/blender/editors/asset/intern/asset_shelf_catalog_selector.cc b/source/blender/editors/asset/intern/asset_shelf_catalog_selector.cc index da9e3b18958..9446f75cb2e 100644 --- a/source/blender/editors/asset/intern/asset_shelf_catalog_selector.cc +++ b/source/blender/editors/asset/intern/asset_shelf_catalog_selector.cc @@ -73,7 +73,7 @@ class AssetCatalogSelectorTree : public ui::AbstractTreeView { Item &build_catalog_items_recursive(ui::TreeViewOrItem &parent_view_item, const asset_system::AssetCatalogTreeItem &catalog_item) const { - Item &view_item = parent_view_item.add_tree_item(catalog_item, shelf_settings_); + Item &view_item = parent_view_item.add_tree_item(catalog_item, shelf_); catalog_item.foreach_child( [&view_item, this](const asset_system::AssetCatalogTreeItem &child) { @@ -92,12 +92,11 @@ class AssetCatalogSelectorTree : public ui::AbstractTreeView { char catalog_path_enabled_ = false; public: - Item(const asset_system::AssetCatalogTreeItem &catalog_item, - AssetShelfSettings &shelf_settings) + Item(const asset_system::AssetCatalogTreeItem &catalog_item, AssetShelf &shelf) : ui::BasicTreeViewItem(catalog_item.get_name()), catalog_item_(catalog_item), catalog_path_enabled_( - settings_is_catalog_path_enabled(shelf_settings, catalog_item.catalog_path())) + settings_is_catalog_path_enabled(shelf, catalog_item.catalog_path())) { disable_activatable(); } @@ -166,11 +165,11 @@ class AssetCatalogSelectorTree : public ui::AbstractTreeView { void AssetCatalogSelectorTree::update_shelf_settings_from_enabled_catalogs() { - settings_clear_enabled_catalogs(shelf_settings_); + settings_clear_enabled_catalogs(shelf_); foreach_item([this](ui::AbstractTreeViewItem &view_item) { const auto &selector_tree_item = dynamic_cast(view_item); if (selector_tree_item.is_catalog_path_enabled()) { - settings_set_catalog_path_enabled(shelf_settings_, selector_tree_item.catalog_path()); + settings_set_catalog_path_enabled(shelf_, selector_tree_item.catalog_path()); } }); } diff --git a/source/blender/editors/asset/intern/asset_shelf_settings.cc b/source/blender/editors/asset/intern/asset_shelf_settings.cc index 6368d48953d..5d39ec5313c 100644 --- a/source/blender/editors/asset/intern/asset_shelf_settings.cc +++ b/source/blender/editors/asset/intern/asset_shelf_settings.cc @@ -20,6 +20,10 @@ #include "BLI_string.h" #include "BLI_string_ref.hh" +#include "BKE_asset.hh" +#include "BKE_preferences.h" +#include "BKE_screen.hh" + #include "asset_shelf.hh" using namespace blender; @@ -45,18 +49,15 @@ AssetShelfSettings &AssetShelfSettings::operator=(const AssetShelfSettings &othe if (active_catalog_path) { active_catalog_path = BLI_strdup(other.active_catalog_path); } - BLI_listbase_clear(&enabled_catalog_paths); + BKE_asset_catalog_path_list_free(enabled_catalog_paths); + enabled_catalog_paths = BKE_asset_catalog_path_list_duplicate(other.enabled_catalog_paths); - LISTBASE_FOREACH (LinkData *, catalog_path_item, &other.enabled_catalog_paths) { - LinkData *new_path_item = BLI_genericNodeN(BLI_strdup((char *)catalog_path_item->data)); - BLI_addtail(&enabled_catalog_paths, new_path_item); - } return *this; } AssetShelfSettings::~AssetShelfSettings() { - shelf::settings_clear_enabled_catalogs(*this); + BKE_asset_catalog_path_list_free(enabled_catalog_paths); MEM_delete(active_catalog_path); } @@ -66,32 +67,16 @@ void settings_blend_write(BlendWriter *writer, const AssetShelfSettings &setting { BLO_write_struct(writer, AssetShelfSettings, &settings); - LISTBASE_FOREACH (LinkData *, catalog_path_item, &settings.enabled_catalog_paths) { - BLO_write_struct(writer, LinkData, catalog_path_item); - BLO_write_string(writer, (const char *)catalog_path_item->data); - } - + BKE_asset_catalog_path_list_blend_write(writer, settings.enabled_catalog_paths); BLO_write_string(writer, settings.active_catalog_path); } void settings_blend_read_data(BlendDataReader *reader, AssetShelfSettings &settings) { - BLO_read_struct_list(reader, LinkData, &settings.enabled_catalog_paths); - LISTBASE_FOREACH (LinkData *, catalog_path_item, &settings.enabled_catalog_paths) { - BLO_read_string(reader, reinterpret_cast(&catalog_path_item->data)); - } + BKE_asset_catalog_path_list_blend_read_data(reader, settings.enabled_catalog_paths); BLO_read_string(reader, &settings.active_catalog_path); } -void settings_clear_enabled_catalogs(AssetShelfSettings &settings) -{ - LISTBASE_FOREACH_MUTABLE (LinkData *, catalog_path_item, &settings.enabled_catalog_paths) { - MEM_freeN(catalog_path_item->data); - BLI_freelinkN(&settings.enabled_catalog_paths, catalog_path_item); - } - BLI_assert(BLI_listbase_is_empty(&settings.enabled_catalog_paths)); -} - void settings_set_active_catalog(AssetShelfSettings &settings, const asset_system::AssetCatalogPath &path) { @@ -116,30 +101,76 @@ bool settings_is_all_catalog_active(const AssetShelfSettings &settings) return !settings.active_catalog_path || !settings.active_catalog_path[0]; } -bool settings_is_catalog_path_enabled(const AssetShelfSettings &settings, - const asset_system::AssetCatalogPath &path) +static bool use_enabled_catalogs_from_prefs(const AssetShelf &shelf) { - LISTBASE_FOREACH (LinkData *, catalog_path_item, &settings.enabled_catalog_paths) { - if (StringRef((const char *)catalog_path_item->data) == path.str()) { - return true; - } - } - return false; + return shelf.type && (shelf.type->flag & ASSET_SHELF_TYPE_FLAG_STORE_CATALOGS_IN_PREFS); } -void settings_set_catalog_path_enabled(AssetShelfSettings &settings, +static const ListBase *get_enabled_catalog_path_list(const AssetShelf &shelf) +{ + if (use_enabled_catalogs_from_prefs(shelf)) { + bUserAssetShelfSettings *pref_settings = BKE_preferences_asset_shelf_settings_get( + &U, shelf.idname); + return pref_settings ? &pref_settings->enabled_catalog_paths : nullptr; + } + return &shelf.settings.enabled_catalog_paths; +} + +static ListBase *get_enabled_catalog_path_list(AssetShelf &shelf) +{ + return const_cast( + get_enabled_catalog_path_list(const_cast(shelf))); +} + +void settings_clear_enabled_catalogs(AssetShelf &shelf) +{ + ListBase *enabled_catalog_paths = get_enabled_catalog_path_list(shelf); + if (enabled_catalog_paths) { + BKE_asset_catalog_path_list_free(*enabled_catalog_paths); + BLI_assert(BLI_listbase_is_empty(enabled_catalog_paths)); + } +} + +bool settings_is_catalog_path_enabled(const AssetShelf &shelf, + const asset_system::AssetCatalogPath &path) +{ + const ListBase *enabled_catalog_paths = get_enabled_catalog_path_list(shelf); + if (!enabled_catalog_paths) { + return false; + } + + return BKE_asset_catalog_path_list_has_path(*enabled_catalog_paths, path.c_str()); +} + +void settings_set_catalog_path_enabled(AssetShelf &shelf, const asset_system::AssetCatalogPath &path) { - char *path_copy = BLI_strdupn(path.c_str(), path.length()); - BLI_addtail(&settings.enabled_catalog_paths, BLI_genericNodeN(path_copy)); + if (use_enabled_catalogs_from_prefs(shelf)) { + if (BKE_preferences_asset_shelf_settings_ensure_catalog_path_enabled( + &U, shelf.idname, path.c_str())) + { + U.runtime.is_dirty = true; + } + } + else { + if (!BKE_asset_catalog_path_list_has_path(shelf.settings.enabled_catalog_paths, path.c_str())) + { + BKE_asset_catalog_path_list_add_path(shelf.settings.enabled_catalog_paths, path.c_str()); + } + } } void settings_foreach_enabled_catalog_path( - const AssetShelfSettings &settings, + const AssetShelf &shelf, FunctionRef fn) { - LISTBASE_FOREACH (LinkData *, catalog_path_item, &settings.enabled_catalog_paths) { - fn(asset_system::AssetCatalogPath((char *)catalog_path_item->data)); + const ListBase *enabled_catalog_paths = get_enabled_catalog_path_list(shelf); + if (!enabled_catalog_paths) { + return; + } + + LISTBASE_FOREACH (const AssetCatalogPathLink *, path_link, enabled_catalog_paths) { + fn(asset_system::AssetCatalogPath(path_link->path)); } } diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h index 5ae7c074772..b92378393e3 100644 --- a/source/blender/makesdna/DNA_asset_types.h +++ b/source/blender/makesdna/DNA_asset_types.h @@ -205,3 +205,8 @@ typedef struct AssetWeakReference { typedef struct AssetHandle { const struct FileDirEntry *file_data; } AssetHandle; + +struct AssetCatalogPathLink { + struct AssetCatalogPathLink *next, *prev; + char *path; +}; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 32d32c7e7f4..f50a9a10625 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -799,7 +799,7 @@ typedef struct AssetShelfSettings { AssetLibraryReference asset_library_reference; - ListBase enabled_catalog_paths; /* #LinkData */ + ListBase enabled_catalog_paths; /* #AssetCatalogPathLink */ /** If not set (null or empty string), all assets will be displayed ("All" catalog behavior). */ const char *active_catalog_path; diff --git a/source/blender/makesdna/DNA_userdef_defaults.h b/source/blender/makesdna/DNA_userdef_defaults.h index 992d009b6ab..1dfd0b8b917 100644 --- a/source/blender/makesdna/DNA_userdef_defaults.h +++ b/source/blender/makesdna/DNA_userdef_defaults.h @@ -39,4 +39,16 @@ /** \} */ +/* -------------------------------------------------------------------- */ +/** \name bUserExtensionRepo Struct + * \{ */ + +#define _DNA_DEFAULT_bUserAssetShelfSettings \ + { \ + .shelf_idname = {'\0'}, \ + .enabled_catalog_paths = {NULL, NULL}, \ + } + +/** \} */ + /* clang-format on */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 7a6caacc140..5069a0af879 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -754,6 +754,20 @@ typedef struct bUserScriptDirectory { char dir_path[768]; /* FILE_MAXDIR */ } bUserScriptDirectory; +/** + * Settings for an asset shelf, stored in the Preferences. Most settings are still stored in the + * asset shelf instance in #AssetShelfSettings. This is just for the options that should be shared + * as Preferences. + */ +typedef struct bUserAssetShelfSettings { + struct bUserAssetShelfSettings *next, *prev; + + /** Identifier that matches the #AssetShelfType.idname of the shelf these settings apply to. */ + char shelf_idname[64]; /* MAX_NAME */ + + ListBase enabled_catalog_paths; /* #AssetCatalogPathLink */ +} bUserAssetShelfSettings; + /** * Main user preferences data, typically accessed from #U. * See: #BKE_blendfile_userdef_from_defaults & #BKE_blendfile_userdef_read. @@ -891,6 +905,7 @@ typedef struct UserDef { struct ListBase asset_libraries; /** #bUserExtensionRepo */ struct ListBase extension_repos; + struct ListBase asset_shelves_settings; /* #bUserAssetShelfSettings */ char keyconfigstr[64]; diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c index c5aa0df1900..39b002a1d24 100644 --- a/source/blender/makesdna/intern/dna_defaults.c +++ b/source/blender/makesdna/intern/dna_defaults.c @@ -238,6 +238,7 @@ SDNA_DEFAULT_DECL_STRUCT(Tex); /* DNA_userdef_types.h */ SDNA_DEFAULT_DECL_STRUCT(bUserAssetLibrary); SDNA_DEFAULT_DECL_STRUCT(bUserExtensionRepo); +SDNA_DEFAULT_DECL_STRUCT(bUserAssetShelfSettings); /* DNA_view3d_defaults.h */ SDNA_DEFAULT_DECL_STRUCT(View3D); @@ -517,6 +518,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = { SDNA_DEFAULT_DECL_EX(WalkNavigation, UserDef.walk_navigation), SDNA_DEFAULT_DECL(bUserAssetLibrary), SDNA_DEFAULT_DECL(bUserExtensionRepo), + SDNA_DEFAULT_DECL(bUserAssetShelfSettings), /* DNA_view3d_defaults.h */ SDNA_DEFAULT_DECL(View3D), diff --git a/source/blender/makesrna/intern/rna_ui.cc b/source/blender/makesrna/intern/rna_ui.cc index b43ba106eff..f25fc8fc19e 100644 --- a/source/blender/makesrna/intern/rna_ui.cc +++ b/source/blender/makesrna/intern/rna_ui.cc @@ -2267,6 +2267,12 @@ static void rna_def_asset_shelf(BlenderRNA *brna) "Visible by Default", "Unhide the asset shelf when it's available for the first time, otherwise it will be " "hidden"}, + {ASSET_SHELF_TYPE_FLAG_STORE_CATALOGS_IN_PREFS, + "STORE_ENABLED_CATALOGS_IN_PREFERENCES", + 0, + "Store Enabled Catalogs in Preferences", + "Store the shelf's enabled catalogs in the preferences rather than the local asset shelf " + "settings"}, {0, nullptr, 0, nullptr, nullptr}, };