[Bf-blender-cvs] [2d6a69ae4e9] master: Asset System: New Asset Browser editor

Julian Eisel noreply at git.blender.org
Tue Dec 15 17:04:35 CET 2020


Commit: 2d6a69ae4e9905a19ac7228b97ed08fb4ea72e75
Author: Julian Eisel
Date:   Mon Dec 14 14:07:42 2020 +0100
Branches: master
https://developer.blender.org/rB2d6a69ae4e9905a19ac7228b97ed08fb4ea72e75

Asset System: New Asset Browser editor

This introduces the User Interface part of the Asset Browser, based on the
design in T54642.

Additions:
* New Asset Browser (internally a sub-editor of the File Browser).
* Navigation region showing asset categories.
* Main region showing the assets of the selected asset library with previews.
  The assets may be stored over multiple .blends in the directory that's
  "mounted" as asset library in the Preferences. They will all be shown in this
  list.
* Header with an asset library dropdown, allowing to choose the active asset
  library to show. Options are the "Current File" as asset library and all
  custom libraries.
* Display popover, filter popover and search box (partially dummies, see
  T82680).
* Sidebar showing the metadata of the currently active file (name, preview,
  description and tags), which can be edited for assets in the "Current File"
  asset library. (For others it will reset on reload.)
* The sidebar includes a button to load a custom preview image from a file.
* Make asset files draggable (with preview image).
* If a library with invalid path is selected, a message is drawn in the main
  region to help the user understand what's wrong.
* Operators to add and remove asset tags. Exposed in the sidebar.
* "Only Assets" option for Link/Append.
* Internal utilities for asset UI scripts.

For screenshots or demo videos, please see D9725. Or the 2.92 release notes.

Note that there are many things to be tweaked and polished in the Asset Browser
UI still. For example, the filter and display popovers are mostly dummies. See
T82680.

Part of the first Asset Browser milestone. Check the #asset_browser_milestone_1
project milestone on developer.blender.org.

Differential Revision: https://developer.blender.org/D9725

Reviewed by: Brecht Van Lommel, Hans Goudey

===================================================================

M	release/scripts/modules/bpy_extras/__init__.py
A	release/scripts/modules/bpy_extras/asset_utils.py
M	release/scripts/startup/bl_operators/__init__.py
A	release/scripts/startup/bl_operators/assets.py
M	release/scripts/startup/bl_ui/space_filebrowser.py
M	source/blender/editors/interface/interface_style.c
M	source/blender/editors/space_file/file_draw.c
M	source/blender/editors/space_file/file_intern.h
M	source/blender/editors/space_file/file_ops.c
M	source/blender/editors/space_file/file_utils.c
M	source/blender/editors/space_file/space_file.c
M	source/blender/makesrna/intern/rna_screen.c
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/makesrna/intern/rna_userdef.c

===================================================================

