[Bf-blender-cvs] [83b572f6b93] asset-browser: Asset Browser UI

Julian Eisel noreply at git.blender.org
Thu Dec 3 01:58:55 CET 2020


Commit: 83b572f6b9395ba571ef69bc06e6c01b2b0a1b75
Author: Julian Eisel
Date:   Wed Dec 2 22:37:17 2020 +0100
Branches: asset-browser
https://developer.blender.org/rB83b572f6b9395ba571ef69bc06e6c01b2b0a1b75

Asset Browser UI

This introduces the UI part of the Asset Browser.

Additions:
* Asset Browser as sub-editor of the File Browser.
* Asset repository dropdown, showing "Current File" and all custom repositories.
* Display popover, filter popover and search box (partially dummies, see T82680).
* Navigation region showing asset categories.
* Asset metadata editing UI in the sidebar (preview, description, tags).
* Make asset files draggable (with preview image).
* If a repository with invalid path is selected, draw a message in the main region to help the user understand what's wrong.
* Operators to add and remove asset tags.
* "Only Assets" option for Link/Append.

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

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

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_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

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

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 eff88c835e7..cd930eaa318 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..45f9493d87c 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_repository", text="")
+        # External repositories don't auto-refresh, add refresh button.
+        if params.asset_repository != '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.re

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list