Assets/UI: Use UI-list for asset library preferences UI

The Preferences for asset libraries are becoming more than a simple name
+ path. E.g. there is now an Import Method options, and we previously
also considered a Relative Paths option (which we may still want to
add). The previous UI, while consistent with the Auto Run Python Scripts
UI isn't well suited for less than trivial cases. Using UI lists makes
the UI more scalable and follows usual list UI patterns more. There is
also more space for the path button now.

Part of #104686.
This commit is contained in:
Julian Eisel
2023-02-15 13:00:17 +01:00
parent 972f58c482
commit 0d798ef57c
5 changed files with 68 additions and 39 deletions
+31 -30
View File
@@ -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(),
@@ -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;
+3 -1
View File
@@ -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;
+2 -2
View File
@@ -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);
}
@@ -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)