diff --git a/release/scripts/modules/bpy_extras/__init__.py b/release/scripts/modules/bpy_extras/__init__.py
index 1caef074d43..cb990b014a1 100644
--- a/release/scripts/modules/bpy_extras/__init__.py
+++ b/release/scripts/modules/bpy_extras/__init__.py
@@ -24,6 +24,7 @@ Utility modules associated with the bpy module.
 
 __all__ = (
     "anim_utils",
+    "asset_utils",
     "object_utils",
     "io_utils",
     "image_utils",
diff --git a/release/scripts/modules/bpy_extras/asset_utils.py b/release/scripts/modules/bpy_extras/asset_utils.py
new file mode 100644
index 00000000000..db982e119d4
--- /dev/null
+++ b/release/scripts/modules/bpy_extras/asset_utils.py
@@ -0,0 +1,63 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+"""
+Helpers for asset management tasks.
+"""
+
+import bpy
+from bpy.types import (
+    Context,
+)
+
+__all__ = (
+    "SpaceAssetInfo",
+)
+
+class SpaceAssetInfo:
+    @classmethod
+    def is_asset_browser(cls, space_data: bpy.types.Space):
+        return space_data.type == 'FILE_BROWSER' and space_data.browse_mode == 'ASSETS'
+
+    @classmethod
+    def is_asset_browser_poll(cls, context: Context):
+        return cls.is_asset_browser(context.space_data)
+
+    @classmethod
+    def get_active_asset(cls, context: Context):
+        if hasattr(context, "active_file"):
+            active_file = context.active_file
+            return active_file.asset_data if active_file else None
+
+class AssetBrowserPanel:
+    bl_space_type = 'FILE_BROWSER'
+
+    @classmethod
+    def poll(cls, context):
+        return SpaceAssetInfo.is_asset_browser_poll(context)
+
+class AssetMetaDataPanel:
+    bl_space_type = 'FILE_BROWSER'
+    bl_region_type = 'TOOL_PROPS'
+
+    @classmethod
+    def poll(cls, context):
+        active_file = context.active_file
+        return SpaceAssetInfo.is_asset_browser_poll(context) and active_file and active_file.asset_data
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index 71b2de41d9e..e91d3b3ce60 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -27,6 +27,7 @@ if "bpy" in locals():
 _modules = [
     "add_mesh_torus",
     "anim",
+    "assets",
     "clip",
     "console",
     "constraint",
diff --git a/release/scripts/startup/bl_operators/assets.py b/release/scripts/startup/bl_operators/assets.py
new file mode 100644
index 00000000000..c317df78aa5
--- /dev/null
+++ b/release/scripts/startup/bl_operators/assets.py
@@ -0,0 +1,74 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import bpy
+
+from bpy_extras.asset_utils import (
+    SpaceAssetInfo,
+)
+
+class ASSET_OT_tag_add(bpy.types.Operator):
+    """Add a new keyword tag to the active asset"""
+
+    bl_idname = "asset.tag_add"
+    bl_label = "Add Asset Tag"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    @classmethod
+    def poll(cls, context):
+        return SpaceAssetInfo.is_asset_browser_poll(context) and SpaceAssetInfo.get_active_asset(context)
+
+    def execute(self, context):
+        active_asset = SpaceAssetInfo.get_active_asset(context)
+        active_asset.tags.new("Unnamed Tag")
+
+        return {'FINISHED'}
+
+
+class ASSET_OT_tag_remove(bpy.types.Operator):
+    """Remove an existing keyword tag from the active asset"""
+
+    bl_idname = "asset.tag_remove"
+    bl_label = "Remove Asset Tag"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    @classmethod
+    def poll(cls, context):
+        if not SpaceAssetInfo.is_asset_browser_poll(context):
+            return False
+
+        active_asset = SpaceAssetInfo.get_active_asset(context)
+        if not active_asset:
+            return False
+
+        return active_asset.active_tag in range(len(active_asset.tags))
+
+    def execute(self, context):
+        active_asset = SpaceAssetInfo.get_active_asset(context)
+        tag = active_asset.tags[active_asset.active_tag]
+
+        active_asset.tags.remove(tag)
+        active_asset.active_tag -= 1
+
+        return {'FINISHED'}
+
+
+classes = (
+    ASSET_OT_tag_add,
+    ASSET_OT_tag_remove,
+)
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index a9bb2e79762..527a5bc623e 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -17,27 +17,79 @@
 # ##### END GPL LICENSE BLOCK #####
 
 # <pep8 compliant>
+
+import bpy
+
 from bpy.types import Header, Panel, Menu, UIList
 
+from bpy_extras import (
+    asset_utils,
+)
+
 
 class FILEBROWSER_HT_header(Header):
     bl_space_type = 'FILE_BROWSER'
 
+    def draw_asset_browser_buttons(self, context):
+        layout = self.layout
+
+        space_data = context.space_data
+        params = space_data.params
+
+        row = layout.row(align=True)
+        row.prop(params, "asset_library", text="")
+        # External libraries don't auto-refresh, add refresh button.
+        if params.asset_library != 'LOCAL':
+            row.operator("file.refresh", text="", icon="FILE_REFRESH")
+
+        layout.separator_spacer()
+
+        # Uses prop_with_popover() as popover() only adds the triangle icon in headers.
+        layout.prop_with_popover(
+            params,
+            "display_type",
+            panel="FILEBROWSER_PT_display",
+            text="",
+            icon_only=True,
+        )
+        layout.prop_with_popover(
+            params,
+            "display_type",
+            panel="FILEBROWSER_PT_filter",
+            text="",
+            icon='FILTER',
+            icon_only=True,
+        )
+
+        layout.prop(params, "filter_search", text="", icon='VIEWZOOM')
+
+        layout.operator(
+            "screen.region_toggle",
+            text="",
+            icon='PREFERENCES',
+            depress=is_option_region_visible(context, space_data)
+        ).region_type = 'TOOL_PROPS'
+
     def draw(self, context):
+        from bpy_extras.asset_utils import SpaceAssetInfo
+
         layout = self.layout
 
-        st = context.space_data
+        space_data = context.space_data
 
-        if st.active_operator is None:
+        if space_data.active_operator is None:
             layout.template_header()
 
         FILEBROWSER_MT_editor_menus.draw_collapsible(context, layout)
 
-        # can be None when save/reload with a file selector open
-
-        layout.separator_spacer()
+        if SpaceAssetInfo.is_asset_browser(space_data):
+            layout.separator()
+            self.draw_asset_browser_buttons(context)
+        else:
+            layout.separator_spacer()
 
-        layout.template_running_jobs()
+        if not context.screen.show_statusbar:
+            layout.template_running_jobs()
 
 
 class FILEBROWSER_PT_display(Panel):
@@ -144,6 +196,9 @@ class FILEBROWSER_PT_filter(Panel):
                 row.label(icon='BLANK1')  # Indentation
 
                 sub = row.column(align=True)
+
+                sub.prop(params, "use_filter_asset_only")
+
                 filter_id = params.filter_id
                 for identifier in dir(filter_id):
                     if identifier.startswith("category_"):
@@ -160,6 +215,11 @@ def panel_poll_is_upper_region(region):
     return region.alignment in {'LEFT', 'RIGHT'}
 
 
+def panel_poll_is_asset_browsing(context):
+    from bpy_extras.asset_utils import SpaceAssetInfo
+    return SpaceAssetInfo.is_asset_browser_poll(context)
+
+
 class FILEBROWSER_UL_dir(UIList):
     def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
         direntry = item
@@ -187,7 +247,7 @@ class FILEBROWSER_PT_bookmarks_volumes(Panel):
 
     @classmethod
     def poll(cls, context):
-        return panel_poll_is_upper_region(context.region)
+        return panel_poll_is_upper_region(context.region) and not panel_poll_is_asset_browsing(context)
 
     def draw(self, context):
         layout = self.layout
@@ -207,7 +267,7 @@ class FILEBROWSER_PT_bookmarks_system(Panel):
 
     @classmethod
     def poll(cls, context):
-        return not context.preferences.filepaths.hide_system_bookmarks and panel_poll_is_upper_region(context.region)
+        return not context.preferences.filepaths.hide_system_bookmarks and panel_poll_is_upper_region(context.region) and not panel_poll_is_asset_browsing(context)
 
     def draw(self, context):
         layout = self.layout
@@ -241,7 +301,7 @@ class FILEBROWSER_PT_bookmarks_favorites(Panel):
 
     @classmethod
     def poll(cls, context):
-        return panel_poll_is_upper_region(context.region)
+        return panel_poll_is_upper_region(context.region) and

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list