diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index a7dcd9f68b8..f0dedc42c54 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1424,42 +1424,40 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel): layout.use_property_decorate = False paths = context.preferences.filepaths + active_library_index = paths.active_asset_library - box = layout.box() - split = box.split(factor=0.35) - name_col = split.column() - path_col = split.column() + row = layout.row() - row = name_col.row(align=True) # Padding - row.separator() - row.label(text="Name") + row.template_list( + "USERPREF_UL_asset_libraries", "user_asset_libraries", + paths, "asset_libraries", + paths, "active_asset_library" + ) - row = path_col.row(align=True) # Padding - row.separator() - row.label(text="Path") + col = row.column(align=True) + col.operator("preferences.asset_library_add", text="", icon='ADD') + props = col.operator("preferences.asset_library_remove", text="", icon='REMOVE') + props.index = active_library_index - for i, library in enumerate(paths.asset_libraries): - row = name_col.row() - row.alert = not library.name - row.prop(library, "name", text="") - row = name_col.row() - # Dummy for spacing - row.label(text="") - name_col.separator() + if active_library_index < 0: + return - row = path_col.row() - subrow = row.row() - subrow.alert = not library.path - subrow.prop(library, "path", text="") - row.operator("preferences.asset_library_remove", text="", icon='X', emboss=False).index = i - row = path_col.row() - row.prop(library, "import_method", text="") - row.label(text="", icon='BLANK1') - path_col.separator() + layout.separator() - row = box.row() - row.alignment = 'RIGHT' - row.operator("preferences.asset_library_add", text="", icon='ADD', emboss=False) + active_library = paths.asset_libraries[active_library_index] + layout.prop(active_library, "path") + layout.prop(active_library, "import_method", text="Import Method") + + +class USERPREF_UL_asset_libraries(bpy.types.UIList): + def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index): + asset_library = item + + if self.layout_type in {'DEFAULT', 'COMPACT'}: + layout.prop(asset_library, "name", text="", emboss=False) + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.prop(asset_library, "name", text="", emboss=False) # ----------------------------------------------------------------------------- @@ -2495,6 +2493,9 @@ classes = ( # USERPREF_PT_experimental_tweaks, USERPREF_PT_experimental_debugging, + # UI lists + USERPREF_UL_asset_libraries, + # Add dynamically generated editor theme panels last, # so they show up last in the theme section. *ThemeGenericClassGenerator.generate_panel_classes_from_theme_areas(), diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c index a7a741b3ce2..c04fe2cc543 100644 --- a/source/blender/editors/space_userpref/userpref_ops.c +++ b/source/blender/editors/space_userpref/userpref_ops.c @@ -134,7 +134,9 @@ static int preferences_asset_library_add_exec(bContext *UNUSED(C), wmOperator *o BLI_split_file_part(path, dirname, sizeof(dirname)); /* NULL is a valid directory path here. A library without path will be created then. */ - BKE_preferences_asset_library_add(&U, dirname, path); + const bUserAssetLibrary *new_library = BKE_preferences_asset_library_add(&U, dirname, path); + /* Activate new library in the UI for further setup. */ + U.active_asset_library = BLI_findindex(&U.asset_libraries, new_library); U.runtime.is_dirty = true; /* There's no dedicated notifier for the Preferences. */ @@ -182,16 +184,32 @@ static void PREFERENCES_OT_asset_library_add(wmOperatorType *ot) /** \name Remove Asset Library Operator * \{ */ +static bool preferences_asset_library_remove_poll(bContext *C) +{ + if (BLI_listbase_is_empty(&U.asset_libraries)) { + CTX_wm_operator_poll_msg_set(C, "There is no asset library to remove"); + return false; + } + return true; +} + static int preferences_asset_library_remove_exec(bContext *UNUSED(C), wmOperator *op) { const int index = RNA_int_get(op->ptr, "index"); bUserAssetLibrary *library = BLI_findlink(&U.asset_libraries, index); - if (library) { - BKE_preferences_asset_library_remove(&U, library); - U.runtime.is_dirty = true; - /* Trigger refresh for the Asset Browser. */ - WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL); + if (!library) { + return OPERATOR_CANCELLED; } + + BKE_preferences_asset_library_remove(&U, library); + const int count_remaining = BLI_listbase_count(&U.asset_libraries); + /* Update active library index to be in range. */ + CLAMP(U.active_asset_library, 0, count_remaining - 1); + U.runtime.is_dirty = true; + + /* Trigger refresh for the Asset Browser. */ + WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL); + return OPERATOR_FINISHED; } @@ -203,6 +221,7 @@ static void PREFERENCES_OT_asset_library_remove(wmOperatorType *ot) "Remove a path to a .blend file, so the Asset Browser will not attempt to show it anymore"; ot->exec = preferences_asset_library_remove_exec; + ot->poll = preferences_asset_library_remove_poll; ot->flag = OPTYPE_INTERNAL; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 91e950b540e..519510cd18a 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -783,8 +783,10 @@ typedef struct UserDef { char keyconfigstr[64]; + /** Index of the asset library being edited in the Preferences UI. */ + short active_asset_library; + short undosteps; - char _pad1[2]; int undomemory; float gpu_viewport_quality DNA_DEPRECATED; short gp_manhattandist, gp_euclideandist, gp_eraser; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index b9b9a30d608..53e5f3a21aa 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -6965,8 +6965,8 @@ static void rna_def_fileselect_asset_params(BlenderRNA *brna) prop = RNA_def_property(srna, "import_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, asset_import_type_items); RNA_def_property_ui_text(prop, "Import Method", "Determine how the asset will be imported"); - /* Asset drag info saved by buttons stores the import type, so the space must redraw when import - * type changes. */ + /* Asset drag info saved by buttons stores the import method, so the space must redraw when + * import type changes. */ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 6fa8884c54c..f9e10a4eaf1 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6346,6 +6346,13 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) prop = RNA_def_property(srna, "asset_libraries", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "UserAssetLibrary"); RNA_def_property_ui_text(prop, "Asset Libraries", ""); + + prop = RNA_def_property(srna, "active_asset_library", PROP_INT, PROP_NONE); + RNA_def_property_ui_text(prop, + "Active Asset Library", + "Index of the asset library being edited in the Preferences UI"); + /* Tag for UI-only update, meaning preferences will not be tagged as changed. */ + RNA_def_property_update(prop, 0, "rna_userdef_ui_update"); } static void rna_def_userdef_apps(BlenderRNA *brna)