WIP: Rewrite asset browser as separate editor #104978
|
@ -1085,6 +1085,35 @@ const bTheme U_theme_default = {
|
||||||
.edited_object = RGBA(0x00806266),
|
.edited_object = RGBA(0x00806266),
|
||||||
.row_alternate = RGBA(0xffffff04),
|
.row_alternate = RGBA(0xffffff04),
|
||||||
},
|
},
|
||||||
|
.space_assets = {
|
||||||
|
.back = RGBA(0x28282800),
|
||||||
|
.title = RGBA(0xffffffff),
|
||||||
|
.text = RGBA(0xe6e6e6ff),
|
||||||
|
.text_hi = RGBA(0xffffffff),
|
||||||
|
.header = RGBA(0x303030b3),
|
||||||
|
.header_text = RGBA(0xeeeeeeff),
|
||||||
|
.header_text_hi = RGBA(0xffffffff),
|
||||||
|
.tab_active = RGBA(0x303030ff),
|
||||||
|
.tab_inactive = RGBA(0x1d1d1dff),
|
||||||
|
.tab_back = RGBA(0x181818ff),
|
||||||
|
.tab_outline = RGBA(0x3d3d3dff),
|
||||||
|
.button = RGBA(0x30303000),
|
||||||
|
.button_title = RGBA(0xffffffff),
|
||||||
|
.button_text = RGBA(0xccccccff),
|
||||||
|
.button_text_hi = RGBA(0xffffffff),
|
||||||
|
.navigation_bar = RGBA(0x303030ff),
|
||||||
|
.execution_buts = RGBA(0x303030ff),
|
||||||
|
.panelcolors = {
|
||||||
|
.header = RGBA(0x3d3d3dff),
|
||||||
|
.back = RGBA(0x3d3d3dff),
|
||||||
|
.sub_back = RGBA(0x0000001f),
|
||||||
|
},
|
||||||
|
.hilite = RGBA(0x4772b3ff),
|
||||||
|
.vertex_size = 3,
|
||||||
|
.outline_width = 1,
|
||||||
|
.facedot_size = 4,
|
||||||
|
.row_alternate = RGBA(0xffffff04),
|
||||||
|
},
|
||||||
.tarm = {
|
.tarm = {
|
||||||
{
|
{
|
||||||
.solid = RGBA(0x9a0000ff),
|
.solid = RGBA(0x9a0000ff),
|
||||||
|
|
|
@ -1388,6 +1388,42 @@
|
||||||
</space_list>
|
</space_list>
|
||||||
</ThemeSpreadsheet>
|
</ThemeSpreadsheet>
|
||||||
</spreadsheet>
|
</spreadsheet>
|
||||||
|
<asset_browser>
|
||||||
|
<ThemeAssetBrowser
|
||||||
|
row_alternate="#ffffff0f"
|
||||||
|
>
|
||||||
|
<space>
|
||||||
|
<ThemeSpaceGeneric
|
||||||
|
back="#999999"
|
||||||
|
title="#000000"
|
||||||
|
text="#000000"
|
||||||
|
text_hi="#ffffff"
|
||||||
|
header="#adadadff"
|
||||||
|
header_text="#000000"
|
||||||
|
header_text_hi="#ffffff"
|
||||||
|
button="#999999e6"
|
||||||
|
button_title="#1a1a1a"
|
||||||
|
button_text="#000000"
|
||||||
|
button_text_hi="#000000"
|
||||||
|
navigation_bar="#00000000"
|
||||||
|
execution_buts="#999999e6"
|
||||||
|
tab_active="#6697e6"
|
||||||
|
tab_inactive="#cccccc"
|
||||||
|
tab_back="#999999ff"
|
||||||
|
tab_outline="#999999"
|
||||||
|
>
|
||||||
|
<panelcolors>
|
||||||
|
<ThemePanelColors
|
||||||
|
header="#42424200"
|
||||||
|
back="#00000028"
|
||||||
|
sub_back="#00000024"
|
||||||
|
>
|
||||||
|
</ThemePanelColors>
|
||||||
|
</panelcolors>
|
||||||
|
</ThemeSpaceGeneric>
|
||||||
|
</space>
|
||||||
|
</ThemeAssetBrowser>
|
||||||
|
</asset_browser>
|
||||||
<bone_color_sets>
|
<bone_color_sets>
|
||||||
<ThemeBoneColorSet
|
<ThemeBoneColorSet
|
||||||
normal="#9a0000"
|
normal="#9a0000"
|
||||||
|
|
|
@ -2186,7 +2186,6 @@ def km_info(params):
|
||||||
|
|
||||||
return keymap
|
return keymap
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Editor (File Browser)
|
# Editor (File Browser)
|
||||||
|
|
||||||
|
@ -2344,6 +2343,28 @@ def km_file_browser_buttons(_params):
|
||||||
return keymap
|
return keymap
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# Editor (Asset Browser)
|
||||||
|
|
||||||
|
def km_asset_browser(params):
|
||||||
|
items = []
|
||||||
|
keymap = (
|
||||||
|
"Asset Browser",
|
||||||
|
{"space_type": 'ASSET_BROWSER', "region_type": 'WINDOW'},
|
||||||
|
{"items": items},
|
||||||
|
)
|
||||||
|
|
||||||
|
items.extend([
|
||||||
|
("wm.context_toggle", {"type": 'T', "value": 'PRESS'},
|
||||||
|
{"properties": [("data_path", 'space_data.show_region_nav_bar')]}),
|
||||||
|
*_template_space_region_type_toggle(
|
||||||
|
sidebar_key={"type": 'N', "value": 'PRESS'},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
return keymap
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Editor (Dope Sheet)
|
# Editor (Dope Sheet)
|
||||||
|
|
||||||
|
@ -8057,6 +8078,7 @@ def generate_keymaps(params=None):
|
||||||
km_node_editor(params),
|
km_node_editor(params),
|
||||||
km_spreadsheet_generic(params),
|
km_spreadsheet_generic(params),
|
||||||
km_info(params),
|
km_info(params),
|
||||||
|
km_asset_browser(params),
|
||||||
km_file_browser(params),
|
km_file_browser(params),
|
||||||
km_file_browser_main(params),
|
km_file_browser_main(params),
|
||||||
km_file_browser_buttons(params),
|
km_file_browser_buttons(params),
|
||||||
|
|
|
@ -4161,6 +4161,7 @@ def generate_keymaps_impl(params=None):
|
||||||
km_clip_editor(params),
|
km_clip_editor(params),
|
||||||
km_clip_graph_editor(params),
|
km_clip_graph_editor(params),
|
||||||
km_clip_dopesheet_editor(params),
|
km_clip_dopesheet_editor(params),
|
||||||
|
# TODO asset browser
|
||||||
|
|
||||||
# Animation.
|
# Animation.
|
||||||
km_frames(params),
|
km_frames(params),
|
||||||
|
|
|
@ -60,6 +60,7 @@ _modules = [
|
||||||
"space_toolsystem_common",
|
"space_toolsystem_common",
|
||||||
"space_toolsystem_toolbar",
|
"space_toolsystem_toolbar",
|
||||||
|
|
||||||
|
"space_assets",
|
||||||
"space_clip",
|
"space_clip",
|
||||||
"space_console",
|
"space_console",
|
||||||
"space_dopesheet",
|
"space_dopesheet",
|
||||||
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
import bpy
|
||||||
|
from bpy.types import Header, Menu, Panel, UIList
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_HT_header(Header):
|
||||||
|
bl_space_type = 'ASSET_BROWSER'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
space = context.space_data
|
||||||
|
|
||||||
|
layout.template_header()
|
||||||
|
|
||||||
|
ASSETBROWSER_MT_editor_menus.draw_collapsible(context, layout)
|
||||||
|
|
||||||
|
layout.separator_spacer()
|
||||||
|
|
||||||
|
layout.operator(
|
||||||
|
"screen.region_toggle",
|
||||||
|
text="",
|
||||||
|
icon='PREFERENCES',
|
||||||
|
depress=is_option_region_visible(context, space)
|
||||||
|
).region_type = 'UI'
|
||||||
|
|
||||||
|
|
||||||
|
def is_option_region_visible(context, space):
|
||||||
|
for region in context.area.regions:
|
||||||
|
if region.type == 'UI' and region.width <= 1:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_MT_editor_menus(Menu):
|
||||||
|
bl_idname = "ASSETBROWSER_MT_editor_menus"
|
||||||
|
bl_label = ""
|
||||||
|
|
||||||
|
def draw(self, _context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
layout.menu("ASSETBROWSER_MT_view")
|
||||||
|
layout.menu("ASSETBROWSER_MT_select")
|
||||||
|
layout.menu("ASSETBROWSER_MT_edit")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_MT_view(Menu):
|
||||||
|
bl_label = "View"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
st = context.space_data
|
||||||
|
|
||||||
|
layout.prop(st, "show_region_nav_bar", text="Navigation")
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
layout.menu("INFO_MT_area")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_MT_select(Menu):
|
||||||
|
bl_label = "Select"
|
||||||
|
|
||||||
|
def draw(self, _context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_MT_edit(Menu):
|
||||||
|
bl_label = "Edit"
|
||||||
|
|
||||||
|
def draw(self, _context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
layout.operator("asset.catalog_undo", text="Undo")
|
||||||
|
layout.operator("asset.catalog_redo", text="Redo")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_PT_metadata(Panel):
|
||||||
|
bl_space_type = 'ASSET_BROWSER'
|
||||||
|
bl_region_type = 'UI'
|
||||||
|
bl_label = "Asset Metadata"
|
||||||
|
bl_options = {'HIDE_HEADER'}
|
||||||
|
bl_category = 'Metadata'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
wm = context.window_manager
|
||||||
|
asset_handle = context.asset_handle
|
||||||
|
asset_file = asset_handle.file_data
|
||||||
|
|
||||||
|
if asset_handle is None:
|
||||||
|
layout.label(text="No active asset", icon='INFO')
|
||||||
|
return
|
||||||
|
|
||||||
|
asset_library_ref = context.asset_library_ref
|
||||||
|
asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file, asset_library_ref)
|
||||||
|
|
||||||
|
prefs = context.preferences
|
||||||
|
show_asset_debug_info = prefs.view.show_developer_ui and prefs.experimental.show_asset_debug_info
|
||||||
|
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
if asset_handle.local_id:
|
||||||
|
# If the active file is an ID, use its name directly so renaming is possible from right here.
|
||||||
|
layout.prop(asset_handle.local_id, "name")
|
||||||
|
|
||||||
|
if show_asset_debug_info:
|
||||||
|
col = layout.column(align=True)
|
||||||
|
col.label(text="Asset Catalog:")
|
||||||
|
col.prop(asset_handle.local_id.asset_data, "catalog_id", text="UUID")
|
||||||
|
col.prop(asset_handle.local_id.asset_data, "catalog_simple_name", text="Simple Name")
|
||||||
|
else:
|
||||||
|
layout.prop(asset_file, "name")
|
||||||
|
|
||||||
|
if show_asset_debug_info:
|
||||||
|
col = layout.column(align=True)
|
||||||
|
col.enabled = False
|
||||||
|
col.label(text="Asset Catalog:")
|
||||||
|
col.prop(asset_file.asset_data, "catalog_id", text="UUID")
|
||||||
|
col.prop(asset_file.asset_data, "catalog_simple_name", text="Simple Name")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.prop(wm, "asset_path_dummy", text="Source")
|
||||||
|
row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS')
|
||||||
|
|
||||||
|
layout.prop(asset_file.asset_data, "description")
|
||||||
|
layout.prop(asset_file.asset_data, "author")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_PT_metadata_preview(Panel):
|
||||||
|
bl_space_type = 'ASSET_BROWSER'
|
||||||
|
bl_region_type = 'UI'
|
||||||
|
bl_label = "Preview"
|
||||||
|
bl_category = 'Metadata'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
asset_handle = context.asset_handle
|
||||||
|
asset_file = asset_handle.file_data
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
box = row.box()
|
||||||
|
box.template_icon(icon_value=asset_file.preview_icon_id, scale=5.0)
|
||||||
|
|
||||||
|
col = row.column(align=True)
|
||||||
|
col.operator("ed.lib_id_load_custom_preview", icon='FILEBROWSER', text="")
|
||||||
|
col.separator()
|
||||||
|
col.operator("ed.lib_id_generate_preview", icon='FILE_REFRESH', text="")
|
||||||
|
col.menu("ASSETBROWSER_MT_metadata_preview_menu", icon='DOWNARROW_HLT', text="")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_MT_metadata_preview_menu(Menu):
|
||||||
|
bl_label = "Preview"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.operator("ed.lib_id_generate_preview_from_object", text="Render Active Object")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_PT_metadata_tags(Panel):
|
||||||
|
bl_space_type = 'ASSET_BROWSER'
|
||||||
|
bl_region_type = 'UI'
|
||||||
|
bl_label = "Tags"
|
||||||
|
bl_category = 'Metadata'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
asset = context.asset_handle
|
||||||
|
asset_data = asset.file_data.asset_data
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.template_list("ASSETBROWSEROLD_UL_metadata_tags", "asset_tags", asset_data, "tags",
|
||||||
|
asset_data, "active_tag", rows=4)
|
||||||
|
|
||||||
|
col = row.column(align=True)
|
||||||
|
col.operator("asset.tag_add", icon='ADD', text="")
|
||||||
|
col.operator("asset.tag_remove", icon='REMOVE', text="")
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETBROWSER_UL_metadata_tags(UIList):
|
||||||
|
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||||
|
tag = item
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
# Non-editable entries would show grayed-out, which is bad in this specific case, so switch to mere label.
|
||||||
|
if tag.is_property_readonly("name"):
|
||||||
|
row.label(text=tag.name, icon_value=icon)
|
||||||
|
else:
|
||||||
|
row.prop(tag, "name", text="", emboss=False, icon_value=icon)
|
||||||
|
|
||||||
|
|
||||||
|
classes = (
|
||||||
|
ASSETBROWSER_HT_header,
|
||||||
|
ASSETBROWSER_MT_editor_menus,
|
||||||
|
ASSETBROWSER_MT_view,
|
||||||
|
ASSETBROWSER_MT_select,
|
||||||
|
ASSETBROWSER_MT_edit,
|
||||||
|
ASSETBROWSER_PT_metadata,
|
||||||
|
ASSETBROWSER_PT_metadata_preview,
|
||||||
|
ASSETBROWSER_MT_metadata_preview_menu,
|
||||||
|
ASSETBROWSER_PT_metadata_tags,
|
||||||
|
ASSETBROWSER_UL_metadata_tags,
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__": # only for live edit.
|
||||||
|
from bpy.utils import register_class
|
||||||
|
for cls in classes:
|
||||||
|
register_class(cls)
|
|
@ -64,7 +64,7 @@ class FILEBROWSER_HT_header(Header):
|
||||||
layout.template_header()
|
layout.template_header()
|
||||||
|
|
||||||
if SpaceAssetInfo.is_asset_browser(space_data):
|
if SpaceAssetInfo.is_asset_browser(space_data):
|
||||||
ASSETBROWSER_MT_editor_menus.draw_collapsible(context, layout)
|
ASSETBROWSEROLD_MT_editor_menus.draw_collapsible(context, layout)
|
||||||
layout.separator()
|
layout.separator()
|
||||||
self.draw_asset_browser_buttons(context)
|
self.draw_asset_browser_buttons(context)
|
||||||
else:
|
else:
|
||||||
|
@ -638,19 +638,19 @@ class AssetBrowserMenu:
|
||||||
return SpaceAssetInfo.is_asset_browser_poll(context)
|
return SpaceAssetInfo.is_asset_browser_poll(context)
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_MT_editor_menus(AssetBrowserMenu, Menu):
|
class ASSETBROWSEROLD_MT_editor_menus(AssetBrowserMenu, Menu):
|
||||||
bl_idname = "ASSETBROWSER_MT_editor_menus"
|
bl_idname = "ASSETBROWSEROLD_MT_editor_menus"
|
||||||
bl_label = ""
|
bl_label = ""
|
||||||
|
|
||||||
def draw(self, _context):
|
def draw(self, _context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
layout.menu("ASSETBROWSER_MT_view")
|
layout.menu("ASSETBROWSEROLD_MT_view")
|
||||||
layout.menu("ASSETBROWSER_MT_select")
|
layout.menu("ASSETBROWSEROLD_MT_select")
|
||||||
layout.menu("ASSETBROWSER_MT_catalog")
|
layout.menu("ASSETBROWSER_MT_catalog")
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu):
|
class ASSETBROWSEROLD_MT_view(AssetBrowserMenu, Menu):
|
||||||
bl_label = "View"
|
bl_label = "View"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
@ -671,7 +671,7 @@ class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu):
|
||||||
layout.menu("INFO_MT_area")
|
layout.menu("INFO_MT_area")
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_MT_select(AssetBrowserMenu, Menu):
|
class ASSETBROWSEROLD_MT_select(AssetBrowserMenu, Menu):
|
||||||
bl_label = "Select"
|
bl_label = "Select"
|
||||||
|
|
||||||
def draw(self, _context):
|
def draw(self, _context):
|
||||||
|
@ -700,7 +700,7 @@ class ASSETBROWSER_MT_catalog(AssetBrowserMenu, Menu):
|
||||||
layout.operator("asset.catalog_new").parent_path = ""
|
layout.operator("asset.catalog_new").parent_path = ""
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
|
class ASSETBROWSEROLD_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
|
||||||
bl_region_type = 'TOOL_PROPS'
|
bl_region_type = 'TOOL_PROPS'
|
||||||
bl_label = "Asset Metadata"
|
bl_label = "Asset Metadata"
|
||||||
bl_options = {'HIDE_HEADER'}
|
bl_options = {'HIDE_HEADER'}
|
||||||
|
@ -750,7 +750,7 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
|
||||||
layout.prop(asset_file_handle.asset_data, "author")
|
layout.prop(asset_file_handle.asset_data, "author")
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel):
|
class ASSETBROWSEROLD_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel):
|
||||||
bl_label = "Preview"
|
bl_label = "Preview"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
@ -765,10 +765,10 @@ class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel):
|
||||||
col.operator("ed.lib_id_load_custom_preview", icon='FILEBROWSER', text="")
|
col.operator("ed.lib_id_load_custom_preview", icon='FILEBROWSER', text="")
|
||||||
col.separator()
|
col.separator()
|
||||||
col.operator("ed.lib_id_generate_preview", icon='FILE_REFRESH', text="")
|
col.operator("ed.lib_id_generate_preview", icon='FILE_REFRESH', text="")
|
||||||
col.menu("ASSETBROWSER_MT_metadata_preview_menu", icon='DOWNARROW_HLT', text="")
|
col.menu("ASSETBROWSEROLD_MT_metadata_preview_menu", icon='DOWNARROW_HLT', text="")
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_MT_metadata_preview_menu(bpy.types.Menu):
|
class ASSETBROWSEROLD_MT_metadata_preview_menu(bpy.types.Menu):
|
||||||
bl_label = "Preview"
|
bl_label = "Preview"
|
||||||
|
|
||||||
def draw(self, _context):
|
def draw(self, _context):
|
||||||
|
@ -776,7 +776,7 @@ class ASSETBROWSER_MT_metadata_preview_menu(bpy.types.Menu):
|
||||||
layout.operator("ed.lib_id_generate_preview_from_object", text="Render Active Object")
|
layout.operator("ed.lib_id_generate_preview_from_object", text="Render Active Object")
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
|
class ASSETBROWSEROLD_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
|
||||||
bl_label = "Tags"
|
bl_label = "Tags"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
|
@ -784,7 +784,7 @@ class ASSETBROWSER_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
|
||||||
asset_data = asset_utils.SpaceAssetInfo.get_active_asset(context)
|
asset_data = asset_utils.SpaceAssetInfo.get_active_asset(context)
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.template_list("ASSETBROWSER_UL_metadata_tags", "asset_tags", asset_data, "tags",
|
row.template_list("ASSETBROWSEROLD_UL_metadata_tags", "asset_tags", asset_data, "tags",
|
||||||
asset_data, "active_tag", rows=4)
|
asset_data, "active_tag", rows=4)
|
||||||
|
|
||||||
col = row.column(align=True)
|
col = row.column(align=True)
|
||||||
|
@ -792,7 +792,7 @@ class ASSETBROWSER_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
|
||||||
col.operator("asset.tag_remove", icon='REMOVE', text="")
|
col.operator("asset.tag_remove", icon='REMOVE', text="")
|
||||||
|
|
||||||
|
|
||||||
class ASSETBROWSER_UL_metadata_tags(UIList):
|
class ASSETBROWSEROLD_UL_metadata_tags(UIList):
|
||||||
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||||
tag = item
|
tag = item
|
||||||
|
|
||||||
|
@ -850,15 +850,15 @@ classes = (
|
||||||
FILEBROWSER_MT_view_pie,
|
FILEBROWSER_MT_view_pie,
|
||||||
ASSETBROWSER_PT_display,
|
ASSETBROWSER_PT_display,
|
||||||
ASSETBROWSER_PT_filter,
|
ASSETBROWSER_PT_filter,
|
||||||
ASSETBROWSER_MT_editor_menus,
|
ASSETBROWSEROLD_MT_editor_menus,
|
||||||
ASSETBROWSER_MT_view,
|
ASSETBROWSEROLD_MT_view,
|
||||||
ASSETBROWSER_MT_select,
|
ASSETBROWSEROLD_MT_select,
|
||||||
ASSETBROWSER_MT_catalog,
|
ASSETBROWSER_MT_catalog,
|
||||||
ASSETBROWSER_MT_metadata_preview_menu,
|
ASSETBROWSEROLD_MT_metadata_preview_menu,
|
||||||
ASSETBROWSER_PT_metadata,
|
ASSETBROWSEROLD_PT_metadata,
|
||||||
ASSETBROWSER_PT_metadata_preview,
|
ASSETBROWSEROLD_PT_metadata_preview,
|
||||||
ASSETBROWSER_PT_metadata_tags,
|
ASSETBROWSEROLD_PT_metadata_tags,
|
||||||
ASSETBROWSER_UL_metadata_tags,
|
ASSETBROWSEROLD_UL_metadata_tags,
|
||||||
ASSETBROWSER_MT_context_menu,
|
ASSETBROWSER_MT_context_menu,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1228,8 +1228,7 @@ class ThemeGenericClassGenerator:
|
||||||
("Scroll Bar", "wcol_scroll"),
|
("Scroll Bar", "wcol_scroll"),
|
||||||
("Progress Bar", "wcol_progress"),
|
("Progress Bar", "wcol_progress"),
|
||||||
("List Item", "wcol_list_item"),
|
("List Item", "wcol_list_item"),
|
||||||
# Not used yet, so hide this from the UI.
|
("Data-View Item", "wcol_view_item"),
|
||||||
# ("Data-View Item", "wcol_view_item"),
|
|
||||||
("Tab", "wcol_tab"),
|
("Tab", "wcol_tab"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,7 @@ struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C);
|
||||||
struct SpaceClip *CTX_wm_space_clip(const bContext *C);
|
struct SpaceClip *CTX_wm_space_clip(const bContext *C);
|
||||||
struct SpaceTopBar *CTX_wm_space_topbar(const bContext *C);
|
struct SpaceTopBar *CTX_wm_space_topbar(const bContext *C);
|
||||||
struct SpaceSpreadsheet *CTX_wm_space_spreadsheet(const bContext *C);
|
struct SpaceSpreadsheet *CTX_wm_space_spreadsheet(const bContext *C);
|
||||||
|
struct SpaceAssets *CTX_wm_space_assets(const bContext *C);
|
||||||
|
|
||||||
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
|
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
|
||||||
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
|
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
|
||||||
|
@ -380,6 +381,7 @@ bool CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
|
||||||
|
|
||||||
const struct AssetLibraryReference *CTX_wm_asset_library_ref(const bContext *C);
|
const struct AssetLibraryReference *CTX_wm_asset_library_ref(const bContext *C);
|
||||||
struct AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid);
|
struct AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid);
|
||||||
|
struct AssetHandle *CTX_wm_asset_handle_ptr(const bContext *C);
|
||||||
|
|
||||||
struct AssetRepresentation *CTX_wm_asset(const bContext *C);
|
struct AssetRepresentation *CTX_wm_asset(const bContext *C);
|
||||||
|
|
||||||
|
|
|
@ -929,6 +929,15 @@ SpaceSpreadsheet *CTX_wm_space_spreadsheet(const bContext *C)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SpaceAssets *CTX_wm_space_assets(const bContext *C)
|
||||||
|
{
|
||||||
|
ScrArea *area = CTX_wm_area(C);
|
||||||
|
if (area && area->spacetype == SPACE_ASSETS) {
|
||||||
|
return static_cast<SpaceAssets *>(area->spacedata.first);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
|
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
|
||||||
{
|
{
|
||||||
C->wm.manager = wm;
|
C->wm.manager = wm;
|
||||||
|
@ -1493,6 +1502,17 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid)
|
||||||
return AssetHandle{nullptr};
|
return AssetHandle{nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \note Only works in the new Asset Browser and the asset view template (not in the old File
|
||||||
|
* Browser based Asset Browser).
|
||||||
|
* TODO Replace #CTX_wm_asset_handle() with this.
|
||||||
|
*/
|
||||||
|
AssetHandle *CTX_wm_asset_handle_ptr(const bContext *C)
|
||||||
|
{
|
||||||
|
return static_cast<AssetHandle *>(
|
||||||
|
CTX_data_pointer_get_type(C, "asset_handle", &RNA_AssetHandle).data);
|
||||||
|
}
|
||||||
|
|
||||||
AssetRepresentation *CTX_wm_asset(const bContext *C)
|
AssetRepresentation *CTX_wm_asset(const bContext *C)
|
||||||
{
|
{
|
||||||
return static_cast<AssetRepresentation *>(ctx_data_pointer_get(C, "asset"));
|
return static_cast<AssetRepresentation *>(ctx_data_pointer_get(C, "asset"));
|
||||||
|
|
|
@ -1159,6 +1159,10 @@ static void write_area(BlendWriter *writer, ScrArea *area)
|
||||||
if (space_type && space_type->blend_write) {
|
if (space_type && space_type->blend_write) {
|
||||||
space_type->blend_write(writer, sl);
|
space_type->blend_write(writer, sl);
|
||||||
}
|
}
|
||||||
|
else if (sl->spacetype == SPACE_ASSETS) {
|
||||||
|
BLO_write_struct(writer, SpaceAssets, sl);
|
||||||
|
// SpaceAssets *space_assets = (SpaceAssets *)sl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2603,6 +2603,7 @@ static void lib_link_workspace_layout_restore(IDNameLib_Map *id_map,
|
||||||
lib_link_restore_viewer_path(id_map, &sspreadsheet->viewer_path);
|
lib_link_restore_viewer_path(id_map, &sspreadsheet->viewer_path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPACE_ASSETS:
|
||||||
case SPACE_INFO:
|
case SPACE_INFO:
|
||||||
case SPACE_IMASEL:
|
case SPACE_IMASEL:
|
||||||
case SPACE_SOUND:
|
case SPACE_SOUND:
|
||||||
|
|
|
@ -104,6 +104,9 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Keep this block, even when empty. */
|
/* Keep this block, even when empty. */
|
||||||
|
/* TODO version bump. */
|
||||||
|
btheme->space_assets = btheme->space_file;
|
||||||
|
btheme->tui.wcol_view_item = U_theme_default.tui.wcol_view_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef FROM_DEFAULT_V4_UCHAR
|
#undef FROM_DEFAULT_V4_UCHAR
|
||||||
|
|
|
@ -27,6 +27,7 @@ if(WITH_BLENDER)
|
||||||
add_subdirectory(sound)
|
add_subdirectory(sound)
|
||||||
add_subdirectory(space_action)
|
add_subdirectory(space_action)
|
||||||
add_subdirectory(space_api)
|
add_subdirectory(space_api)
|
||||||
|
add_subdirectory(space_assets)
|
||||||
add_subdirectory(space_buttons)
|
add_subdirectory(space_buttons)
|
||||||
add_subdirectory(space_clip)
|
add_subdirectory(space_clip)
|
||||||
add_subdirectory(space_console)
|
add_subdirectory(space_console)
|
||||||
|
|
|
@ -33,6 +33,7 @@ set(SRC
|
||||||
intern/asset_ops.cc
|
intern/asset_ops.cc
|
||||||
intern/asset_temp_id_consumer.cc
|
intern/asset_temp_id_consumer.cc
|
||||||
intern/asset_type.cc
|
intern/asset_type.cc
|
||||||
|
intern/asset_view_catalog_filter.cc
|
||||||
|
|
||||||
ED_asset_catalog.h
|
ED_asset_catalog.h
|
||||||
ED_asset_catalog.hh
|
ED_asset_catalog.hh
|
||||||
|
@ -46,6 +47,7 @@ set(SRC
|
||||||
ED_asset_mark_clear.h
|
ED_asset_mark_clear.h
|
||||||
ED_asset_temp_id_consumer.h
|
ED_asset_temp_id_consumer.h
|
||||||
ED_asset_type.h
|
ED_asset_type.h
|
||||||
|
ED_asset_view_catalog_filter.h
|
||||||
intern/asset_library_reference.hh
|
intern/asset_library_reference.hh
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct AssetHandle;
|
||||||
|
|
||||||
struct AssetRepresentation *ED_asset_handle_get_representation(const struct AssetHandle *asset);
|
struct AssetRepresentation *ED_asset_handle_get_representation(const struct AssetHandle *asset);
|
||||||
const char *ED_asset_handle_get_name(const struct AssetHandle *asset);
|
const char *ED_asset_handle_get_name(const struct AssetHandle *asset);
|
||||||
|
const char *ED_asset_handle_get_identifier(const struct AssetHandle *asset);
|
||||||
struct AssetMetaData *ED_asset_handle_get_metadata(const struct AssetHandle *asset);
|
struct AssetMetaData *ED_asset_handle_get_metadata(const struct AssetHandle *asset);
|
||||||
struct ID *ED_asset_handle_get_local_id(const struct AssetHandle *asset);
|
struct ID *ED_asset_handle_get_local_id(const struct AssetHandle *asset);
|
||||||
ID_Type ED_asset_handle_get_id_type(const struct AssetHandle *asset);
|
ID_Type ED_asset_handle_get_id_type(const struct AssetHandle *asset);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct AssetCatalogFilterSettings;
|
||||||
struct AssetLibraryReference;
|
struct AssetLibraryReference;
|
||||||
struct ID;
|
struct ID;
|
||||||
struct bContext;
|
struct bContext;
|
||||||
|
@ -26,11 +27,12 @@ struct wmNotifier;
|
||||||
*/
|
*/
|
||||||
void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_reference,
|
void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_reference,
|
||||||
const struct bContext *C);
|
const struct bContext *C);
|
||||||
|
void ED_assetlist_catalog_filter_set(const struct AssetLibraryReference *,
|
||||||
|
const struct AssetCatalogFilterSettings *catalog_filter);
|
||||||
bool ED_assetlist_is_loaded(const struct AssetLibraryReference *library_reference);
|
bool ED_assetlist_is_loaded(const struct AssetLibraryReference *library_reference);
|
||||||
void ED_assetlist_ensure_previews_job(const struct AssetLibraryReference *library_reference,
|
|
||||||
const struct bContext *C);
|
|
||||||
void ED_assetlist_clear(const struct AssetLibraryReference *library_reference, struct bContext *C);
|
void ED_assetlist_clear(const struct AssetLibraryReference *library_reference, struct bContext *C);
|
||||||
bool ED_assetlist_storage_has_list_for_library(const AssetLibraryReference *library_reference);
|
bool ED_assetlist_storage_has_list_for_library(const AssetLibraryReference *library_reference);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag all asset lists in the storage that show main data as needing an update (re-fetch).
|
* Tag all asset lists in the storage that show main data as needing an update (re-fetch).
|
||||||
*
|
*
|
||||||
|
@ -50,11 +52,18 @@ void ED_assetlist_storage_id_remap(struct ID *id_old, struct ID *id_new);
|
||||||
*/
|
*/
|
||||||
void ED_assetlist_storage_exit(void);
|
void ED_assetlist_storage_exit(void);
|
||||||
|
|
||||||
AssetHandle ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
AssetHandle *ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
||||||
int asset_index);
|
int asset_index);
|
||||||
|
|
||||||
|
struct PreviewImage *ED_assetlist_asset_preview_request(
|
||||||
|
const struct AssetLibraryReference *library_reference, AssetHandle *asset_handle);
|
||||||
|
int ED_assetlist_asset_preview_icon_id_request(const AssetLibraryReference *library_reference,
|
||||||
|
AssetHandle *asset_handle);
|
||||||
struct ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle);
|
struct ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle);
|
||||||
|
|
||||||
|
struct AssetLibrary *ED_assetlist_library_get(
|
||||||
|
const struct AssetLibraryReference *library_reference);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \return True if the region needs a UI redraw.
|
* \return True if the region needs a UI redraw.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "BLI_function_ref.hh"
|
#include "BLI_function_ref.hh"
|
||||||
|
@ -29,8 +30,12 @@ blender::asset_system::AssetLibrary *ED_assetlist_library_get_once_available(
|
||||||
const AssetLibraryReference &library_reference);
|
const AssetLibraryReference &library_reference);
|
||||||
|
|
||||||
/* Can return false to stop iterating. */
|
/* Can return false to stop iterating. */
|
||||||
using AssetListIterFn = blender::FunctionRef<bool(AssetHandle)>;
|
using AssetListIterFn = blender::FunctionRef<bool(AssetHandle &)>;
|
||||||
/**
|
/**
|
||||||
|
* Iterate the currently loaded assets for the referenced asset library, calling \a fn for each
|
||||||
|
* asset. This may be executed while the asset list is loading asynchronously. Assets will then be
|
||||||
|
* included as they get done loading.
|
||||||
|
*
|
||||||
* \warning Never keep the asset handle passed to \a fn outside of \a fn's scope. While iterating,
|
* \warning Never keep the asset handle passed to \a fn outside of \a fn's scope. While iterating,
|
||||||
* the file data wrapped by the asset handle can be freed, since the file cache has a maximum size.
|
* the file data wrapped by the asset handle can be freed, since the file cache has a maximum size.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup edasset
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
struct AssetLibrary;
|
||||||
|
struct AssetMetaData;
|
||||||
|
struct bUUID;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct AssetViewCatalogFilterSettingsHandle AssetViewCatalogFilterSettingsHandle;
|
||||||
|
|
||||||
|
AssetViewCatalogFilterSettingsHandle *asset_view_create_catalog_filter_settings(void);
|
||||||
|
void asset_view_delete_catalog_filter_settings(
|
||||||
|
AssetViewCatalogFilterSettingsHandle **filter_settings_handle);
|
||||||
|
bool asset_view_set_catalog_filter_settings(
|
||||||
|
AssetViewCatalogFilterSettingsHandle *filter_settings_handle,
|
||||||
|
AssetCatalogFilterMode catalog_visibility,
|
||||||
|
bUUID catalog_id);
|
||||||
|
void asset_view_ensure_updated_catalog_filter_data(
|
||||||
|
AssetViewCatalogFilterSettingsHandle *filter_settings_handle,
|
||||||
|
const AssetLibrary *asset_library);
|
||||||
|
bool asset_view_is_asset_visible_in_catalog_filter_settings(
|
||||||
|
const AssetViewCatalogFilterSettingsHandle *filter_settings_handle,
|
||||||
|
const AssetMetaData *asset_data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -29,6 +29,11 @@ const char *ED_asset_handle_get_name(const AssetHandle *asset)
|
||||||
return AS_asset_representation_name_get(asset->file_data->asset);
|
return AS_asset_representation_name_get(asset->file_data->asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *ED_asset_handle_get_identifier(const AssetHandle *asset)
|
||||||
|
{
|
||||||
|
return asset->file_data->relpath;
|
||||||
|
}
|
||||||
|
|
||||||
AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset_handle)
|
AssetMetaData *ED_asset_handle_get_metadata(const AssetHandle *asset_handle)
|
||||||
{
|
{
|
||||||
return AS_asset_representation_metadata_get(asset_handle->file_data->asset);
|
return AS_asset_representation_metadata_get(asset_handle->file_data->asset);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "AS_asset_library.hh"
|
#include "AS_asset_library.hh"
|
||||||
|
#include "AS_asset_representation.hh"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
|
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "BKE_icons.h"
|
||||||
#include "BKE_preferences.h"
|
#include "BKE_preferences.h"
|
||||||
|
|
||||||
#include "WM_api.h"
|
#include "WM_api.h"
|
||||||
|
@ -74,32 +76,13 @@ class FileListWrapper {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreviewTimer {
|
|
||||||
/* Non-owning! The Window-Manager registers and owns this. */
|
|
||||||
wmTimer *timer_ = nullptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void ensureRunning(const bContext *C)
|
|
||||||
{
|
|
||||||
if (!timer_) {
|
|
||||||
timer_ = WM_event_add_timer_notifier(
|
|
||||||
CTX_wm_manager(C), CTX_wm_window(C), NC_ASSET | ND_ASSET_LIST_PREVIEW, 0.01);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stop(const bContext *C)
|
|
||||||
{
|
|
||||||
if (timer_) {
|
|
||||||
WM_event_remove_timer_notifier(CTX_wm_manager(C), CTX_wm_window(C), timer_);
|
|
||||||
timer_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AssetList : NonCopyable {
|
class AssetList : NonCopyable {
|
||||||
FileListWrapper filelist_;
|
FileListWrapper filelist_;
|
||||||
|
/** Storage for asset handles, items are lazy-created on request.
|
||||||
|
* Asset handles are stored as a pointer here, to ensure a consistent memory address (address
|
||||||
|
* inside the map changes as the map changes). */
|
||||||
|
mutable Map<uint32_t, std::unique_ptr<AssetHandle>> asset_handle_map_;
|
||||||
AssetLibraryReference library_ref_;
|
AssetLibraryReference library_ref_;
|
||||||
PreviewTimer previews_timer_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AssetList() = delete;
|
AssetList() = delete;
|
||||||
|
@ -109,14 +92,15 @@ class AssetList : NonCopyable {
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
void fetch(const bContext &C);
|
void fetch(const bContext &C);
|
||||||
void ensurePreviewsJob(const bContext *C);
|
void setCatalogFilterSettings(const AssetCatalogFilterSettings &settings);
|
||||||
void clear(bContext *C);
|
void clear(bContext *C);
|
||||||
|
|
||||||
AssetHandle asset_get_by_index(int index) const;
|
AssetHandle *asset_get_by_index(int index) const;
|
||||||
|
|
||||||
bool needsRefetch() const;
|
bool needsRefetch() const;
|
||||||
bool isLoaded() const;
|
bool isLoaded() const;
|
||||||
asset_system::AssetLibrary *asset_library() const;
|
asset_system::AssetLibrary *asset_library() const;
|
||||||
|
AssetHandle &asset_handle_from_file(const FileDirEntry &) const;
|
||||||
void iterate(AssetListIterFn fn) const;
|
void iterate(AssetListIterFn fn) const;
|
||||||
bool listen(const wmNotifier ¬ifier) const;
|
bool listen(const wmNotifier ¬ifier) const;
|
||||||
int size() const;
|
int size() const;
|
||||||
|
@ -167,6 +151,7 @@ void AssetList::fetch(const bContext &C)
|
||||||
if (filelist_needs_force_reset(files)) {
|
if (filelist_needs_force_reset(files)) {
|
||||||
filelist_readjob_stop(files, CTX_wm_manager(&C));
|
filelist_readjob_stop(files, CTX_wm_manager(&C));
|
||||||
filelist_clear_from_reset_tag(files);
|
filelist_clear_from_reset_tag(files);
|
||||||
|
asset_handle_map_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filelist_needs_reading(files)) {
|
if (filelist_needs_reading(files)) {
|
||||||
|
@ -178,6 +163,12 @@ void AssetList::fetch(const bContext &C)
|
||||||
filelist_filter(files);
|
filelist_filter(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetList::setCatalogFilterSettings(const AssetCatalogFilterSettings &settings)
|
||||||
|
{
|
||||||
|
filelist_set_asset_catalog_filter_options(
|
||||||
|
filelist_, (AssetCatalogFilterMode)settings.filter_mode, &settings.active_catalog_id);
|
||||||
|
}
|
||||||
|
|
||||||
bool AssetList::needsRefetch() const
|
bool AssetList::needsRefetch() const
|
||||||
{
|
{
|
||||||
return filelist_needs_force_reset(filelist_) || filelist_needs_reading(filelist_);
|
return filelist_needs_force_reset(filelist_) || filelist_needs_reading(filelist_);
|
||||||
|
@ -193,6 +184,15 @@ asset_system::AssetLibrary *AssetList::asset_library() const
|
||||||
return reinterpret_cast<asset_system::AssetLibrary *>(filelist_asset_library(filelist_));
|
return reinterpret_cast<asset_system::AssetLibrary *>(filelist_asset_library(filelist_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssetHandle &AssetList::asset_handle_from_file(const FileDirEntry &file) const
|
||||||
|
{
|
||||||
|
AssetHandle &asset = *asset_handle_map_.lookup_or_add(
|
||||||
|
file.uid, std::make_unique<AssetHandle>(AssetHandle{&file}));
|
||||||
|
/* The file is recreated while loading, update the pointer here. */
|
||||||
|
asset.file_data = &file;
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
void AssetList::iterate(AssetListIterFn fn) const
|
void AssetList::iterate(AssetListIterFn fn) const
|
||||||
{
|
{
|
||||||
FileList *files = filelist_;
|
FileList *files = filelist_;
|
||||||
|
@ -204,7 +204,7 @@ void AssetList::iterate(AssetListIterFn fn) const
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetHandle asset_handle = {file};
|
AssetHandle &asset_handle = asset_handle_from_file(*file);
|
||||||
if (!fn(asset_handle)) {
|
if (!fn(asset_handle)) {
|
||||||
/* If the callback returns false, we stop iterating. */
|
/* If the callback returns false, we stop iterating. */
|
||||||
break;
|
break;
|
||||||
|
@ -212,30 +212,6 @@ void AssetList::iterate(AssetListIterFn fn) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetList::ensurePreviewsJob(const bContext *C)
|
|
||||||
{
|
|
||||||
FileList *files = filelist_;
|
|
||||||
int numfiles = filelist_files_ensure(files);
|
|
||||||
|
|
||||||
filelist_cache_previews_set(files, true);
|
|
||||||
filelist_file_cache_slidingwindow_set(files, 256);
|
|
||||||
/* TODO fetch all previews for now. */
|
|
||||||
filelist_file_cache_block(files, numfiles / 2);
|
|
||||||
filelist_cache_previews_update(files);
|
|
||||||
|
|
||||||
{
|
|
||||||
const bool previews_running = filelist_cache_previews_running(files) &&
|
|
||||||
!filelist_cache_previews_done(files);
|
|
||||||
if (previews_running) {
|
|
||||||
previews_timer_.ensureRunning(C);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Preview is not running, no need to keep generating update events! */
|
|
||||||
previews_timer_.stop(C);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetList::clear(bContext *C)
|
void AssetList::clear(bContext *C)
|
||||||
{
|
{
|
||||||
/* Based on #ED_fileselect_clear() */
|
/* Based on #ED_fileselect_clear() */
|
||||||
|
@ -244,13 +220,18 @@ void AssetList::clear(bContext *C)
|
||||||
filelist_readjob_stop(files, CTX_wm_manager(C));
|
filelist_readjob_stop(files, CTX_wm_manager(C));
|
||||||
filelist_freelib(files);
|
filelist_freelib(files);
|
||||||
filelist_clear(files);
|
filelist_clear(files);
|
||||||
|
asset_handle_map_.clear();
|
||||||
|
|
||||||
WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST, nullptr);
|
WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetHandle AssetList::asset_get_by_index(int index) const
|
AssetHandle *AssetList::asset_get_by_index(int index) const
|
||||||
{
|
{
|
||||||
return {filelist_file(filelist_, index)};
|
FileDirEntry *file = filelist_file(filelist_, index);
|
||||||
|
if (!file) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &asset_handle_from_file(*file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,7 +247,11 @@ bool AssetList::listen(const wmNotifier ¬ifier) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NC_ASSET:
|
case NC_ASSET:
|
||||||
if (ELEM(notifier.data, ND_ASSET_LIST, ND_ASSET_LIST_READING, ND_ASSET_LIST_PREVIEW)) {
|
if (ELEM(notifier.data, ND_ASSET_LIST)) {
|
||||||
|
filelist_tag_needs_filtering(filelist_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ELEM(notifier.data, ND_ASSET_LIST_READING)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (ELEM(notifier.action, NA_ADDED, NA_REMOVED, NA_EDITED)) {
|
if (ELEM(notifier.action, NA_ADDED, NA_REMOVED, NA_EDITED)) {
|
||||||
|
@ -438,13 +423,12 @@ bool ED_assetlist_is_loaded(const AssetLibraryReference *library_reference)
|
||||||
return list->isLoaded();
|
return list->isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ED_assetlist_ensure_previews_job(const AssetLibraryReference *library_reference,
|
void ED_assetlist_catalog_filter_set(const struct AssetLibraryReference *library_reference,
|
||||||
const bContext *C)
|
const struct AssetCatalogFilterSettings *settings)
|
||||||
{
|
{
|
||||||
|
|
||||||
AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
||||||
if (list) {
|
if (list) {
|
||||||
list->ensurePreviewsJob(C);
|
list->setCatalogFilterSettings(*settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,13 +463,44 @@ asset_system::AssetLibrary *ED_assetlist_library_get_once_available(
|
||||||
return list->asset_library();
|
return list->asset_library();
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetHandle ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
AssetHandle *ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
||||||
int asset_index)
|
int asset_index)
|
||||||
{
|
{
|
||||||
const AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
const AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
||||||
return list->asset_get_by_index(asset_index);
|
return list->asset_get_by_index(asset_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreviewImage *ED_assetlist_asset_preview_request(const AssetLibraryReference *library_reference,
|
||||||
|
AssetHandle *asset_handle)
|
||||||
|
{
|
||||||
|
if (asset_handle->preview) {
|
||||||
|
return asset_handle->preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ID *local_id = ED_asset_handle_get_local_id(asset_handle)) {
|
||||||
|
asset_handle->preview = BKE_previewimg_id_get(local_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *asset_identifier = ED_asset_handle_get_identifier(asset_handle);
|
||||||
|
const int source = filelist_preview_source_get(asset_handle->file_data->typeflag);
|
||||||
|
const std::string asset_path = AS_asset_representation_full_path_get(
|
||||||
|
asset_handle->file_data->asset);
|
||||||
|
|
||||||
|
asset_handle->preview = BKE_previewimg_cached_thumbnail_read(
|
||||||
|
asset_identifier, asset_path.c_str(), source, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return asset_handle->preview;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ED_assetlist_asset_preview_icon_id_request(const AssetLibraryReference *library_reference,
|
||||||
|
AssetHandle *asset_handle)
|
||||||
|
{
|
||||||
|
PreviewImage *preview = ED_assetlist_asset_preview_request(library_reference, asset_handle);
|
||||||
|
ID *local_id = ED_asset_handle_get_local_id(asset_handle);
|
||||||
|
return BKE_icon_preview_ensure(local_id, preview);
|
||||||
|
}
|
||||||
|
|
||||||
ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
|
ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
|
||||||
{
|
{
|
||||||
ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data);
|
ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data);
|
||||||
|
@ -496,6 +511,15 @@ ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle)
|
||||||
return filelist_geticon_image_ex(asset_handle->file_data);
|
return filelist_geticon_image_ex(asset_handle->file_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssetLibrary *ED_assetlist_library_get(const AssetLibraryReference *library_reference)
|
||||||
|
{
|
||||||
|
AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
||||||
|
if (list) {
|
||||||
|
return reinterpret_cast<AssetLibrary *>(list->asset_library());
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool ED_assetlist_listen(const AssetLibraryReference *library_reference,
|
bool ED_assetlist_listen(const AssetLibraryReference *library_reference,
|
||||||
const wmNotifier *notifier)
|
const wmNotifier *notifier)
|
||||||
{
|
{
|
||||||
|
|
|
@ -430,13 +430,24 @@ static void ASSET_OT_library_refresh(struct wmOperatorType *ot)
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static AssetLibrary *get_asset_library(const bContext *C)
|
||||||
|
{
|
||||||
|
if (const SpaceFile *sfile = CTX_wm_space_file(C)) {
|
||||||
|
return ED_fileselect_active_asset_library_get(sfile);
|
||||||
|
}
|
||||||
|
if (const AssetLibraryReference *library_ref = CTX_wm_asset_library_ref(C)) {
|
||||||
|
return ED_assetlist_library_get(library_ref);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static bool asset_catalog_operator_poll(bContext *C)
|
static bool asset_catalog_operator_poll(bContext *C)
|
||||||
{
|
{
|
||||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
const SpaceFile *sfile = CTX_wm_space_file(C);
|
||||||
if (!sfile) {
|
if (!sfile) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
const AssetLibrary *asset_library = get_asset_library(C);
|
||||||
if (!asset_library) {
|
if (!asset_library) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -449,16 +460,20 @@ static bool asset_catalog_operator_poll(bContext *C)
|
||||||
|
|
||||||
static int asset_catalog_new_exec(bContext *C, wmOperator *op)
|
static int asset_catalog_new_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
AssetLibrary *asset_library = get_asset_library(C);
|
||||||
struct AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
|
||||||
char *parent_path = RNA_string_get_alloc(op->ptr, "parent_path", nullptr, 0, nullptr);
|
char *parent_path = RNA_string_get_alloc(op->ptr, "parent_path", nullptr, 0, nullptr);
|
||||||
|
|
||||||
blender::asset_system::AssetCatalog *new_catalog = ED_asset_catalog_add(
|
blender::asset_system::AssetCatalog *new_catalog = ED_asset_catalog_add(
|
||||||
asset_library, "Catalog", parent_path);
|
asset_library, "Catalog", parent_path);
|
||||||
|
|
||||||
if (sfile) {
|
if (SpaceFile *sfile = CTX_wm_space_file(C)) {
|
||||||
ED_fileselect_activate_asset_catalog(sfile, new_catalog->catalog_id);
|
ED_fileselect_activate_asset_catalog(sfile, new_catalog->catalog_id);
|
||||||
}
|
}
|
||||||
|
else if (SpaceAssets *sassets = CTX_wm_space_assets(C)) {
|
||||||
|
/* TODO how can we select the catalog here in a nice way, without being space dependent? Idea:
|
||||||
|
* use an operator macro instead? */
|
||||||
|
UNUSED_VARS(sassets);
|
||||||
|
}
|
||||||
|
|
||||||
MEM_freeN(parent_path);
|
MEM_freeN(parent_path);
|
||||||
|
|
||||||
|
@ -489,8 +504,7 @@ static void ASSET_OT_catalog_new(struct wmOperatorType *ot)
|
||||||
|
|
||||||
static int asset_catalog_delete_exec(bContext *C, wmOperator *op)
|
static int asset_catalog_delete_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
AssetLibrary *asset_library = get_asset_library(C);
|
||||||
struct AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
|
||||||
char *catalog_id_str = RNA_string_get_alloc(op->ptr, "catalog_id", nullptr, 0, nullptr);
|
char *catalog_id_str = RNA_string_get_alloc(op->ptr, "catalog_id", nullptr, 0, nullptr);
|
||||||
asset_system::CatalogID catalog_id;
|
asset_system::CatalogID catalog_id;
|
||||||
if (!BLI_uuid_parse_string(&catalog_id, catalog_id_str)) {
|
if (!BLI_uuid_parse_string(&catalog_id, catalog_id_str)) {
|
||||||
|
@ -525,13 +539,16 @@ static void ASSET_OT_catalog_delete(struct wmOperatorType *ot)
|
||||||
|
|
||||||
static asset_system::AssetCatalogService *get_catalog_service(bContext *C)
|
static asset_system::AssetCatalogService *get_catalog_service(bContext *C)
|
||||||
{
|
{
|
||||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
if (const SpaceFile *sfile = CTX_wm_space_file(C)) {
|
||||||
if (!sfile) {
|
AssetLibrary *asset_lib = ED_fileselect_active_asset_library_get(sfile);
|
||||||
return nullptr;
|
return AS_asset_library_get_catalog_service(asset_lib);
|
||||||
|
}
|
||||||
|
if (const AssetLibraryReference *library_ref = CTX_wm_asset_library_ref(C)) {
|
||||||
|
AssetLibrary *asset_lib = ED_assetlist_library_get(library_ref);
|
||||||
|
return AS_asset_library_get_catalog_service(asset_lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetLibrary *asset_lib = ED_fileselect_active_asset_library_get(sfile);
|
return nullptr;
|
||||||
return AS_asset_library_get_catalog_service(asset_lib);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asset_catalog_undo_exec(bContext *C, wmOperator * /*op*/)
|
static int asset_catalog_undo_exec(bContext *C, wmOperator * /*op*/)
|
||||||
|
@ -542,7 +559,7 @@ static int asset_catalog_undo_exec(bContext *C, wmOperator * /*op*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
catalog_service->undo();
|
catalog_service->undo();
|
||||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
WM_event_add_notifier(C, NC_ASSET | ND_ASSET_CATALOGS, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,7 +589,7 @@ static int asset_catalog_redo_exec(bContext *C, wmOperator * /*op*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
catalog_service->redo();
|
catalog_service->redo();
|
||||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
WM_event_add_notifier(C, NC_ASSET | ND_ASSET_CATALOGS, nullptr);
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,8 +666,7 @@ static bool asset_catalogs_save_poll(bContext *C)
|
||||||
|
|
||||||
static int asset_catalogs_save_exec(bContext *C, wmOperator * /*op*/)
|
static int asset_catalogs_save_exec(bContext *C, wmOperator * /*op*/)
|
||||||
{
|
{
|
||||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
::AssetLibrary *asset_library = get_asset_library(C);
|
||||||
::AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
|
||||||
|
|
||||||
ED_asset_catalogs_save_from_main_path(asset_library, CTX_data_main(C));
|
ED_asset_catalogs_save_from_main_path(asset_library, CTX_data_main(C));
|
||||||
|
|
||||||
|
@ -685,11 +701,12 @@ static bool has_external_files(Main *bmain, struct ReportList *reports);
|
||||||
static bool asset_bundle_install_poll(bContext *C)
|
static bool asset_bundle_install_poll(bContext *C)
|
||||||
{
|
{
|
||||||
/* This operator only works when the asset browser is set to Current File. */
|
/* This operator only works when the asset browser is set to Current File. */
|
||||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
const AssetLibraryReference *asset_library_ref = CTX_wm_asset_library_ref(C);
|
||||||
if (sfile == nullptr) {
|
if (asset_library_ref == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ED_fileselect_is_local_asset_library(sfile)) {
|
|
||||||
|
if (asset_library_ref->type == ASSET_LIBRARY_LOCAL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup edasset
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "AS_asset_catalog.hh"
|
||||||
|
#include "AS_asset_library.hh"
|
||||||
|
|
||||||
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "ED_asset_view_catalog_filter.h"
|
||||||
|
|
||||||
|
namespace asset_system = blender::asset_system;
|
||||||
|
|
||||||
|
struct AssetViewCatalogFilter {
|
||||||
|
AssetCatalogFilterSettings filter_settings;
|
||||||
|
std::unique_ptr<asset_system::AssetCatalogFilter> catalog_filter;
|
||||||
|
};
|
||||||
|
|
||||||
|
AssetViewCatalogFilterSettingsHandle *asset_view_create_catalog_filter_settings()
|
||||||
|
{
|
||||||
|
AssetViewCatalogFilter *filter_settings = MEM_new<AssetViewCatalogFilter>(__func__);
|
||||||
|
return reinterpret_cast<AssetViewCatalogFilterSettingsHandle *>(filter_settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void asset_view_delete_catalog_filter_settings(
|
||||||
|
AssetViewCatalogFilterSettingsHandle **filter_settings_handle)
|
||||||
|
{
|
||||||
|
AssetViewCatalogFilter **filter_settings = reinterpret_cast<AssetViewCatalogFilter **>(
|
||||||
|
filter_settings_handle);
|
||||||
|
MEM_delete(*filter_settings);
|
||||||
|
*filter_settings = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool asset_view_set_catalog_filter_settings(
|
||||||
|
AssetViewCatalogFilterSettingsHandle *filter_settings_handle,
|
||||||
|
AssetCatalogFilterMode catalog_visibility,
|
||||||
|
::bUUID catalog_id)
|
||||||
|
{
|
||||||
|
AssetViewCatalogFilter *filter_settings = reinterpret_cast<AssetViewCatalogFilter *>(
|
||||||
|
filter_settings_handle);
|
||||||
|
bool needs_update = false;
|
||||||
|
|
||||||
|
if (filter_settings->filter_settings.filter_mode != catalog_visibility) {
|
||||||
|
filter_settings->filter_settings.filter_mode = catalog_visibility;
|
||||||
|
needs_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_settings->filter_settings.filter_mode == ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG &&
|
||||||
|
!BLI_uuid_equal(filter_settings->filter_settings.active_catalog_id, catalog_id)) {
|
||||||
|
filter_settings->filter_settings.active_catalog_id = catalog_id;
|
||||||
|
needs_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return needs_update;
|
||||||
|
}
|
||||||
|
|
||||||
|
void asset_view_ensure_updated_catalog_filter_data(
|
||||||
|
AssetViewCatalogFilterSettingsHandle *filter_settings_handle,
|
||||||
|
const ::AssetLibrary *asset_library)
|
||||||
|
{
|
||||||
|
AssetViewCatalogFilter *filter_settings = reinterpret_cast<AssetViewCatalogFilter *>(
|
||||||
|
filter_settings_handle);
|
||||||
|
const asset_system::AssetCatalogService *catalog_service = AS_asset_library_get_catalog_service(
|
||||||
|
asset_library);
|
||||||
|
|
||||||
|
if (filter_settings->filter_settings.filter_mode != ASSET_CATALOG_SHOW_ALL_ASSETS) {
|
||||||
|
filter_settings->catalog_filter = std::make_unique<asset_system::AssetCatalogFilter>(
|
||||||
|
catalog_service->create_catalog_filter(
|
||||||
|
filter_settings->filter_settings.active_catalog_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool asset_view_is_asset_visible_in_catalog_filter_settings(
|
||||||
|
const AssetViewCatalogFilterSettingsHandle *filter_settings_handle,
|
||||||
|
const AssetMetaData *asset_data)
|
||||||
|
{
|
||||||
|
const AssetViewCatalogFilter *filter_settings = reinterpret_cast<const AssetViewCatalogFilter *>(
|
||||||
|
filter_settings_handle);
|
||||||
|
|
||||||
|
switch (filter_settings->filter_settings.filter_mode) {
|
||||||
|
case ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG:
|
||||||
|
return !filter_settings->catalog_filter->is_known(asset_data->catalog_id);
|
||||||
|
case ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG:
|
||||||
|
return filter_settings->catalog_filter->contains(asset_data->catalog_id);
|
||||||
|
case ASSET_CATALOG_SHOW_ALL_ASSETS:
|
||||||
|
/* All asset files should be visible. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ void ED_spacemacros_init(void);
|
||||||
* Calls for registering default spaces, only called once, from #ED_spacetypes_init
|
* Calls for registering default spaces, only called once, from #ED_spacetypes_init
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
|
void ED_spacetype_assets(void);
|
||||||
void ED_spacetype_outliner(void);
|
void ED_spacetype_outliner(void);
|
||||||
void ED_spacetype_view3d(void);
|
void ED_spacetype_view3d(void);
|
||||||
void ED_spacetype_ipo(void);
|
void ED_spacetype_ipo(void);
|
||||||
|
|
|
@ -4549,8 +4549,8 @@ static void ui_litem_layout_grid_flow(uiLayout *litem)
|
||||||
BLI_assert(gflow->tot_columns > 0);
|
BLI_assert(gflow->tot_columns > 0);
|
||||||
BLI_assert(gflow->tot_rows > 0);
|
BLI_assert(gflow->tot_rows > 0);
|
||||||
|
|
||||||
const int space_x = style->columnspace;
|
const int space_x = litem->align ? 0 : style->columnspace;
|
||||||
const int space_y = style->buttonspacey;
|
const int space_y = litem->align ? 0 : style->buttonspacey;
|
||||||
|
|
||||||
blender::Array<int, 64> widths(gflow->tot_columns);
|
blender::Array<int, 64> widths(gflow->tot_columns);
|
||||||
blender::Array<int, 64> heights(gflow->tot_rows);
|
blender::Array<int, 64> heights(gflow->tot_rows);
|
||||||
|
|
|
@ -38,7 +38,9 @@ struct AssetViewListData {
|
||||||
bool show_names;
|
bool show_names;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle)
|
static void asset_view_item_but_drag_set(uiBut *but,
|
||||||
|
AssetViewListData *list_data,
|
||||||
|
AssetHandle *asset_handle)
|
||||||
{
|
{
|
||||||
ID *id = ED_asset_handle_get_local_id(asset_handle);
|
ID *id = ED_asset_handle_get_local_id(asset_handle);
|
||||||
if (id != nullptr) {
|
if (id != nullptr) {
|
||||||
|
@ -54,13 +56,14 @@ static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle)
|
||||||
|
|
||||||
if (blend_path[0]) {
|
if (blend_path[0]) {
|
||||||
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
|
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
|
||||||
UI_but_drag_set_asset(but,
|
UI_but_drag_set_asset(
|
||||||
asset_handle,
|
but,
|
||||||
BLI_strdup(blend_path),
|
asset_handle,
|
||||||
import_method,
|
BLI_strdup(blend_path),
|
||||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
import_method,
|
||||||
imbuf,
|
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, asset_handle),
|
||||||
1.0f);
|
imbuf,
|
||||||
|
1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +80,8 @@ static void asset_view_draw_item(uiList *ui_list,
|
||||||
{
|
{
|
||||||
AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
|
AssetViewListData *list_data = (AssetViewListData *)ui_list->dyn_data->customdata;
|
||||||
|
|
||||||
AssetHandle asset_handle = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
AssetHandle asset_handle = *ED_assetlist_asset_get_by_index(&list_data->asset_library_ref,
|
||||||
|
index);
|
||||||
|
|
||||||
PointerRNA file_ptr;
|
PointerRNA file_ptr;
|
||||||
RNA_pointer_create(&list_data->screen->id,
|
RNA_pointer_create(&list_data->screen->id,
|
||||||
|
@ -88,30 +92,31 @@ static void asset_view_draw_item(uiList *ui_list,
|
||||||
|
|
||||||
uiBlock *block = uiLayoutGetBlock(layout);
|
uiBlock *block = uiLayoutGetBlock(layout);
|
||||||
const bool show_names = list_data->show_names;
|
const bool show_names = list_data->show_names;
|
||||||
/* TODO ED_fileselect_init_layout(). Share somehow? */
|
const int size_x = UI_preview_tile_size_x();
|
||||||
const float size_x = (96.0f / 20.0f) * UI_UNIT_X;
|
const int size_y = show_names ? UI_preview_tile_size_y() : UI_preview_tile_size_y_no_label();
|
||||||
const float size_y = (96.0f / 20.0f) * UI_UNIT_Y - (show_names ? 0 : UI_UNIT_Y);
|
uiBut *but = uiDefIconTextBut(
|
||||||
uiBut *but = uiDefIconTextBut(block,
|
block,
|
||||||
UI_BTYPE_PREVIEW_TILE,
|
UI_BTYPE_PREVIEW_TILE,
|
||||||
0,
|
0,
|
||||||
ED_asset_handle_get_preview_icon_id(&asset_handle),
|
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, &asset_handle),
|
||||||
show_names ? ED_asset_handle_get_name(&asset_handle) : "",
|
show_names ? ED_asset_handle_get_name(&asset_handle) : "",
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
size_x,
|
size_x,
|
||||||
size_y,
|
size_y,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"");
|
"");
|
||||||
ui_def_but_icon(but,
|
ui_def_but_icon(
|
||||||
ED_asset_handle_get_preview_icon_id(&asset_handle),
|
but,
|
||||||
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, &asset_handle),
|
||||||
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
||||||
|
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
||||||
if (!ui_list->dyn_data->custom_drag_optype) {
|
if (!ui_list->dyn_data->custom_drag_optype) {
|
||||||
asset_view_item_but_drag_set(but, &asset_handle);
|
asset_view_item_but_drag_set(but, list_data, &asset_handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +135,8 @@ static void asset_view_filter_items(uiList *ui_list,
|
||||||
C,
|
C,
|
||||||
[&name_filter, list_data, &filter_settings](
|
[&name_filter, list_data, &filter_settings](
|
||||||
const PointerRNA &itemptr, blender::StringRefNull name, int index) {
|
const PointerRNA &itemptr, blender::StringRefNull name, int index) {
|
||||||
AssetHandle asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
AssetHandle *asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
||||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
if (!ED_asset_filter_matches_asset(&filter_settings, asset)) {
|
||||||
return UI_LIST_ITEM_NEVER_SHOW;
|
return UI_LIST_ITEM_NEVER_SHOW;
|
||||||
}
|
}
|
||||||
return name_filter(itemptr, name, index);
|
return name_filter(itemptr, name, index);
|
||||||
|
@ -139,8 +144,8 @@ static void asset_view_filter_items(uiList *ui_list,
|
||||||
dataptr,
|
dataptr,
|
||||||
propname,
|
propname,
|
||||||
[list_data](const PointerRNA & /*itemptr*/, int index) -> std::string {
|
[list_data](const PointerRNA & /*itemptr*/, int index) -> std::string {
|
||||||
AssetHandle asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
AssetHandle *asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
||||||
return ED_asset_handle_get_name(&asset);
|
return ED_asset_handle_get_name(asset);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +253,6 @@ void uiTemplateAssetView(uiLayout *layout,
|
||||||
}
|
}
|
||||||
|
|
||||||
ED_assetlist_storage_fetch(&asset_library_ref, C);
|
ED_assetlist_storage_fetch(&asset_library_ref, C);
|
||||||
ED_assetlist_ensure_previews_job(&asset_library_ref, C);
|
|
||||||
const int tot_items = ED_assetlist_size(&asset_library_ref);
|
const int tot_items = ED_assetlist_size(&asset_library_ref);
|
||||||
|
|
||||||
populate_asset_collection(asset_library_ref, *assets_dataptr, assets_propname);
|
populate_asset_collection(asset_library_ref, *assets_dataptr, assets_propname);
|
||||||
|
|
|
@ -643,6 +643,8 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
||||||
SPACE_MENU_NOP(SPACE_STATUSBAR);
|
SPACE_MENU_NOP(SPACE_STATUSBAR);
|
||||||
SPACE_MENU_NOP(SPACE_TOPBAR);
|
SPACE_MENU_NOP(SPACE_TOPBAR);
|
||||||
SPACE_MENU_NOP(SPACE_SPREADSHEET);
|
SPACE_MENU_NOP(SPACE_SPREADSHEET);
|
||||||
|
/* TODO */
|
||||||
|
SPACE_MENU_NOP(SPACE_ASSETS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < idname_array_len; i++) {
|
for (int i = 0; i < idname_array_len; i++) {
|
||||||
|
|
|
@ -5464,13 +5464,17 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle,
|
||||||
eFontStyle_Align text_align)
|
eFontStyle_Align text_align)
|
||||||
{
|
{
|
||||||
rcti trect = *rect;
|
rcti trect = *rect;
|
||||||
const float text_size = UI_UNIT_Y;
|
|
||||||
float font_dims[2] = {0.0f, 0.0f};
|
float font_dims[2] = {0.0f, 0.0f};
|
||||||
const bool has_text = name && name[0];
|
const bool has_text = name && name[0];
|
||||||
|
const float padding = PREVIEW_PAD;
|
||||||
|
|
||||||
if (has_text) {
|
if (has_text) {
|
||||||
|
UI_fontstyle_set(fstyle);
|
||||||
|
BLF_width_and_height(
|
||||||
|
fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
|
||||||
|
|
||||||
/* draw icon in rect above the space reserved for the label */
|
/* draw icon in rect above the space reserved for the label */
|
||||||
rect->ymin += text_size;
|
rect->ymin += round_fl_to_int(font_dims[1] + 2 * padding);
|
||||||
}
|
}
|
||||||
GPU_blend(GPU_BLEND_ALPHA);
|
GPU_blend(GPU_BLEND_ALPHA);
|
||||||
widget_draw_preview(BIFIconID(iconid), 1.0f, rect);
|
widget_draw_preview(BIFIconID(iconid), 1.0f, rect);
|
||||||
|
@ -5480,15 +5484,9 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLF_width_and_height(
|
|
||||||
fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
|
|
||||||
|
|
||||||
/* text rect */
|
/* text rect */
|
||||||
trect.ymin += U.widget_unit / 2;
|
BLI_rcti_pad(&trect, -padding * 2, -padding * 2);
|
||||||
trect.ymax = trect.ymin + font_dims[1];
|
trect.ymax = round_fl_to_int(trect.ymin + font_dims[1]);
|
||||||
if (trect.xmax > rect->xmax - PREVIEW_PAD) {
|
|
||||||
trect.xmax = rect->xmax - PREVIEW_PAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
char drawstr[UI_MAX_DRAW_STR];
|
char drawstr[UI_MAX_DRAW_STR];
|
||||||
|
|
|
@ -140,6 +140,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
|
||||||
case SPACE_SPREADSHEET:
|
case SPACE_SPREADSHEET:
|
||||||
ts = &btheme->space_spreadsheet;
|
ts = &btheme->space_spreadsheet;
|
||||||
break;
|
break;
|
||||||
|
case SPACE_ASSETS:
|
||||||
|
ts = &btheme->space_assets;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ts = &btheme->space_view3d;
|
ts = &btheme->space_view3d;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -23,6 +23,7 @@ set(SRC
|
||||||
set(LIB
|
set(LIB
|
||||||
bf_editor_geometry
|
bf_editor_geometry
|
||||||
bf_editor_space_action
|
bf_editor_space_action
|
||||||
|
bf_editor_space_assets
|
||||||
bf_editor_space_buttons
|
bf_editor_space_buttons
|
||||||
bf_editor_space_clip
|
bf_editor_space_clip
|
||||||
bf_editor_space_console
|
bf_editor_space_console
|
||||||
|
|
|
@ -63,6 +63,7 @@ void ED_spacetypes_init(void)
|
||||||
U.widget_unit = 20;
|
U.widget_unit = 20;
|
||||||
|
|
||||||
/* Create space types. */
|
/* Create space types. */
|
||||||
|
ED_spacetype_assets();
|
||||||
ED_spacetype_outliner();
|
ED_spacetype_outliner();
|
||||||
ED_spacetype_view3d();
|
ED_spacetype_view3d();
|
||||||
ED_spacetype_ipo();
|
ED_spacetype_ipo();
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
set(INC
|
||||||
|
../include
|
||||||
|
../../asset_system
|
||||||
|
../../blenfont
|
||||||
|
../../blenkernel
|
||||||
|
../../blenlib
|
||||||
|
../../blentranslation
|
||||||
|
../../gpu
|
||||||
|
../../makesdna
|
||||||
|
../../makesrna
|
||||||
|
../../windowmanager
|
||||||
|
../../../../intern/glew-mx
|
||||||
|
../../../../intern/guardedalloc
|
||||||
|
# RNA_prototypes.h
|
||||||
|
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SRC
|
||||||
|
asset_browser_draw.cc
|
||||||
|
asset_browser_ops.cc
|
||||||
|
asset_browser_panels.cc
|
||||||
|
asset_catalog_tree_view.cc
|
||||||
|
asset_view.cc
|
||||||
|
space_assets.cc
|
||||||
|
|
||||||
|
asset_browser_intern.hh
|
||||||
|
asset_view.hh
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LIB
|
||||||
|
)
|
||||||
|
|
||||||
|
blender_add_lib(bf_editor_space_assets "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||||
|
|
||||||
|
# RNA_prototypes.h
|
||||||
|
add_dependencies(bf_editor_space_assets bf_rna)
|
|
@ -0,0 +1,77 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DNA_screen_types.h"
|
||||||
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "BKE_context.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
#include "RNA_prototypes.h"
|
||||||
|
|
||||||
|
#include "UI_interface.h"
|
||||||
|
#include "UI_resources.h"
|
||||||
|
#include "UI_view2d.h"
|
||||||
|
|
||||||
|
#include "asset_browser_intern.hh"
|
||||||
|
#include "asset_view.hh"
|
||||||
|
|
||||||
|
namespace blender::ed::asset_browser {
|
||||||
|
|
||||||
|
} // namespace blender::ed::asset_browser
|
||||||
|
|
||||||
|
using namespace blender::ed::asset_browser;
|
||||||
|
|
||||||
|
void asset_browser_main_region_draw(const bContext *C, ARegion *region)
|
||||||
|
{
|
||||||
|
SpaceAssets *asset_space = CTX_wm_space_assets(C);
|
||||||
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
|
View2D *v2d = ®ion->v2d;
|
||||||
|
|
||||||
|
UI_ThemeClearColor(TH_BACK);
|
||||||
|
|
||||||
|
UI_view2d_view_ortho(v2d);
|
||||||
|
|
||||||
|
const uiStyle *style = UI_style_get_dpi();
|
||||||
|
const float padding = style->panelouter;
|
||||||
|
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
|
||||||
|
uiLayout *layout = UI_block_layout(
|
||||||
|
block,
|
||||||
|
UI_LAYOUT_VERTICAL,
|
||||||
|
UI_LAYOUT_PANEL,
|
||||||
|
padding,
|
||||||
|
-padding,
|
||||||
|
/* 3x (instead of 2x) padding to add extra space for the scrollbar on the right. */
|
||||||
|
region->winx - 3 * padding,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
style);
|
||||||
|
|
||||||
|
PointerRNA asset_space_ptr;
|
||||||
|
RNA_pointer_create(&screen->id, &RNA_SpaceAssetBrowser, asset_space, &asset_space_ptr);
|
||||||
|
PropertyRNA *active_asset_idx_prop = RNA_struct_find_property(&asset_space_ptr,
|
||||||
|
"active_asset_idx");
|
||||||
|
|
||||||
|
asset_view_create_in_layout(*C,
|
||||||
|
asset_space->asset_library_ref,
|
||||||
|
asset_space->catalog_filter,
|
||||||
|
asset_space_ptr,
|
||||||
|
active_asset_idx_prop,
|
||||||
|
*v2d,
|
||||||
|
*layout);
|
||||||
|
|
||||||
|
/* Update main region View2d dimensions. */
|
||||||
|
int layout_width, layout_height;
|
||||||
|
UI_block_layout_resolve(block, &layout_width, &layout_height);
|
||||||
|
UI_view2d_totRect_set(v2d, layout_width, layout_height);
|
||||||
|
|
||||||
|
UI_block_end(C, block);
|
||||||
|
UI_block_draw(C, block);
|
||||||
|
|
||||||
|
/* reset view matrix */
|
||||||
|
UI_view2d_view_restore(C);
|
||||||
|
UI_view2d_scrollers_draw(v2d, nullptr);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void asset_browser_operatortypes();
|
||||||
|
|
||||||
|
struct ARegion;
|
||||||
|
struct ARegionType;
|
||||||
|
struct AssetLibrary;
|
||||||
|
struct bContext;
|
||||||
|
struct PointerRNA;
|
||||||
|
struct PropertyRNA;
|
||||||
|
struct uiLayout;
|
||||||
|
struct wmMsgBus;
|
||||||
|
|
||||||
|
void asset_browser_main_region_draw(const bContext *C, ARegion *region);
|
||||||
|
|
||||||
|
void asset_browser_navigation_region_panels_register(ARegionType *art);
|
||||||
|
|
||||||
|
void asset_view_create_catalog_tree_view_in_layout(::AssetLibrary *asset_library,
|
||||||
|
uiLayout *layout,
|
||||||
|
PointerRNA *catalog_filter_owner_ptr,
|
||||||
|
PropertyRNA *catalog_filter_prop,
|
||||||
|
wmMsgBus *msg_bus);
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asset_browser_intern.hh"
|
||||||
|
|
||||||
|
void asset_browser_operatortypes() {}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "DNA_screen_types.h"
|
||||||
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "BKE_screen.h"
|
||||||
|
|
||||||
|
#include "BLI_listbase.h"
|
||||||
|
|
||||||
|
#include "BLT_translation.h"
|
||||||
|
|
||||||
|
#include "ED_asset.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
#include "RNA_prototypes.h"
|
||||||
|
|
||||||
|
#include "UI_interface.h"
|
||||||
|
#include "UI_resources.h"
|
||||||
|
|
||||||
|
#include "WM_api.h"
|
||||||
|
|
||||||
|
#include "asset_browser_intern.hh"
|
||||||
|
|
||||||
|
static void assets_panel_asset_catalog_buttons_draw(const bContext *C, Panel *panel)
|
||||||
|
{
|
||||||
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
|
SpaceAssets *assets_space = CTX_wm_space_assets(C);
|
||||||
|
|
||||||
|
uiLayout *col = uiLayoutColumn(panel->layout, false);
|
||||||
|
uiLayout *row = uiLayoutRow(col, true);
|
||||||
|
|
||||||
|
PointerRNA assets_space_ptr;
|
||||||
|
RNA_pointer_create(&screen->id, &RNA_SpaceAssetBrowser, assets_space, &assets_space_ptr);
|
||||||
|
|
||||||
|
uiItemR(row, &assets_space_ptr, "asset_library_ref", 0, "", ICON_NONE);
|
||||||
|
if (assets_space->asset_library_ref.type == ASSET_LIBRARY_LOCAL) {
|
||||||
|
bContext *mutable_ctx = CTX_copy(C);
|
||||||
|
if (WM_operator_name_poll(mutable_ctx, "asset.bundle_install")) {
|
||||||
|
uiItemS(col);
|
||||||
|
uiItemMenuEnumO(col,
|
||||||
|
mutable_ctx,
|
||||||
|
"asset.bundle_install",
|
||||||
|
"asset_library_ref",
|
||||||
|
"Copy Bundle to Asset Library...",
|
||||||
|
ICON_IMPORT);
|
||||||
|
}
|
||||||
|
CTX_free(mutable_ctx);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uiItemO(row, "", ICON_FILE_REFRESH, "ASSET_OT_library_refresh");
|
||||||
|
}
|
||||||
|
|
||||||
|
uiItemS(col);
|
||||||
|
|
||||||
|
AssetLibrary *library = ED_assetlist_library_get(&assets_space->asset_library_ref);
|
||||||
|
PropertyRNA *catalog_filter_prop = RNA_struct_find_property(&assets_space_ptr, "catalog_filter");
|
||||||
|
|
||||||
|
asset_view_create_catalog_tree_view_in_layout(
|
||||||
|
library, col, &assets_space_ptr, catalog_filter_prop, CTX_wm_message_bus(C));
|
||||||
|
}
|
||||||
|
|
||||||
|
void asset_browser_navigation_region_panels_register(ARegionType *art)
|
||||||
|
{
|
||||||
|
PanelType *pt;
|
||||||
|
|
||||||
|
pt = MEM_cnew<PanelType>("asset browser catalog buttons");
|
||||||
|
strcpy(pt->idname, "FILE_PT_asset_catalog_buttons");
|
||||||
|
strcpy(pt->label, N_("Asset Catalogs"));
|
||||||
|
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||||
|
pt->flag = PANEL_TYPE_NO_HEADER;
|
||||||
|
pt->draw = assets_panel_asset_catalog_buttons_draw;
|
||||||
|
BLI_addtail(&art->paneltypes, pt);
|
||||||
|
}
|
|
@ -0,0 +1,747 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AS_asset_catalog.hh"
|
||||||
|
#include "AS_asset_catalog_tree.hh"
|
||||||
|
#include "AS_asset_library.hh"
|
||||||
|
|
||||||
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "BKE_asset.h"
|
||||||
|
|
||||||
|
#include "BLI_string_ref.hh"
|
||||||
|
|
||||||
|
#include "BLT_translation.h"
|
||||||
|
|
||||||
|
#include "ED_asset.h"
|
||||||
|
#include "ED_undo.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
|
||||||
|
#include "UI_interface.h"
|
||||||
|
#include "UI_interface.hh"
|
||||||
|
#include "UI_resources.h"
|
||||||
|
#include "UI_tree_view.hh"
|
||||||
|
|
||||||
|
#include "RNA_prototypes.h"
|
||||||
|
|
||||||
|
#include "WM_api.h"
|
||||||
|
#include "WM_message.h"
|
||||||
|
#include "WM_types.h"
|
||||||
|
|
||||||
|
#include "asset_browser_intern.hh"
|
||||||
|
|
||||||
|
using namespace blender;
|
||||||
|
using namespace blender::asset_system;
|
||||||
|
|
||||||
|
namespace blender::ed::asset_browser {
|
||||||
|
|
||||||
|
class AssetCatalogTreeViewAllItem;
|
||||||
|
|
||||||
|
class AssetCatalogTreeView : public ui::AbstractTreeView {
|
||||||
|
/** The asset library this catalog tree comes from. May be null when drawing the catalog tree
|
||||||
|
* before the library was read. */
|
||||||
|
::AssetLibrary *asset_library_;
|
||||||
|
/** The asset catalog tree this tree-view represents. */
|
||||||
|
AssetCatalogTree *catalog_tree_;
|
||||||
|
|
||||||
|
PointerRNA catalog_filter_owner_;
|
||||||
|
PropertyRNA &catalog_filter_prop_;
|
||||||
|
/** Used to notify the parts of the UI that display the filtered assets. */
|
||||||
|
wmMsgBus *msg_bus_;
|
||||||
|
|
||||||
|
friend class AssetCatalogTreeViewItem;
|
||||||
|
friend class AssetCatalogDropTarget;
|
||||||
|
friend class AssetCatalogTreeViewAllItem;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetCatalogTreeView(::AssetLibrary *library,
|
||||||
|
const PointerRNA &catalog_filter_owner,
|
||||||
|
PropertyRNA &catalog_filter_prop,
|
||||||
|
wmMsgBus *msg_bus);
|
||||||
|
|
||||||
|
void build_tree() override;
|
||||||
|
bool listen(const wmNotifier ¬ifier) const override;
|
||||||
|
|
||||||
|
void activate_catalog_by_id(asset_system::CatalogID catalog_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ui::BasicTreeViewItem &build_catalog_items_recursive(ui::TreeViewOrItem &view_parent_item,
|
||||||
|
AssetCatalogTreeItem &catalog);
|
||||||
|
|
||||||
|
AssetCatalogTreeViewAllItem &add_all_item();
|
||||||
|
void add_unassigned_item();
|
||||||
|
bool is_active_catalog(CatalogID catalog_id) const;
|
||||||
|
|
||||||
|
AssetCatalogFilterSettings &catalog_filter_settings() const;
|
||||||
|
void notify_catalog_filter_change();
|
||||||
|
void notify_catalog_tree_change();
|
||||||
|
void notify_catalog_assignments_change();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
|
||||||
|
/** The catalog tree item this tree view item represents. */
|
||||||
|
AssetCatalogTreeItem &catalog_item_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog_item);
|
||||||
|
|
||||||
|
void on_activate() override;
|
||||||
|
|
||||||
|
void build_row(uiLayout &row) override;
|
||||||
|
void build_context_menu(bContext &C, uiLayout &column) const override;
|
||||||
|
|
||||||
|
bool supports_renaming() const override;
|
||||||
|
bool rename(StringRefNull new_name) override;
|
||||||
|
|
||||||
|
/** Add drag support for catalog items. */
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDragController> create_drag_controller() const override;
|
||||||
|
/** Add dropping support for catalog items. */
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDropTarget> create_drop_target() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssetCatalogDragController : public ui::AbstractViewItemDragController {
|
||||||
|
AssetCatalogTreeItem &catalog_item_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AssetCatalogDragController(AssetCatalogTreeView &tree_view,
|
||||||
|
AssetCatalogTreeItem &catalog_item);
|
||||||
|
|
||||||
|
int get_drag_type() const override;
|
||||||
|
void *create_drag_data() const override;
|
||||||
|
void on_drag_start() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssetCatalogDropTarget : public ui::AbstractViewItemDropTarget {
|
||||||
|
AssetCatalogTreeItem &catalog_item_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetCatalogDropTarget(AssetCatalogTreeView &tree_view, AssetCatalogTreeItem &catalog_item);
|
||||||
|
|
||||||
|
bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override;
|
||||||
|
std::string drop_tooltip(const wmDrag &drag) const override;
|
||||||
|
bool on_drop(struct bContext *C, const wmDrag &drag) const override;
|
||||||
|
|
||||||
|
::AssetLibrary &get_asset_library() const;
|
||||||
|
|
||||||
|
static AssetCatalog *get_drag_catalog(const wmDrag &drag, const ::AssetLibrary &asset_library);
|
||||||
|
static bool has_droppable_asset(const wmDrag &drag, const char **r_disabled_hint);
|
||||||
|
static bool can_modify_catalogs(const ::AssetLibrary &asset_library,
|
||||||
|
const char **r_disabled_hint);
|
||||||
|
static bool drop_assets_into_catalog(struct bContext *C,
|
||||||
|
AssetCatalogTreeView &tree_view,
|
||||||
|
const wmDrag &drag,
|
||||||
|
CatalogID catalog_id,
|
||||||
|
StringRefNull simple_name = "");
|
||||||
|
/**
|
||||||
|
* \param drop_catalog_id: Can be unset to drop into the root level of the tree.
|
||||||
|
*/
|
||||||
|
static bool drop_asset_catalog_into_catalog(
|
||||||
|
const wmDrag &drag,
|
||||||
|
AssetCatalogTreeView &tree_view,
|
||||||
|
const std::optional<CatalogID> drop_catalog_id = std::nullopt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string drop_tooltip_asset_list(const wmDrag &drag) const;
|
||||||
|
std::string drop_tooltip_asset_catalog(const wmDrag &drag) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Only reason this isn't just `BasicTreeViewItem` is to add a '+' icon for adding a root level
|
||||||
|
* catalog. */
|
||||||
|
class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem {
|
||||||
|
using BasicTreeViewItem::BasicTreeViewItem;
|
||||||
|
|
||||||
|
void build_row(uiLayout &row) override;
|
||||||
|
|
||||||
|
struct DropTarget : public ui::AbstractViewItemDropTarget {
|
||||||
|
DropTarget(AssetCatalogTreeView &tree_view);
|
||||||
|
|
||||||
|
bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override;
|
||||||
|
std::string drop_tooltip(const wmDrag &drag) const override;
|
||||||
|
bool on_drop(struct bContext *C, const wmDrag &drag) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDropTarget> create_drop_target() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem {
|
||||||
|
using BasicTreeViewItem::BasicTreeViewItem;
|
||||||
|
|
||||||
|
struct DropTarget : public ui::AbstractViewItemDropTarget {
|
||||||
|
DropTarget(AssetCatalogTreeView &tree_view);
|
||||||
|
|
||||||
|
bool can_drop(const wmDrag &drag, const char **r_disabled_hint) const override;
|
||||||
|
std::string drop_tooltip(const wmDrag &drag) const override;
|
||||||
|
bool on_drop(struct bContext *C, const wmDrag &drag) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDropTarget> create_drop_target() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
AssetCatalogTreeView::AssetCatalogTreeView(::AssetLibrary *library,
|
||||||
|
const PointerRNA &catalog_filter_owner,
|
||||||
|
PropertyRNA &catalog_filter_prop,
|
||||||
|
wmMsgBus *msg_bus)
|
||||||
|
: asset_library_(library),
|
||||||
|
catalog_tree_(AS_asset_library_get_catalog_tree(library)),
|
||||||
|
catalog_filter_owner_(catalog_filter_owner),
|
||||||
|
catalog_filter_prop_(catalog_filter_prop),
|
||||||
|
msg_bus_(msg_bus)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeView::build_tree()
|
||||||
|
{
|
||||||
|
AssetCatalogTreeViewAllItem &all_item = add_all_item();
|
||||||
|
all_item.set_collapsed(false);
|
||||||
|
|
||||||
|
if (catalog_tree_) {
|
||||||
|
/* Pass the "All" item on as parent of the actual catalog items. */
|
||||||
|
catalog_tree_->foreach_root_item([this, &all_item](AssetCatalogTreeItem &item) {
|
||||||
|
build_catalog_items_recursive(all_item, item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
add_unassigned_item();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::BasicTreeViewItem &AssetCatalogTreeView::build_catalog_items_recursive(
|
||||||
|
ui::TreeViewOrItem &view_parent_item, AssetCatalogTreeItem &catalog)
|
||||||
|
{
|
||||||
|
ui::BasicTreeViewItem &view_item = view_parent_item.add_tree_item<AssetCatalogTreeViewItem>(
|
||||||
|
&catalog);
|
||||||
|
view_item.set_is_active_fn(
|
||||||
|
[this, &catalog]() { return is_active_catalog(catalog.get_catalog_id()); });
|
||||||
|
|
||||||
|
catalog.foreach_child([&view_item, this](AssetCatalogTreeItem &child) {
|
||||||
|
build_catalog_items_recursive(view_item, child);
|
||||||
|
});
|
||||||
|
return view_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCatalogTreeViewAllItem &AssetCatalogTreeView::add_all_item()
|
||||||
|
{
|
||||||
|
AssetCatalogTreeViewAllItem &item = add_tree_item<AssetCatalogTreeViewAllItem>(IFACE_("All"));
|
||||||
|
item.set_on_activate_fn([this](ui::BasicTreeViewItem & /*item*/) {
|
||||||
|
catalog_filter_settings().filter_mode = ASSET_CATALOG_SHOW_ALL_ASSETS;
|
||||||
|
notify_catalog_filter_change();
|
||||||
|
});
|
||||||
|
item.set_is_active_fn(
|
||||||
|
[this]() { return catalog_filter_settings().filter_mode == ASSET_CATALOG_SHOW_ALL_ASSETS; });
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeView::add_unassigned_item()
|
||||||
|
{
|
||||||
|
AssetCatalogTreeViewUnassignedItem &item = add_tree_item<AssetCatalogTreeViewUnassignedItem>(
|
||||||
|
IFACE_("Unassigned"), ICON_FILE_HIDDEN);
|
||||||
|
|
||||||
|
item.set_on_activate_fn([this](ui::BasicTreeViewItem & /*item*/) {
|
||||||
|
catalog_filter_settings().filter_mode = ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG;
|
||||||
|
notify_catalog_filter_change();
|
||||||
|
});
|
||||||
|
item.set_is_active_fn([this]() {
|
||||||
|
return catalog_filter_settings().filter_mode == ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeView::activate_catalog_by_id(CatalogID catalog_id)
|
||||||
|
{
|
||||||
|
AssetCatalogFilterSettings &catalog_filter = catalog_filter_settings();
|
||||||
|
catalog_filter.filter_mode = ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG;
|
||||||
|
catalog_filter.active_catalog_id = catalog_id;
|
||||||
|
notify_catalog_filter_change();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeView::is_active_catalog(CatalogID catalog_id) const
|
||||||
|
{
|
||||||
|
const AssetCatalogFilterSettings &catalog_filter = catalog_filter_settings();
|
||||||
|
return (catalog_filter.filter_mode == ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG) &&
|
||||||
|
(catalog_filter.active_catalog_id == catalog_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCatalogFilterSettings &AssetCatalogTreeView::catalog_filter_settings() const
|
||||||
|
{
|
||||||
|
/* Copy so we can pass a non-const pointer to this to RNA functions. */
|
||||||
|
PointerRNA catalog_filter_owner = catalog_filter_owner_;
|
||||||
|
PointerRNA catalog_filter_ptr = RNA_property_pointer_get(&catalog_filter_owner,
|
||||||
|
&catalog_filter_prop_);
|
||||||
|
BLI_assert(catalog_filter_ptr.type == &RNA_AssetCatalogFilterSettings);
|
||||||
|
|
||||||
|
return *reinterpret_cast<AssetCatalogFilterSettings *>(catalog_filter_ptr.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeView::listen(const wmNotifier ¬ifier) const
|
||||||
|
{
|
||||||
|
switch (notifier.category) {
|
||||||
|
case NC_ASSET:
|
||||||
|
if (ELEM(notifier.data, ND_ASSET_CATALOGS, ND_ASSET_LIST_READING)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeView::notify_catalog_filter_change()
|
||||||
|
{
|
||||||
|
WM_msg_publish_rna(msg_bus_, &catalog_filter_owner_, &catalog_filter_prop_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeView::notify_catalog_tree_change()
|
||||||
|
{
|
||||||
|
WM_main_add_notifier(NC_ASSET | ND_ASSET_CATALOGS, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeView::notify_catalog_assignments_change()
|
||||||
|
{
|
||||||
|
WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
AssetCatalogTreeViewItem::AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog_item)
|
||||||
|
: BasicTreeViewItem(catalog_item->get_name()), catalog_item_(*catalog_item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeViewItem::on_activate()
|
||||||
|
{
|
||||||
|
AssetCatalogTreeView &tree_view = static_cast<AssetCatalogTreeView &>(get_tree_view());
|
||||||
|
tree_view.activate_catalog_by_id(catalog_item_.get_catalog_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeViewItem::build_row(uiLayout &row)
|
||||||
|
{
|
||||||
|
const std::string label_override = catalog_item_.has_unsaved_changes() ? (label_ + "*") : label_;
|
||||||
|
add_label(row, label_override);
|
||||||
|
|
||||||
|
if (!is_hovered()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiButViewItem *item_but = view_item_button();
|
||||||
|
PointerRNA *props;
|
||||||
|
|
||||||
|
props = UI_but_extra_operator_icon_add(
|
||||||
|
(uiBut *)item_but, "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD);
|
||||||
|
RNA_string_set(props, "parent_path", catalog_item_.catalog_path().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogTreeViewItem::build_context_menu(bContext &C, uiLayout &column) const
|
||||||
|
{
|
||||||
|
PointerRNA props;
|
||||||
|
|
||||||
|
uiItemFullO(&column,
|
||||||
|
"ASSET_OT_catalog_new",
|
||||||
|
"New Catalog",
|
||||||
|
ICON_NONE,
|
||||||
|
nullptr,
|
||||||
|
WM_OP_INVOKE_DEFAULT,
|
||||||
|
0,
|
||||||
|
&props);
|
||||||
|
RNA_string_set(&props, "parent_path", catalog_item_.catalog_path().c_str());
|
||||||
|
|
||||||
|
char catalog_id_str_buffer[UUID_STRING_LEN] = "";
|
||||||
|
BLI_uuid_format(catalog_id_str_buffer, catalog_item_.get_catalog_id());
|
||||||
|
uiItemFullO(&column,
|
||||||
|
"ASSET_OT_catalog_delete",
|
||||||
|
"Delete Catalog",
|
||||||
|
ICON_NONE,
|
||||||
|
nullptr,
|
||||||
|
WM_OP_INVOKE_DEFAULT,
|
||||||
|
0,
|
||||||
|
&props);
|
||||||
|
RNA_string_set(&props, "catalog_id", catalog_id_str_buffer);
|
||||||
|
uiItemO(&column, "Rename", ICON_NONE, "UI_OT_view_item_rename");
|
||||||
|
|
||||||
|
/* Doesn't actually exist right now, but could be defined in Python. Reason that this isn't done
|
||||||
|
* in Python yet is that catalogs are not exposed in BPY, and we'd somehow pass the clicked on
|
||||||
|
* catalog to the menu draw callback (via context probably). */
|
||||||
|
MenuType *mt = WM_menutype_find("ASSETBROWSER_MT_catalog_context_menu", true);
|
||||||
|
if (!mt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UI_menutype_draw(&C, mt, &column);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeViewItem::supports_renaming() const
|
||||||
|
{
|
||||||
|
const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
|
||||||
|
get_tree_view());
|
||||||
|
return !ED_asset_catalogs_read_only(*tree_view.asset_library_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeViewItem::rename(StringRefNull new_name)
|
||||||
|
{
|
||||||
|
/* Important to keep state. */
|
||||||
|
BasicTreeViewItem::rename(new_name);
|
||||||
|
|
||||||
|
const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
|
||||||
|
get_tree_view());
|
||||||
|
ED_asset_catalog_rename(tree_view.asset_library_, catalog_item_.get_catalog_id(), new_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDropTarget> AssetCatalogTreeViewItem::create_drop_target()
|
||||||
|
{
|
||||||
|
return std::make_unique<AssetCatalogDropTarget>(
|
||||||
|
static_cast<AssetCatalogTreeView &>(get_tree_view()), catalog_item_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDragController> AssetCatalogTreeViewItem::
|
||||||
|
create_drag_controller() const
|
||||||
|
{
|
||||||
|
return std::make_unique<AssetCatalogDragController>(
|
||||||
|
static_cast<AssetCatalogTreeView &>(get_tree_view()), catalog_item_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
AssetCatalogDropTarget::AssetCatalogDropTarget(AssetCatalogTreeView &tree_view,
|
||||||
|
AssetCatalogTreeItem &catalog_item)
|
||||||
|
: ui::AbstractViewItemDropTarget(tree_view), catalog_item_(catalog_item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogDropTarget::can_drop(const wmDrag &drag, const char **r_disabled_hint) const
|
||||||
|
{
|
||||||
|
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||||
|
const ::AssetLibrary &library = get_asset_library();
|
||||||
|
if (!can_modify_catalogs(library, r_disabled_hint)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AssetCatalog *drag_catalog = get_drag_catalog(drag, library);
|
||||||
|
/* NOTE: Technically it's not an issue to allow this (the catalog will just receive a new
|
||||||
|
* path and the catalog system will generate missing parents from the path). But it does
|
||||||
|
* appear broken to users, so disabling entirely. */
|
||||||
|
if (catalog_item_.catalog_path().is_contained_in(drag_catalog->path)) {
|
||||||
|
*r_disabled_hint = "Catalog cannot be dropped into itself";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (catalog_item_.catalog_path() == drag_catalog->path.parent()) {
|
||||||
|
*r_disabled_hint = "Catalog is already placed inside this catalog";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (drag.type == WM_DRAG_ASSET_LIST) {
|
||||||
|
return has_droppable_asset(drag, r_disabled_hint);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetCatalogDropTarget::drop_tooltip(const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||||
|
return drop_tooltip_asset_catalog(drag);
|
||||||
|
}
|
||||||
|
return drop_tooltip_asset_list(drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetCatalogDropTarget::drop_tooltip_asset_catalog(const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||||
|
const AssetCatalog *src_catalog = get_drag_catalog(drag, get_asset_library());
|
||||||
|
|
||||||
|
return std::string(TIP_("Move Catalog")) + " '" + src_catalog->path.name() + "' " +
|
||||||
|
TIP_("into") + " '" + catalog_item_.get_name() + "'";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetCatalogDropTarget::drop_tooltip_asset_list(const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
BLI_assert(drag.type == WM_DRAG_ASSET_LIST);
|
||||||
|
|
||||||
|
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
|
||||||
|
const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
|
||||||
|
|
||||||
|
/* Don't try to be smart by dynamically adding the 's' for the plural. Just makes translation
|
||||||
|
* harder, so use full literals. */
|
||||||
|
std::string basic_tip = is_multiple_assets ? TIP_("Move assets to catalog") :
|
||||||
|
TIP_("Move asset to catalog");
|
||||||
|
|
||||||
|
basic_tip += ": " + catalog_item_.get_name();
|
||||||
|
|
||||||
|
/* Display the full catalog path, but only if it's not exactly the same as the already shown name
|
||||||
|
* (i.e. not a root level catalog with no parent). */
|
||||||
|
if (catalog_item_.get_name() != catalog_item_.catalog_path().str()) {
|
||||||
|
basic_tip += " (" + catalog_item_.catalog_path().str() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
return basic_tip;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogDropTarget::on_drop(struct bContext *C, const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
if (drag.type == WM_DRAG_ASSET_CATALOG) {
|
||||||
|
return drop_asset_catalog_into_catalog(
|
||||||
|
drag, get_view<AssetCatalogTreeView>(), catalog_item_.get_catalog_id());
|
||||||
|
}
|
||||||
|
return drop_assets_into_catalog(C,
|
||||||
|
get_view<AssetCatalogTreeView>(),
|
||||||
|
drag,
|
||||||
|
catalog_item_.get_catalog_id(),
|
||||||
|
catalog_item_.get_simple_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogDropTarget::drop_asset_catalog_into_catalog(
|
||||||
|
const wmDrag &drag,
|
||||||
|
AssetCatalogTreeView &tree_view,
|
||||||
|
const std::optional<CatalogID> drop_catalog_id)
|
||||||
|
{
|
||||||
|
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||||
|
wmDragAssetCatalog *catalog_drag = WM_drag_get_asset_catalog_data(&drag);
|
||||||
|
ED_asset_catalog_move(tree_view.asset_library_, catalog_drag->drag_catalog_id, drop_catalog_id);
|
||||||
|
tree_view.activate_catalog_by_id(catalog_drag->drag_catalog_id);
|
||||||
|
|
||||||
|
tree_view.notify_catalog_tree_change();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogDropTarget::drop_assets_into_catalog(struct bContext *C,
|
||||||
|
AssetCatalogTreeView &tree_view,
|
||||||
|
const wmDrag &drag,
|
||||||
|
CatalogID catalog_id,
|
||||||
|
StringRefNull simple_name)
|
||||||
|
{
|
||||||
|
BLI_assert(drag.type == WM_DRAG_ASSET_LIST);
|
||||||
|
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
|
||||||
|
if (!asset_drags) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool did_update = false;
|
||||||
|
LISTBASE_FOREACH (wmDragAssetListItem *, asset_item, asset_drags) {
|
||||||
|
if (asset_item->is_external) {
|
||||||
|
/* Only internal assets can be modified! */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
did_update = true;
|
||||||
|
BKE_asset_metadata_catalog_id_set(
|
||||||
|
asset_item->asset_data.local_id->asset_data, catalog_id, simple_name.c_str());
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
/* Trigger re-run of filtering to update visible assets. */
|
||||||
|
// filelist_tag_needs_filtering(tree_view.space_file_.files);
|
||||||
|
// file_select_deselect_all(&tree_view.space_file_, FILE_SEL_SELECTED |
|
||||||
|
// FILE_SEL_HIGHLIGHTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (did_update) {
|
||||||
|
tree_view.notify_catalog_assignments_change();
|
||||||
|
ED_undo_push(C, "Assign Asset Catalog");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCatalog *AssetCatalogDropTarget::get_drag_catalog(const wmDrag &drag,
|
||||||
|
const ::AssetLibrary &asset_library)
|
||||||
|
{
|
||||||
|
if (drag.type != WM_DRAG_ASSET_CATALOG) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const asset_system::AssetCatalogService *catalog_service = AS_asset_library_get_catalog_service(
|
||||||
|
&asset_library);
|
||||||
|
const wmDragAssetCatalog *catalog_drag = WM_drag_get_asset_catalog_data(&drag);
|
||||||
|
|
||||||
|
return catalog_service->find_catalog(catalog_drag->drag_catalog_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogDropTarget::has_droppable_asset(const wmDrag &drag, const char **r_disabled_hint)
|
||||||
|
{
|
||||||
|
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
|
||||||
|
|
||||||
|
*r_disabled_hint = nullptr;
|
||||||
|
/* There needs to be at least one asset from the current file. */
|
||||||
|
LISTBASE_FOREACH (const wmDragAssetListItem *, asset_item, asset_drags) {
|
||||||
|
if (!asset_item->is_external) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*r_disabled_hint = TIP_("Only assets from this current file can be moved between catalogs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogDropTarget::can_modify_catalogs(const ::AssetLibrary &library,
|
||||||
|
const char **r_disabled_hint)
|
||||||
|
{
|
||||||
|
if (ED_asset_catalogs_read_only(library)) {
|
||||||
|
*r_disabled_hint = "Catalogs cannot be edited in this asset library";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
::AssetLibrary &AssetCatalogDropTarget::get_asset_library() const
|
||||||
|
{
|
||||||
|
return *get_view<AssetCatalogTreeView>().asset_library_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
AssetCatalogDragController::AssetCatalogDragController(AssetCatalogTreeView &tree_view,
|
||||||
|
AssetCatalogTreeItem &catalog_item)
|
||||||
|
: ui::AbstractViewItemDragController(tree_view), catalog_item_(catalog_item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AssetCatalogDragController::get_drag_type() const
|
||||||
|
{
|
||||||
|
return WM_DRAG_ASSET_CATALOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *AssetCatalogDragController::create_drag_data() const
|
||||||
|
{
|
||||||
|
wmDragAssetCatalog *drag_catalog = (wmDragAssetCatalog *)MEM_callocN(sizeof(*drag_catalog),
|
||||||
|
__func__);
|
||||||
|
drag_catalog->drag_catalog_id = catalog_item_.get_catalog_id();
|
||||||
|
return drag_catalog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetCatalogDragController::on_drag_start()
|
||||||
|
{
|
||||||
|
AssetCatalogTreeView &tree_view_ = get_view<AssetCatalogTreeView>();
|
||||||
|
tree_view_.activate_catalog_by_id(catalog_item_.get_catalog_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void AssetCatalogTreeViewAllItem::build_row(uiLayout &row)
|
||||||
|
{
|
||||||
|
ui::BasicTreeViewItem::build_row(row);
|
||||||
|
|
||||||
|
PointerRNA *props;
|
||||||
|
|
||||||
|
UI_but_extra_operator_icon_add(
|
||||||
|
(uiBut *)view_item_button(), "ASSET_OT_catalogs_save", WM_OP_INVOKE_DEFAULT, ICON_FILE_TICK);
|
||||||
|
|
||||||
|
props = UI_but_extra_operator_icon_add(
|
||||||
|
(uiBut *)view_item_button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD);
|
||||||
|
/* No parent path to use the root level. */
|
||||||
|
RNA_string_set(props, "parent_path", nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDropTarget> AssetCatalogTreeViewAllItem::create_drop_target()
|
||||||
|
{
|
||||||
|
return std::make_unique<AssetCatalogTreeViewAllItem::DropTarget>(
|
||||||
|
static_cast<AssetCatalogTreeView &>(get_tree_view()));
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCatalogTreeViewAllItem::DropTarget::DropTarget(AssetCatalogTreeView &tree_view)
|
||||||
|
: ui::AbstractViewItemDropTarget(tree_view)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeViewAllItem::DropTarget::can_drop(const wmDrag &drag,
|
||||||
|
const char **r_disabled_hint) const
|
||||||
|
{
|
||||||
|
if (drag.type != WM_DRAG_ASSET_CATALOG) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
::AssetLibrary &library = *get_view<AssetCatalogTreeView>().asset_library_;
|
||||||
|
if (!AssetCatalogDropTarget::can_modify_catalogs(library, r_disabled_hint)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AssetCatalog *drag_catalog = AssetCatalogDropTarget::get_drag_catalog(drag, library);
|
||||||
|
if (drag_catalog->path.parent() == "") {
|
||||||
|
*r_disabled_hint = "Catalog is already placed at the highest level";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetCatalogTreeViewAllItem::DropTarget::drop_tooltip(const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||||
|
const AssetCatalog *drag_catalog = AssetCatalogDropTarget::get_drag_catalog(
|
||||||
|
drag, *get_view<AssetCatalogTreeView>().asset_library_);
|
||||||
|
|
||||||
|
return std::string(TIP_("Move Catalog")) + " '" + drag_catalog->path.name() + "' " +
|
||||||
|
TIP_("to the top level of the tree");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeViewAllItem::DropTarget::on_drop(struct bContext * /*C*/,
|
||||||
|
const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
BLI_assert(drag.type == WM_DRAG_ASSET_CATALOG);
|
||||||
|
return AssetCatalogDropTarget::drop_asset_catalog_into_catalog(
|
||||||
|
drag,
|
||||||
|
get_view<AssetCatalogTreeView>(),
|
||||||
|
/* No value to drop into the root level. */
|
||||||
|
std::nullopt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
std::unique_ptr<ui::AbstractViewItemDropTarget> AssetCatalogTreeViewUnassignedItem::
|
||||||
|
create_drop_target()
|
||||||
|
{
|
||||||
|
return std::make_unique<AssetCatalogTreeViewUnassignedItem::DropTarget>(
|
||||||
|
static_cast<AssetCatalogTreeView &>(get_tree_view()));
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetCatalogTreeViewUnassignedItem::DropTarget::DropTarget(AssetCatalogTreeView &tree_view)
|
||||||
|
: ui::AbstractViewItemDropTarget(tree_view)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeViewUnassignedItem::DropTarget::can_drop(const wmDrag &drag,
|
||||||
|
const char **r_disabled_hint) const
|
||||||
|
{
|
||||||
|
if (drag.type != WM_DRAG_ASSET_LIST) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return AssetCatalogDropTarget::has_droppable_asset(drag, r_disabled_hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AssetCatalogTreeViewUnassignedItem::DropTarget::drop_tooltip(const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
|
||||||
|
const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
|
||||||
|
|
||||||
|
return is_multiple_assets ? TIP_("Move assets out of any catalog") :
|
||||||
|
TIP_("Move asset out of any catalog");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetCatalogTreeViewUnassignedItem::DropTarget::on_drop(struct bContext *C,
|
||||||
|
const wmDrag &drag) const
|
||||||
|
{
|
||||||
|
/* Assign to nil catalog ID. */
|
||||||
|
return AssetCatalogDropTarget::drop_assets_into_catalog(
|
||||||
|
C, get_view<AssetCatalogTreeView>(), drag, CatalogID{});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::ed::asset_browser
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void asset_view_create_catalog_tree_view_in_layout(::AssetLibrary *asset_library,
|
||||||
|
uiLayout *layout,
|
||||||
|
PointerRNA *catalog_filter_owner_ptr,
|
||||||
|
PropertyRNA *catalog_filter_prop,
|
||||||
|
wmMsgBus *msg_bus)
|
||||||
|
{
|
||||||
|
uiBlock *block = uiLayoutGetBlock(layout);
|
||||||
|
|
||||||
|
UI_block_layout_set_current(block, layout);
|
||||||
|
|
||||||
|
ui::AbstractTreeView *tree_view = UI_block_add_view(
|
||||||
|
*block,
|
||||||
|
"asset catalog tree view",
|
||||||
|
std::make_unique<ed::asset_browser::AssetCatalogTreeView>(
|
||||||
|
asset_library, *catalog_filter_owner_ptr, *catalog_filter_prop, msg_bus));
|
||||||
|
|
||||||
|
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
#include "BKE_context.h"
|
||||||
|
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
#include "RNA_types.h"
|
||||||
|
|
||||||
|
#include "ED_asset.h"
|
||||||
|
|
||||||
|
#include "UI_interface.h"
|
||||||
|
#include "UI_interface.hh"
|
||||||
|
|
||||||
|
#include "WM_message.h"
|
||||||
|
|
||||||
|
#include "asset_view.hh"
|
||||||
|
|
||||||
|
namespace blender::ed::asset_browser {
|
||||||
|
|
||||||
|
AssetGridView::AssetGridView(const AssetLibraryReference &asset_library_ref,
|
||||||
|
const PointerRNA &active_asset_idx_owner_ptr,
|
||||||
|
PropertyRNA *active_asset_idx_prop,
|
||||||
|
wmMsgBus *msg_bus)
|
||||||
|
: asset_library_ref_(asset_library_ref),
|
||||||
|
active_asset_idx_owner_(active_asset_idx_owner_ptr),
|
||||||
|
active_asset_idx_prop_(*active_asset_idx_prop),
|
||||||
|
msg_bus_(*msg_bus)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetGridView::build_items()
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
ED_assetlist_iterate(asset_library_ref_, [this, &idx](AssetHandle &asset) {
|
||||||
|
AssetGridViewItem &item = add_item<AssetGridViewItem>(asset_library_ref_, asset);
|
||||||
|
|
||||||
|
item.set_is_active_fn([this, idx]() -> bool {
|
||||||
|
return idx == RNA_property_int_get(&active_asset_idx_owner_, &active_asset_idx_prop_);
|
||||||
|
});
|
||||||
|
item.set_on_activate_fn([this, idx](ui::PreviewGridItem & /*item*/) {
|
||||||
|
RNA_property_int_set(&active_asset_idx_owner_, &active_asset_idx_prop_, idx);
|
||||||
|
WM_msg_publish_rna(&msg_bus_, &active_asset_idx_owner_, &active_asset_idx_prop_);
|
||||||
|
});
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetGridView::listen(const wmNotifier ¬ifier) const
|
||||||
|
{
|
||||||
|
return ED_assetlist_listen(&asset_library_ref_, ¬ifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
AssetGridViewItem::AssetGridViewItem(const AssetLibraryReference &asset_library_ref,
|
||||||
|
AssetHandle &asset)
|
||||||
|
: ui::PreviewGridItem(ED_asset_handle_get_identifier(&asset),
|
||||||
|
ED_asset_handle_get_name(&asset),
|
||||||
|
ED_assetlist_asset_preview_icon_id_request(&asset_library_ref, &asset)),
|
||||||
|
/* Get a copy so the identifier is always available (the file data wrapped by the handle may
|
||||||
|
* be freed). */
|
||||||
|
asset_identifier_(identifier_)
|
||||||
|
{
|
||||||
|
/* Update reference so we don't point into the possibly freed file data. */
|
||||||
|
identifier_ = asset_identifier_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void asset_view_create_in_layout(const bContext &C,
|
||||||
|
const AssetLibraryReference &asset_library_ref,
|
||||||
|
const AssetCatalogFilterSettings &catalog_filter_settings,
|
||||||
|
const PointerRNA &active_asset_idx_owner_ptr,
|
||||||
|
PropertyRNA *active_asset_idx_prop,
|
||||||
|
const View2D &v2d,
|
||||||
|
uiLayout &layout)
|
||||||
|
{
|
||||||
|
uiBlock *block = uiLayoutGetBlock(&layout);
|
||||||
|
UI_block_layout_set_current(block, &layout);
|
||||||
|
|
||||||
|
ED_assetlist_storage_fetch(&asset_library_ref, &C);
|
||||||
|
ED_assetlist_catalog_filter_set(&asset_library_ref, &catalog_filter_settings);
|
||||||
|
|
||||||
|
ui::AbstractGridView *grid_view = UI_block_add_view(
|
||||||
|
*block,
|
||||||
|
"asset grid view",
|
||||||
|
std::make_unique<AssetGridView>(asset_library_ref,
|
||||||
|
active_asset_idx_owner_ptr,
|
||||||
|
active_asset_idx_prop,
|
||||||
|
CTX_wm_message_bus(&C)));
|
||||||
|
|
||||||
|
ui::GridViewBuilder builder(*block);
|
||||||
|
builder.build_grid_view(*grid_view, v2d, layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::ed::asset_browser
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
|
#include "UI_grid_view.hh"
|
||||||
|
|
||||||
|
struct AssetCatalogFilterSettings;
|
||||||
|
struct bContext;
|
||||||
|
struct PointerRNA;
|
||||||
|
struct PropertyRNA;
|
||||||
|
struct uiLayout;
|
||||||
|
struct View2D;
|
||||||
|
struct wmMsgBus;
|
||||||
|
|
||||||
|
namespace blender::ed::asset_browser {
|
||||||
|
|
||||||
|
class AssetGridView : public blender::ui::AbstractGridView {
|
||||||
|
AssetLibraryReference asset_library_ref_;
|
||||||
|
|
||||||
|
/** Reference to bind the active asset of the editor to the view. */
|
||||||
|
PointerRNA active_asset_idx_owner_;
|
||||||
|
PropertyRNA &active_asset_idx_prop_;
|
||||||
|
wmMsgBus &msg_bus_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetGridView(const AssetLibraryReference &,
|
||||||
|
const PointerRNA &active_asset_idx_owner_ptr,
|
||||||
|
PropertyRNA *active_asset_idx_prop,
|
||||||
|
wmMsgBus *msg_bus);
|
||||||
|
|
||||||
|
void build_items() override;
|
||||||
|
bool listen(const wmNotifier &) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssetGridViewItem : public ui::PreviewGridItem {
|
||||||
|
/* Can't store this here, since the wrapped FileDirEntry will be freed while progressively
|
||||||
|
* loading items. */
|
||||||
|
// AssetHandle &asset_;
|
||||||
|
std::string asset_identifier_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AssetGridViewItem(const AssetLibraryReference &asset_library_ref, AssetHandle &);
|
||||||
|
};
|
||||||
|
|
||||||
|
void asset_view_create_in_layout(const bContext &C,
|
||||||
|
const AssetLibraryReference &asset_library_ref,
|
||||||
|
const AssetCatalogFilterSettings &catalog_filter_settings,
|
||||||
|
const PointerRNA &active_asset_idx_owner_ptr,
|
||||||
|
PropertyRNA *active_asset_idx_prop,
|
||||||
|
const View2D &v2d,
|
||||||
|
uiLayout &layout);
|
||||||
|
|
||||||
|
} // namespace blender::ed::asset_browser
|
|
@ -0,0 +1,312 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup spassets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "DNA_screen_types.h"
|
||||||
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "BKE_asset.h"
|
||||||
|
#include "BKE_screen.h"
|
||||||
|
|
||||||
|
#include "BLI_listbase.h"
|
||||||
|
|
||||||
|
#include "ED_asset.h"
|
||||||
|
#include "ED_screen.h"
|
||||||
|
#include "ED_space_api.h"
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "RNA_access.h"
|
||||||
|
|
||||||
|
#include "UI_interface.h"
|
||||||
|
#include "UI_resources.h"
|
||||||
|
#include "UI_view2d.h"
|
||||||
|
|
||||||
|
#include "WM_api.h"
|
||||||
|
#include "WM_message.h"
|
||||||
|
|
||||||
|
#include "asset_browser_intern.hh"
|
||||||
|
#include "asset_view.hh"
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Asset Browser Space */
|
||||||
|
|
||||||
|
static SpaceLink *asset_browser_create(const ScrArea * /*area*/, const Scene * /*scene*/)
|
||||||
|
{
|
||||||
|
SpaceAssets *assets_space = MEM_cnew<SpaceAssets>("asset browser space");
|
||||||
|
assets_space->spacetype = SPACE_ASSETS;
|
||||||
|
|
||||||
|
BKE_asset_library_reference_init_default(&assets_space->asset_library_ref);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Header. */
|
||||||
|
ARegion *region = MEM_cnew<ARegion>("asset browser header");
|
||||||
|
BLI_addtail(&assets_space->regionbase, region);
|
||||||
|
region->regiontype = RGN_TYPE_HEADER;
|
||||||
|
region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Navigation region */
|
||||||
|
ARegion *region = MEM_cnew<ARegion>("asset browser navigation region");
|
||||||
|
|
||||||
|
BLI_addtail(&assets_space->regionbase, region);
|
||||||
|
region->regiontype = RGN_TYPE_NAV_BAR;
|
||||||
|
region->alignment = RGN_ALIGN_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Sidebar region */
|
||||||
|
ARegion *region = MEM_cnew<ARegion>("asset browser sidebar region");
|
||||||
|
|
||||||
|
BLI_addtail(&assets_space->regionbase, region);
|
||||||
|
region->regiontype = RGN_TYPE_UI;
|
||||||
|
region->alignment = RGN_ALIGN_RIGHT;
|
||||||
|
region->flag = RGN_FLAG_HIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Main region. */
|
||||||
|
ARegion *region = MEM_cnew<ARegion>("asset browser main region");
|
||||||
|
BLI_addtail(&assets_space->regionbase, region);
|
||||||
|
region->regiontype = RGN_TYPE_WINDOW;
|
||||||
|
|
||||||
|
region->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
|
||||||
|
region->v2d.align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
|
||||||
|
region->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
|
||||||
|
region->v2d.keeptot = V2D_KEEPTOT_STRICT;
|
||||||
|
region->v2d.minzoom = region->v2d.maxzoom = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SpaceLink *)assets_space;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_free(SpaceLink * /*sl*/) {}
|
||||||
|
|
||||||
|
static void asset_browser_init(wmWindowManager * /*wm*/, ScrArea * /*area*/) {}
|
||||||
|
|
||||||
|
static SpaceLink *asset_browser_duplicate(SpaceLink *sl)
|
||||||
|
{
|
||||||
|
const SpaceAssets *asset_browser_old = (SpaceAssets *)sl;
|
||||||
|
SpaceAssets *asset_browser_new = reinterpret_cast<SpaceAssets *>(
|
||||||
|
MEM_dupallocN(asset_browser_old));
|
||||||
|
|
||||||
|
return (SpaceLink *)asset_browser_new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_keymap(wmKeyConfig *keyconf)
|
||||||
|
{
|
||||||
|
/* keys for all regions */
|
||||||
|
WM_keymap_ensure(keyconf, "Asset Browser", SPACE_ASSETS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *asset_browser_context_dir[] = {
|
||||||
|
"asset_handle",
|
||||||
|
"asset_library_ref",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int /*eContextResult*/ asset_browser_context(const bContext *C,
|
||||||
|
const char *member,
|
||||||
|
bContextDataResult *result)
|
||||||
|
{
|
||||||
|
if (CTX_data_dir(member)) {
|
||||||
|
CTX_data_dir_set(result, asset_browser_context_dir);
|
||||||
|
return CTX_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bScreen *screen = CTX_wm_screen(C);
|
||||||
|
SpaceAssets *assets_space = CTX_wm_space_assets(C);
|
||||||
|
|
||||||
|
if (CTX_data_equals(member, "asset_library_ref")) {
|
||||||
|
CTX_data_pointer_set(
|
||||||
|
result, &screen->id, &RNA_AssetLibraryReference, &assets_space->asset_library_ref);
|
||||||
|
return CTX_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CTX_data_equals(member, "asset_handle")) {
|
||||||
|
AssetHandle *asset = ED_assetlist_asset_get_by_index(&assets_space->asset_library_ref,
|
||||||
|
assets_space->active_asset_idx);
|
||||||
|
if (!asset) {
|
||||||
|
return CTX_RESULT_NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTX_data_pointer_set(result, &screen->id, &RNA_AssetHandle, asset);
|
||||||
|
return CTX_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CTX_RESULT_MEMBER_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Main Region */
|
||||||
|
|
||||||
|
static void asset_browser_main_region_init(wmWindowManager *wm, ARegion *region)
|
||||||
|
{
|
||||||
|
UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy);
|
||||||
|
|
||||||
|
{
|
||||||
|
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Asset Browser", SPACE_ASSETS, 0);
|
||||||
|
WM_event_add_keymap_handler(®ion->handlers, keymap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_main_region_listener(const wmRegionListenerParams *params)
|
||||||
|
{
|
||||||
|
const wmNotifier *notifier = params->notifier;
|
||||||
|
ARegion *region = params->region;
|
||||||
|
|
||||||
|
switch (notifier->category) {
|
||||||
|
case NC_ASSET:
|
||||||
|
if (ELEM(notifier->data, ND_SPACE_ASSET_PARAMS)) {
|
||||||
|
ED_region_tag_redraw(region);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_main_region_message_subscribe(
|
||||||
|
const wmRegionMessageSubscribeParams *params)
|
||||||
|
{
|
||||||
|
struct wmMsgBus *mbus = params->message_bus;
|
||||||
|
bScreen *screen = params->screen;
|
||||||
|
SpaceAssets *assets_space = reinterpret_cast<SpaceAssets *>(params->area->spacedata.first);
|
||||||
|
|
||||||
|
wmMsgSubscribeValue msg_sub_value_region_tag_redraw{};
|
||||||
|
msg_sub_value_region_tag_redraw.owner = params->region;
|
||||||
|
msg_sub_value_region_tag_redraw.user_data = params->region;
|
||||||
|
msg_sub_value_region_tag_redraw.notify = ED_region_do_msg_notify_tag_redraw;
|
||||||
|
|
||||||
|
WM_msg_subscribe_rna_prop(mbus,
|
||||||
|
&screen->id,
|
||||||
|
assets_space,
|
||||||
|
SpaceAssetBrowser,
|
||||||
|
catalog_filter,
|
||||||
|
&msg_sub_value_region_tag_redraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Header Region */
|
||||||
|
|
||||||
|
static void asset_browser_header_init(wmWindowManager * /*wm*/, ARegion *region)
|
||||||
|
{
|
||||||
|
ED_region_header_init(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_header_listener(const wmRegionListenerParams * /*params*/) {}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Navigation Region */
|
||||||
|
|
||||||
|
static void asset_browser_navigation_region_init(wmWindowManager *wm, ARegion *region)
|
||||||
|
{
|
||||||
|
region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
|
||||||
|
ED_region_panels_init(wm, region);
|
||||||
|
|
||||||
|
{
|
||||||
|
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Asset Browser", SPACE_ASSETS, 0);
|
||||||
|
WM_event_add_keymap_handler(®ion->handlers, keymap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_navigation_region_draw(const bContext *C, ARegion *region)
|
||||||
|
{
|
||||||
|
ED_region_panels(C, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_navigation_region_listener(
|
||||||
|
const wmRegionListenerParams * /*listener_params*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Sidebar Region */
|
||||||
|
|
||||||
|
static void asset_browser_sidebar_region_init(wmWindowManager *wm, ARegion *region)
|
||||||
|
{
|
||||||
|
region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
|
||||||
|
ED_region_panels_init(wm, region);
|
||||||
|
|
||||||
|
{
|
||||||
|
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Asset Browser", SPACE_ASSETS, 0);
|
||||||
|
WM_event_add_keymap_handler(®ion->handlers, keymap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_sidebar_region_draw(const bContext *C, ARegion *region)
|
||||||
|
{
|
||||||
|
ED_region_panels(C, region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void asset_browser_sidebar_region_listener(
|
||||||
|
const wmRegionListenerParams * /*listener_params*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* Asset Browser Space-Type */
|
||||||
|
|
||||||
|
void ED_spacetype_assets(void)
|
||||||
|
{
|
||||||
|
SpaceType *st = MEM_cnew<SpaceType>("spacetype asset browser");
|
||||||
|
ARegionType *art;
|
||||||
|
|
||||||
|
st->spaceid = SPACE_ASSETS;
|
||||||
|
strncpy(st->name, "Asset Browser", BKE_ST_MAXNAME);
|
||||||
|
|
||||||
|
st->create = asset_browser_create;
|
||||||
|
st->free = asset_browser_free;
|
||||||
|
st->init = asset_browser_init;
|
||||||
|
st->duplicate = asset_browser_duplicate;
|
||||||
|
st->operatortypes = asset_browser_operatortypes;
|
||||||
|
st->keymap = asset_browser_keymap;
|
||||||
|
st->context = asset_browser_context;
|
||||||
|
|
||||||
|
/* Main region. */
|
||||||
|
art = MEM_cnew<ARegionType>("spacetype asset browser main region");
|
||||||
|
art->regionid = RGN_TYPE_WINDOW;
|
||||||
|
art->init = asset_browser_main_region_init;
|
||||||
|
art->draw = asset_browser_main_region_draw;
|
||||||
|
art->listener = asset_browser_main_region_listener;
|
||||||
|
art->message_subscribe = asset_browser_main_region_message_subscribe;
|
||||||
|
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
|
||||||
|
BLI_addhead(&st->regiontypes, art);
|
||||||
|
|
||||||
|
/* Header region. */
|
||||||
|
art = MEM_cnew<ARegionType>("spacetype asset browser header region");
|
||||||
|
art->regionid = RGN_TYPE_HEADER;
|
||||||
|
art->prefsizey = HEADERY;
|
||||||
|
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
|
||||||
|
art->listener = asset_browser_header_listener;
|
||||||
|
art->init = asset_browser_header_init;
|
||||||
|
art->layout = ED_region_header_layout;
|
||||||
|
art->draw = ED_region_header_draw;
|
||||||
|
BLI_addhead(&st->regiontypes, art);
|
||||||
|
|
||||||
|
/* Navigation region */
|
||||||
|
art = MEM_cnew<ARegionType>("spacetype asset browser navigation region");
|
||||||
|
art->regionid = RGN_TYPE_NAV_BAR;
|
||||||
|
art->prefsizex = 240;
|
||||||
|
art->init = asset_browser_navigation_region_init;
|
||||||
|
art->draw = asset_browser_navigation_region_draw;
|
||||||
|
art->listener = asset_browser_navigation_region_listener;
|
||||||
|
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_NAVBAR;
|
||||||
|
asset_browser_navigation_region_panels_register(art);
|
||||||
|
BLI_addhead(&st->regiontypes, art);
|
||||||
|
|
||||||
|
/* Sidebar region */
|
||||||
|
art = MEM_cnew<ARegionType>("spacetype asset browser sidebar region");
|
||||||
|
art->regionid = RGN_TYPE_UI;
|
||||||
|
art->prefsizex = 240;
|
||||||
|
art->init = asset_browser_sidebar_region_init;
|
||||||
|
art->draw = asset_browser_sidebar_region_draw;
|
||||||
|
art->listener = asset_browser_sidebar_region_listener;
|
||||||
|
art->keymapflag = ED_KEYMAP_UI;
|
||||||
|
BLI_addhead(&st->regiontypes, art);
|
||||||
|
|
||||||
|
BKE_spacetype_register(st);
|
||||||
|
}
|
|
@ -37,7 +37,7 @@
|
||||||
using namespace blender;
|
using namespace blender;
|
||||||
using namespace blender::asset_system;
|
using namespace blender::asset_system;
|
||||||
|
|
||||||
namespace blender::ed::asset_browser {
|
namespace blender::ed::space_file::asset_browser {
|
||||||
|
|
||||||
class AssetCatalogTreeViewAllItem;
|
class AssetCatalogTreeViewAllItem;
|
||||||
|
|
||||||
|
@ -218,11 +218,11 @@ AssetCatalogTreeViewAllItem &AssetCatalogTreeView::add_all_item()
|
||||||
|
|
||||||
AssetCatalogTreeViewAllItem &item = add_tree_item<AssetCatalogTreeViewAllItem>(IFACE_("All"));
|
AssetCatalogTreeViewAllItem &item = add_tree_item<AssetCatalogTreeViewAllItem>(IFACE_("All"));
|
||||||
item.set_on_activate_fn([params](ui::BasicTreeViewItem & /*item*/) {
|
item.set_on_activate_fn([params](ui::BasicTreeViewItem & /*item*/) {
|
||||||
params->asset_catalog_visibility = FILE_SHOW_ASSETS_ALL_CATALOGS;
|
params->asset_catalog_visibility = ASSET_CATALOG_SHOW_ALL_ASSETS;
|
||||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||||
});
|
});
|
||||||
item.set_is_active_fn(
|
item.set_is_active_fn(
|
||||||
[params]() { return params->asset_catalog_visibility == FILE_SHOW_ASSETS_ALL_CATALOGS; });
|
[params]() { return params->asset_catalog_visibility == ASSET_CATALOG_SHOW_ALL_ASSETS; });
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,23 +234,24 @@ void AssetCatalogTreeView::add_unassigned_item()
|
||||||
IFACE_("Unassigned"), ICON_FILE_HIDDEN);
|
IFACE_("Unassigned"), ICON_FILE_HIDDEN);
|
||||||
|
|
||||||
item.set_on_activate_fn([params](ui::BasicTreeViewItem & /*item*/) {
|
item.set_on_activate_fn([params](ui::BasicTreeViewItem & /*item*/) {
|
||||||
params->asset_catalog_visibility = FILE_SHOW_ASSETS_WITHOUT_CATALOG;
|
params->asset_catalog_visibility = ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG;
|
||||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||||
});
|
});
|
||||||
item.set_is_active_fn(
|
item.set_is_active_fn([params]() {
|
||||||
[params]() { return params->asset_catalog_visibility == FILE_SHOW_ASSETS_WITHOUT_CATALOG; });
|
return params->asset_catalog_visibility == ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetCatalogTreeView::activate_catalog_by_id(CatalogID catalog_id)
|
void AssetCatalogTreeView::activate_catalog_by_id(CatalogID catalog_id)
|
||||||
{
|
{
|
||||||
params_->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
|
params_->asset_catalog_visibility = ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG;
|
||||||
params_->catalog_id = catalog_id;
|
params_->catalog_id = catalog_id;
|
||||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetCatalogTreeView::is_active_catalog(CatalogID catalog_id) const
|
bool AssetCatalogTreeView::is_active_catalog(CatalogID catalog_id) const
|
||||||
{
|
{
|
||||||
return (params_->asset_catalog_visibility == FILE_SHOW_ASSETS_FROM_CATALOG) &&
|
return (params_->asset_catalog_visibility == ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG) &&
|
||||||
(params_->catalog_id == catalog_id);
|
(params_->catalog_id == catalog_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,98 +671,11 @@ bool AssetCatalogTreeViewUnassignedItem::DropTarget::on_drop(struct bContext *C,
|
||||||
C, get_view<AssetCatalogTreeView>(), drag, CatalogID{});
|
C, get_view<AssetCatalogTreeView>(), drag, CatalogID{});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::ed::asset_browser
|
} // namespace blender::ed::space_file::asset_browser
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
namespace blender::ed::asset_browser {
|
namespace asset_browser = blender::ed::space_file::asset_browser;
|
||||||
|
|
||||||
class AssetCatalogFilterSettings {
|
|
||||||
public:
|
|
||||||
eFileSel_Params_AssetCatalogVisibility asset_catalog_visibility;
|
|
||||||
bUUID asset_catalog_id;
|
|
||||||
|
|
||||||
std::unique_ptr<AssetCatalogFilter> catalog_filter;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace blender::ed::asset_browser
|
|
||||||
|
|
||||||
using namespace blender::ed::asset_browser;
|
|
||||||
|
|
||||||
FileAssetCatalogFilterSettingsHandle *file_create_asset_catalog_filter_settings()
|
|
||||||
{
|
|
||||||
AssetCatalogFilterSettings *filter_settings = MEM_new<AssetCatalogFilterSettings>(__func__);
|
|
||||||
return reinterpret_cast<FileAssetCatalogFilterSettingsHandle *>(filter_settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_delete_asset_catalog_filter_settings(
|
|
||||||
FileAssetCatalogFilterSettingsHandle **filter_settings_handle)
|
|
||||||
{
|
|
||||||
AssetCatalogFilterSettings **filter_settings = reinterpret_cast<AssetCatalogFilterSettings **>(
|
|
||||||
filter_settings_handle);
|
|
||||||
MEM_delete(*filter_settings);
|
|
||||||
*filter_settings = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool file_set_asset_catalog_filter_settings(
|
|
||||||
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
|
|
||||||
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
|
|
||||||
::bUUID catalog_id)
|
|
||||||
{
|
|
||||||
AssetCatalogFilterSettings *filter_settings = reinterpret_cast<AssetCatalogFilterSettings *>(
|
|
||||||
filter_settings_handle);
|
|
||||||
bool needs_update = false;
|
|
||||||
|
|
||||||
if (filter_settings->asset_catalog_visibility != catalog_visibility) {
|
|
||||||
filter_settings->asset_catalog_visibility = catalog_visibility;
|
|
||||||
needs_update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter_settings->asset_catalog_visibility == FILE_SHOW_ASSETS_FROM_CATALOG &&
|
|
||||||
!BLI_uuid_equal(filter_settings->asset_catalog_id, catalog_id)) {
|
|
||||||
filter_settings->asset_catalog_id = catalog_id;
|
|
||||||
needs_update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return needs_update;
|
|
||||||
}
|
|
||||||
|
|
||||||
void file_ensure_updated_catalog_filter_data(
|
|
||||||
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
|
|
||||||
const asset_system::AssetLibrary *asset_library)
|
|
||||||
{
|
|
||||||
AssetCatalogFilterSettings *filter_settings = reinterpret_cast<AssetCatalogFilterSettings *>(
|
|
||||||
filter_settings_handle);
|
|
||||||
const AssetCatalogService *catalog_service = asset_library->catalog_service.get();
|
|
||||||
|
|
||||||
if (filter_settings->asset_catalog_visibility != FILE_SHOW_ASSETS_ALL_CATALOGS) {
|
|
||||||
filter_settings->catalog_filter = std::make_unique<AssetCatalogFilter>(
|
|
||||||
catalog_service->create_catalog_filter(filter_settings->asset_catalog_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool file_is_asset_visible_in_catalog_filter_settings(
|
|
||||||
const FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
|
|
||||||
const AssetMetaData *asset_data)
|
|
||||||
{
|
|
||||||
const AssetCatalogFilterSettings *filter_settings =
|
|
||||||
reinterpret_cast<const AssetCatalogFilterSettings *>(filter_settings_handle);
|
|
||||||
|
|
||||||
switch (filter_settings->asset_catalog_visibility) {
|
|
||||||
case FILE_SHOW_ASSETS_WITHOUT_CATALOG:
|
|
||||||
return !filter_settings->catalog_filter->is_known(asset_data->catalog_id);
|
|
||||||
case FILE_SHOW_ASSETS_FROM_CATALOG:
|
|
||||||
return filter_settings->catalog_filter->contains(asset_data->catalog_id);
|
|
||||||
case FILE_SHOW_ASSETS_ALL_CATALOGS:
|
|
||||||
/* All asset files should be visible. */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
BLI_assert_unreachable();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library,
|
void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library,
|
||||||
uiLayout *layout,
|
uiLayout *layout,
|
||||||
|
@ -775,8 +689,7 @@ void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library
|
||||||
ui::AbstractTreeView *tree_view = UI_block_add_view(
|
ui::AbstractTreeView *tree_view = UI_block_add_view(
|
||||||
*block,
|
*block,
|
||||||
"asset catalog tree view",
|
"asset catalog tree view",
|
||||||
std::make_unique<ed::asset_browser::AssetCatalogTreeView>(
|
std::make_unique<asset_browser::AssetCatalogTreeView>(asset_library, params, *space_file));
|
||||||
asset_library, params, *space_file));
|
|
||||||
|
|
||||||
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
|
ui::TreeViewBuilder::build_tree_view(*tree_view, *layout);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,39 +215,10 @@ void file_path_to_ui_path(const char *path, char *r_pathi, int max_size);
|
||||||
|
|
||||||
/* asset_catalog_tree_view.cc */
|
/* asset_catalog_tree_view.cc */
|
||||||
|
|
||||||
/* C-handle for #ed::asset_browser::AssetCatalogFilterSettings. */
|
|
||||||
typedef struct FileAssetCatalogFilterSettingsHandle FileAssetCatalogFilterSettingsHandle;
|
|
||||||
|
|
||||||
void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library,
|
void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library,
|
||||||
struct uiLayout *layout,
|
struct uiLayout *layout,
|
||||||
SpaceFile *space_file,
|
struct SpaceFile *space_file,
|
||||||
FileAssetSelectParams *params);
|
struct FileAssetSelectParams *params);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
namespace blender::asset_system {
|
|
||||||
class AssetLibrary;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileAssetCatalogFilterSettingsHandle *file_create_asset_catalog_filter_settings(void);
|
|
||||||
void file_delete_asset_catalog_filter_settings(
|
|
||||||
FileAssetCatalogFilterSettingsHandle **filter_settings_handle);
|
|
||||||
/**
|
|
||||||
* \return True if the file list should update its filtered results
|
|
||||||
* (e.g. because filtering parameters changed).
|
|
||||||
*/
|
|
||||||
bool file_set_asset_catalog_filter_settings(
|
|
||||||
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
|
|
||||||
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
|
|
||||||
bUUID catalog_id);
|
|
||||||
void file_ensure_updated_catalog_filter_data(
|
|
||||||
FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
|
|
||||||
const blender::asset_system::AssetLibrary *asset_library);
|
|
||||||
bool file_is_asset_visible_in_catalog_filter_settings(
|
|
||||||
const FileAssetCatalogFilterSettingsHandle *filter_settings_handle,
|
|
||||||
const AssetMetaData *asset_data);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#include "DNA_asset_types.h"
|
#include "DNA_asset_types.h"
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
|
|
||||||
|
#include "ED_asset_view_catalog_filter.h"
|
||||||
#include "ED_datafiles.h"
|
#include "ED_datafiles.h"
|
||||||
#include "ED_fileselect.h"
|
#include "ED_fileselect.h"
|
||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
|
@ -197,7 +198,7 @@ struct FileListFilter {
|
||||||
char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
|
char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
|
||||||
short flags;
|
short flags;
|
||||||
|
|
||||||
FileAssetCatalogFilterSettingsHandle *asset_catalog_filter;
|
AssetViewCatalogFilterSettingsHandle *asset_catalog_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** #FileListFilter.flags */
|
/** #FileListFilter.flags */
|
||||||
|
@ -805,7 +806,8 @@ static void prepare_filter_asset_library(const FileList *filelist, FileListFilte
|
||||||
"prepare_filter_asset_library() should only be called when the file browser is "
|
"prepare_filter_asset_library() should only be called when the file browser is "
|
||||||
"in asset browser mode");
|
"in asset browser mode");
|
||||||
|
|
||||||
file_ensure_updated_catalog_filter_data(filter->asset_catalog_filter, filelist->asset_library);
|
asset_view_ensure_updated_catalog_filter_data(
|
||||||
|
filter->asset_catalog_filter, reinterpret_cast<::AssetLibrary *>(filelist->asset_library));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -835,7 +837,7 @@ static bool is_filtered_asset(FileListInternEntry *file, FileListFilter *filter)
|
||||||
const AssetMetaData *asset_data = filelist_file_internal_get_asset_data(file);
|
const AssetMetaData *asset_data = filelist_file_internal_get_asset_data(file);
|
||||||
|
|
||||||
/* Not used yet for the asset view template. */
|
/* Not used yet for the asset view template. */
|
||||||
if (filter->asset_catalog_filter && !file_is_asset_visible_in_catalog_filter_settings(
|
if (filter->asset_catalog_filter && !asset_view_is_asset_visible_in_catalog_filter_settings(
|
||||||
filter->asset_catalog_filter, asset_data)) {
|
filter->asset_catalog_filter, asset_data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1024,17 +1026,16 @@ void filelist_setindexer(FileList *filelist, const FileIndexerType *indexer)
|
||||||
filelist->indexer = indexer;
|
filelist->indexer = indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filelist_set_asset_catalog_filter_options(
|
void filelist_set_asset_catalog_filter_options(FileList *filelist,
|
||||||
FileList *filelist,
|
AssetCatalogFilterMode catalog_visibility,
|
||||||
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
|
const ::bUUID *catalog_id)
|
||||||
const ::bUUID *catalog_id)
|
|
||||||
{
|
{
|
||||||
if (!filelist->filter_data.asset_catalog_filter) {
|
if (!filelist->filter_data.asset_catalog_filter) {
|
||||||
/* There's no filter data yet. */
|
/* There's no filter data yet. */
|
||||||
filelist->filter_data.asset_catalog_filter = file_create_asset_catalog_filter_settings();
|
filelist->filter_data.asset_catalog_filter = asset_view_create_catalog_filter_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool needs_update = file_set_asset_catalog_filter_settings(
|
const bool needs_update = asset_view_set_catalog_filter_settings(
|
||||||
filelist->filter_data.asset_catalog_filter, catalog_visibility, *catalog_id);
|
filelist->filter_data.asset_catalog_filter, catalog_visibility, *catalog_id);
|
||||||
|
|
||||||
if (needs_update) {
|
if (needs_update) {
|
||||||
|
@ -1468,6 +1469,26 @@ static int filelist_intern_free_main_files(FileList *filelist)
|
||||||
return removed_counter;
|
return removed_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int filelist_preview_source_get(int /* eFileSel_File_Types */ file_type)
|
||||||
|
{
|
||||||
|
if (file_type & FILE_TYPE_IMAGE) {
|
||||||
|
return THB_SOURCE_IMAGE;
|
||||||
|
}
|
||||||
|
else if (file_type & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) {
|
||||||
|
return THB_SOURCE_BLEND;
|
||||||
|
}
|
||||||
|
else if (file_type & FILE_TYPE_MOVIE) {
|
||||||
|
return THB_SOURCE_MOVIE;
|
||||||
|
}
|
||||||
|
else if (file_type & FILE_TYPE_FTFONT) {
|
||||||
|
return THB_SOURCE_FONT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdata)
|
static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdata)
|
||||||
{
|
{
|
||||||
FileListEntryCache *cache = static_cast<FileListEntryCache *>(BLI_task_pool_user_data(pool));
|
FileListEntryCache *cache = static_cast<FileListEntryCache *>(BLI_task_pool_user_data(pool));
|
||||||
|
@ -1475,30 +1496,11 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
|
||||||
taskdata);
|
taskdata);
|
||||||
FileListEntryPreview *preview = preview_taskdata->preview;
|
FileListEntryPreview *preview = preview_taskdata->preview;
|
||||||
|
|
||||||
/* XXX #THB_SOURCE_IMAGE for "historic" reasons. The case of an undefined source should be
|
ThumbSource source = static_cast<ThumbSource>(filelist_preview_source_get(preview->flags));
|
||||||
* handled better. */
|
|
||||||
ThumbSource source = THB_SOURCE_IMAGE;
|
|
||||||
|
|
||||||
// printf("%s: Start (%d)...\n", __func__, threadid);
|
// printf("%s: Start (%d)...\n", __func__, threadid);
|
||||||
|
|
||||||
// printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
|
// printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
|
||||||
BLI_assert(preview->flags &
|
|
||||||
(FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER |
|
|
||||||
FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB));
|
|
||||||
|
|
||||||
if (preview->flags & FILE_TYPE_IMAGE) {
|
|
||||||
source = THB_SOURCE_IMAGE;
|
|
||||||
}
|
|
||||||
else if (preview->flags &
|
|
||||||
(FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)) {
|
|
||||||
source = THB_SOURCE_BLEND;
|
|
||||||
}
|
|
||||||
else if (preview->flags & FILE_TYPE_MOVIE) {
|
|
||||||
source = THB_SOURCE_MOVIE;
|
|
||||||
}
|
|
||||||
else if (preview->flags & FILE_TYPE_FTFONT) {
|
|
||||||
source = THB_SOURCE_FONT;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMB_thumb_path_lock(preview->filepath);
|
IMB_thumb_path_lock(preview->filepath);
|
||||||
/* Always generate biggest preview size for now, it's simpler and avoids having to re-generate
|
/* Always generate biggest preview size for now, it's simpler and avoids having to re-generate
|
||||||
|
@ -1803,7 +1805,7 @@ static void filelist_clear_asset_library(FileList *filelist)
|
||||||
{
|
{
|
||||||
/* The AssetLibraryService owns the AssetLibrary pointer, so no need for us to free it. */
|
/* The AssetLibraryService owns the AssetLibrary pointer, so no need for us to free it. */
|
||||||
filelist->asset_library = nullptr;
|
filelist->asset_library = nullptr;
|
||||||
file_delete_asset_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter);
|
asset_view_delete_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void filelist_clear_ex(FileList *filelist,
|
void filelist_clear_ex(FileList *filelist,
|
||||||
|
|
|
@ -55,12 +55,11 @@ void filelist_setfilter_options(struct FileList *filelist,
|
||||||
void filelist_setindexer(struct FileList *filelist, const struct FileIndexerType *indexer);
|
void filelist_setindexer(struct FileList *filelist, const struct FileIndexerType *indexer);
|
||||||
/**
|
/**
|
||||||
* \param catalog_id: The catalog that should be filtered by if \a catalog_visibility is
|
* \param catalog_id: The catalog that should be filtered by if \a catalog_visibility is
|
||||||
* #FILE_SHOW_ASSETS_FROM_CATALOG. May be NULL otherwise.
|
* #ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG. May be NULL otherwise.
|
||||||
*/
|
*/
|
||||||
void filelist_set_asset_catalog_filter_options(
|
void filelist_set_asset_catalog_filter_options(struct FileList *filelist,
|
||||||
struct FileList *filelist,
|
AssetCatalogFilterMode catalog_visibility,
|
||||||
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
|
const struct bUUID *catalog_id);
|
||||||
const struct bUUID *catalog_id);
|
|
||||||
void filelist_tag_needs_filtering(struct FileList *filelist);
|
void filelist_tag_needs_filtering(struct FileList *filelist);
|
||||||
void filelist_filter(struct FileList *filelist);
|
void filelist_filter(struct FileList *filelist);
|
||||||
/**
|
/**
|
||||||
|
@ -79,6 +78,7 @@ struct ImBuf *filelist_file_getimage(const FileDirEntry *file);
|
||||||
struct ImBuf *filelist_geticon_image_ex(const FileDirEntry *file);
|
struct ImBuf *filelist_geticon_image_ex(const FileDirEntry *file);
|
||||||
struct ImBuf *filelist_geticon_image(struct FileList *filelist, int index);
|
struct ImBuf *filelist_geticon_image(struct FileList *filelist, int index);
|
||||||
int filelist_geticon(struct FileList *filelist, int index, bool is_main);
|
int filelist_geticon(struct FileList *filelist, int index, bool is_main);
|
||||||
|
int /* ThumbSource */ filelist_preview_source_get(int /* eFileSel_File_Types */ file_type);
|
||||||
|
|
||||||
struct FileList *filelist_new(short type);
|
struct FileList *filelist_new(short type);
|
||||||
void filelist_settype(struct FileList *filelist, short type);
|
void filelist_settype(struct FileList *filelist, short type);
|
||||||
|
|
|
@ -501,7 +501,7 @@ void ED_fileselect_activate_asset_catalog(const SpaceFile *sfile, const bUUID ca
|
||||||
}
|
}
|
||||||
|
|
||||||
FileAssetSelectParams *params = ED_fileselect_get_asset_params(sfile);
|
FileAssetSelectParams *params = ED_fileselect_get_asset_params(sfile);
|
||||||
params->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
|
params->asset_catalog_visibility = ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG;
|
||||||
params->catalog_id = catalog_id;
|
params->catalog_id = catalog_id;
|
||||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,6 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node
|
||||||
const AssetLibraryReference all_library_ref = all_library_reference();
|
const AssetLibraryReference all_library_ref = all_library_reference();
|
||||||
|
|
||||||
ED_assetlist_storage_fetch(&all_library_ref, &C);
|
ED_assetlist_storage_fetch(&all_library_ref, &C);
|
||||||
ED_assetlist_ensure_previews_job(&all_library_ref, &C);
|
|
||||||
|
|
||||||
asset_system::AssetLibrary *all_library = get_all_library_once_available();
|
asset_system::AssetLibrary *all_library = get_all_library_once_available();
|
||||||
if (!all_library) {
|
if (!all_library) {
|
||||||
|
|
|
@ -106,7 +106,6 @@ static void gather_search_items_for_all_assets(const bContext &C,
|
||||||
filter_settings.id_types = FILTER_ID_NT;
|
filter_settings.id_types = FILTER_ID_NT;
|
||||||
|
|
||||||
ED_assetlist_storage_fetch(&library_ref, &C);
|
ED_assetlist_storage_fetch(&library_ref, &C);
|
||||||
ED_assetlist_ensure_previews_job(&library_ref, &C);
|
|
||||||
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
||||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -229,7 +229,6 @@ static void gather_search_link_ops_for_asset_library(const bContext &C,
|
||||||
filter_settings.id_types = FILTER_ID_NT;
|
filter_settings.id_types = FILTER_ID_NT;
|
||||||
|
|
||||||
ED_assetlist_storage_fetch(&library_ref, &C);
|
ED_assetlist_storage_fetch(&library_ref, &C);
|
||||||
ED_assetlist_ensure_previews_job(&library_ref, &C);
|
|
||||||
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
||||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -201,6 +201,7 @@ typedef struct AssetWeakReference {
|
||||||
#
|
#
|
||||||
typedef struct AssetHandle {
|
typedef struct AssetHandle {
|
||||||
const struct FileDirEntry *file_data;
|
const struct FileDirEntry *file_data;
|
||||||
|
struct PreviewImage *preview;
|
||||||
} AssetHandle;
|
} AssetHandle;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -830,10 +830,10 @@ typedef struct FileAssetSelectParams {
|
||||||
FileSelectParams base_params;
|
FileSelectParams base_params;
|
||||||
|
|
||||||
AssetLibraryReference asset_library_ref;
|
AssetLibraryReference asset_library_ref;
|
||||||
short asset_catalog_visibility; /* eFileSel_Params_AssetCatalogVisibility */
|
short asset_catalog_visibility; /* AssetCatalogFilterMode */
|
||||||
char _pad[6];
|
char _pad[6];
|
||||||
/** If #asset_catalog_visibility is #FILE_SHOW_ASSETS_FROM_CATALOG, this sets the ID of the
|
/** If #asset_catalog_visibility is #ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG, this sets the ID of
|
||||||
* catalog to show. */
|
* the catalog to show. */
|
||||||
bUUID catalog_id;
|
bUUID catalog_id;
|
||||||
|
|
||||||
short import_type; /* eFileAssetImportType */
|
short import_type; /* eFileAssetImportType */
|
||||||
|
@ -1040,12 +1040,6 @@ typedef enum eFileSel_Params_Flag {
|
||||||
} eFileSel_Params_Flag;
|
} eFileSel_Params_Flag;
|
||||||
ENUM_OPERATORS(eFileSel_Params_Flag, FILE_FILTER_ASSET_CATALOG);
|
ENUM_OPERATORS(eFileSel_Params_Flag, FILE_FILTER_ASSET_CATALOG);
|
||||||
|
|
||||||
typedef enum eFileSel_Params_AssetCatalogVisibility {
|
|
||||||
FILE_SHOW_ASSETS_ALL_CATALOGS,
|
|
||||||
FILE_SHOW_ASSETS_FROM_CATALOG,
|
|
||||||
FILE_SHOW_ASSETS_WITHOUT_CATALOG,
|
|
||||||
} eFileSel_Params_AssetCatalogVisibility;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* #FileSelectParams.rename_flag / `sfile->params->rename_flag`.
|
* #FileSelectParams.rename_flag / `sfile->params->rename_flag`.
|
||||||
* \note short flag. Defined as bit-flags, but currently only used as exclusive status markers.
|
* \note short flag. Defined as bit-flags, but currently only used as exclusive status markers.
|
||||||
|
@ -2036,6 +2030,42 @@ typedef enum eSpreadsheetColumnValueType {
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Asset Browser
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
typedef enum AssetCatalogFilterMode {
|
||||||
|
ASSET_CATALOG_SHOW_ALL_ASSETS,
|
||||||
|
ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG,
|
||||||
|
ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG,
|
||||||
|
} AssetCatalogFilterMode;
|
||||||
|
|
||||||
|
typedef struct AssetCatalogFilterSettings {
|
||||||
|
short filter_mode; /* AssetCatalogFilterMode */
|
||||||
|
char _pad[6];
|
||||||
|
/** If #visibility_mode is #ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG, this sets the ID of the
|
||||||
|
* catalog to show. */
|
||||||
|
bUUID active_catalog_id;
|
||||||
|
} AssetCatalogFilterSettings;
|
||||||
|
|
||||||
|
typedef struct SpaceAssets {
|
||||||
|
SpaceLink *next, *prev;
|
||||||
|
/** Storage of regions for inactive spaces. */
|
||||||
|
ListBase regionbase;
|
||||||
|
char spacetype;
|
||||||
|
char link_flag;
|
||||||
|
char _pad0[6];
|
||||||
|
/* End 'SpaceLink' header. */
|
||||||
|
|
||||||
|
AssetLibraryReference asset_library_ref;
|
||||||
|
AssetCatalogFilterSettings catalog_filter;
|
||||||
|
/** For now store active asset as index. In future, this could store an #AssetIdentifier. */
|
||||||
|
int active_asset_idx;
|
||||||
|
char _pad1[4];
|
||||||
|
} SpaceAssets;
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Space Defines (eSpace_Type)
|
/** \name Space Defines (eSpace_Type)
|
||||||
* \{ */
|
* \{ */
|
||||||
|
@ -2075,9 +2105,10 @@ typedef enum eSpace_Type {
|
||||||
SPACE_CLIP = 20,
|
SPACE_CLIP = 20,
|
||||||
SPACE_TOPBAR = 21,
|
SPACE_TOPBAR = 21,
|
||||||
SPACE_STATUSBAR = 22,
|
SPACE_STATUSBAR = 22,
|
||||||
SPACE_SPREADSHEET = 23
|
SPACE_SPREADSHEET = 23,
|
||||||
|
SPACE_ASSETS = 24
|
||||||
|
|
||||||
#define SPACE_TYPE_NUM (SPACE_SPREADSHEET + 1)
|
#define SPACE_TYPE_NUM (SPACE_ASSETS + 1)
|
||||||
} eSpace_Type;
|
} eSpace_Type;
|
||||||
|
|
||||||
/* use for function args */
|
/* use for function args */
|
||||||
|
|
|
@ -507,6 +507,7 @@ typedef struct bTheme {
|
||||||
ThemeSpace space_topbar;
|
ThemeSpace space_topbar;
|
||||||
ThemeSpace space_statusbar;
|
ThemeSpace space_statusbar;
|
||||||
ThemeSpace space_spreadsheet;
|
ThemeSpace space_spreadsheet;
|
||||||
|
ThemeSpace space_assets;
|
||||||
|
|
||||||
/* 20 sets of bone colors for this theme */
|
/* 20 sets of bone colors for this theme */
|
||||||
ThemeWireColor tarm[20];
|
ThemeWireColor tarm[20];
|
||||||
|
@ -524,7 +525,7 @@ typedef struct bTheme {
|
||||||
#define UI_THEMESPACE_START(btheme) \
|
#define UI_THEMESPACE_START(btheme) \
|
||||||
(CHECK_TYPE_INLINE(btheme, bTheme *), &((btheme)->space_properties))
|
(CHECK_TYPE_INLINE(btheme, bTheme *), &((btheme)->space_properties))
|
||||||
#define UI_THEMESPACE_END(btheme) \
|
#define UI_THEMESPACE_END(btheme) \
|
||||||
(CHECK_TYPE_INLINE(btheme, bTheme *), (&((btheme)->space_spreadsheet) + 1))
|
(CHECK_TYPE_INLINE(btheme, bTheme *), (&((btheme)->space_assets) + 1))
|
||||||
|
|
||||||
typedef struct bAddon {
|
typedef struct bAddon {
|
||||||
struct bAddon *next, *prev;
|
struct bAddon *next, *prev;
|
||||||
|
|
|
@ -73,13 +73,17 @@ static int rna_AssetTag_editable(PointerRNA *ptr, const char **r_info)
|
||||||
{
|
{
|
||||||
AssetTag *asset_tag = ptr->data;
|
AssetTag *asset_tag = ptr->data;
|
||||||
ID *owner_id = ptr->owner_id;
|
ID *owner_id = ptr->owner_id;
|
||||||
if (owner_id && owner_id->asset_data) {
|
if (!owner_id) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner_id->asset_data) {
|
||||||
BLI_assert_msg(BLI_findindex(&owner_id->asset_data->tags, asset_tag) != -1,
|
BLI_assert_msg(BLI_findindex(&owner_id->asset_data->tags, asset_tag) != -1,
|
||||||
"The owner of the asset tag pointer is not the asset ID containing the tag");
|
"The owner of the asset tag pointer is not the asset ID containing the tag");
|
||||||
UNUSED_VARS_NDEBUG(asset_tag);
|
UNUSED_VARS_NDEBUG(asset_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rna_AssetMetaData_editable_from_owner_id(ptr->owner_id, owner_id->asset_data, r_info) ?
|
return rna_AssetMetaData_editable_from_owner_id(owner_id, owner_id->asset_data, r_info) ?
|
||||||
PROP_EDITABLE :
|
PROP_EDITABLE :
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,14 @@ static PointerRNA rna_Context_asset_file_handle_get(PointerRNA *ptr)
|
||||||
return newptr;
|
return newptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PointerRNA rna_Context_asset_handle_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
bContext *C = (bContext *)ptr->data;
|
||||||
|
PointerRNA newptr;
|
||||||
|
RNA_pointer_create(NULL, &RNA_AssetHandle, CTX_wm_asset_handle_ptr(C), &newptr);
|
||||||
|
return newptr;
|
||||||
|
}
|
||||||
|
|
||||||
static PointerRNA rna_Context_main_get(PointerRNA *ptr)
|
static PointerRNA rna_Context_main_get(PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
bContext *C = (bContext *)ptr->data;
|
bContext *C = (bContext *)ptr->data;
|
||||||
|
@ -298,6 +306,11 @@ void RNA_def_context(BlenderRNA *brna)
|
||||||
"The file of an active asset. Avoid using this, it will be replaced by "
|
"The file of an active asset. Avoid using this, it will be replaced by "
|
||||||
"a proper AssetHandle design");
|
"a proper AssetHandle design");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "asset_handle", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
RNA_def_property_struct_type(prop, "AssetHandle");
|
||||||
|
RNA_def_property_pointer_funcs(prop, "rna_Context_asset_handle_get", NULL, NULL, NULL);
|
||||||
|
|
||||||
/* Data */
|
/* Data */
|
||||||
prop = RNA_def_property(srna, "blend_data", PROP_POINTER, PROP_NONE);
|
prop = RNA_def_property(srna, "blend_data", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
|
|
@ -165,6 +165,11 @@ const EnumPropertyItem rna_enum_space_type_items[] = {
|
||||||
ICON_PROPERTIES,
|
ICON_PROPERTIES,
|
||||||
"Properties",
|
"Properties",
|
||||||
"Edit properties of active object and related data-blocks"},
|
"Edit properties of active object and related data-blocks"},
|
||||||
|
{SPACE_ASSETS,
|
||||||
|
"ASSET_BROWSER",
|
||||||
|
ICON_ASSET_MANAGER,
|
||||||
|
"Asset Browser",
|
||||||
|
"Browse in asset libraries"},
|
||||||
{SPACE_FILE, "FILE_BROWSER", ICON_FILEBROWSER, "File Browser", "Browse for files and assets"},
|
{SPACE_FILE, "FILE_BROWSER", ICON_FILEBROWSER, "File Browser", "Browse for files and assets"},
|
||||||
{SPACE_SPREADSHEET,
|
{SPACE_SPREADSHEET,
|
||||||
"SPREADSHEET",
|
"SPREADSHEET",
|
||||||
|
@ -617,6 +622,8 @@ static StructRNA *rna_Space_refine(struct PointerRNA *ptr)
|
||||||
return &RNA_SpaceClipEditor;
|
return &RNA_SpaceClipEditor;
|
||||||
case SPACE_SPREADSHEET:
|
case SPACE_SPREADSHEET:
|
||||||
return &RNA_SpaceSpreadsheet;
|
return &RNA_SpaceSpreadsheet;
|
||||||
|
case SPACE_ASSETS:
|
||||||
|
return &RNA_SpaceAssetBrowser;
|
||||||
|
|
||||||
/* Currently no type info. */
|
/* Currently no type info. */
|
||||||
case SPACE_SCRIPT:
|
case SPACE_SCRIPT:
|
||||||
|
@ -859,6 +866,20 @@ static void rna_Space_show_region_hud_update(bContext *C, PointerRNA *ptr)
|
||||||
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_HUD, RGN_FLAG_HIDDEN_BY_USER);
|
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_HUD, RGN_FLAG_HIDDEN_BY_USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Navigation Region. */
|
||||||
|
static bool rna_Space_show_region_nav_bar_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
return !rna_Space_bool_from_region_flag_get_by_type(ptr, RGN_TYPE_NAV_BAR, RGN_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
static void rna_Space_show_region_nav_bar_set(PointerRNA *ptr, bool value)
|
||||||
|
{
|
||||||
|
rna_Space_bool_from_region_flag_set_by_type(ptr, RGN_TYPE_NAV_BAR, RGN_FLAG_HIDDEN, !value);
|
||||||
|
}
|
||||||
|
static void rna_Space_show_region_nav_bar_update(bContext *C, PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
rna_Space_bool_from_region_flag_update_by_type(C, ptr, RGN_TYPE_NAV_BAR, RGN_FLAG_HIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
static bool rna_Space_view2d_sync_get(PointerRNA *ptr)
|
static bool rna_Space_view2d_sync_get(PointerRNA *ptr)
|
||||||
|
@ -3352,7 +3373,7 @@ static void rna_FileAssetSelectParams_catalog_id_set(PointerRNA *ptr, const char
|
||||||
|
|
||||||
if (value[0] == '\0') {
|
if (value[0] == '\0') {
|
||||||
params->catalog_id = BLI_uuid_nil();
|
params->catalog_id = BLI_uuid_nil();
|
||||||
params->asset_catalog_visibility = FILE_SHOW_ASSETS_ALL_CATALOGS;
|
params->asset_catalog_visibility = ASSET_CATALOG_SHOW_ALL_ASSETS;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3363,7 +3384,30 @@ static void rna_FileAssetSelectParams_catalog_id_set(PointerRNA *ptr, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
params->catalog_id = new_uuid;
|
params->catalog_id = new_uuid;
|
||||||
params->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
|
params->asset_catalog_visibility = ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int RNA_SpaceAssetBrowser_asset_library_get(PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
SpaceAssets *asset_space = ptr->data;
|
||||||
|
return ED_asset_library_reference_to_enum_value(&asset_space->asset_library_ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RNA_SpaceAssetBrowser_asset_library_set(PointerRNA *ptr, int value)
|
||||||
|
{
|
||||||
|
SpaceAssets *asset_space = ptr->data;
|
||||||
|
asset_space->asset_library_ref = ED_asset_library_reference_from_enum_value(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_AssetCatalogFilterSettings_active_catalog_id_get(PointerRNA *ptr, char *value)
|
||||||
|
{
|
||||||
|
const AssetCatalogFilterSettings *settings = ptr->data;
|
||||||
|
BLI_uuid_format(value, settings->active_catalog_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rna_AssetCatalogFilterSettings_active_catalog_id_length(PointerRNA *UNUSED(ptr))
|
||||||
|
{
|
||||||
|
return UUID_STRING_LEN - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -3463,6 +3507,10 @@ static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int regio
|
||||||
region_type_mask &= ~(1 << RGN_TYPE_HUD);
|
region_type_mask &= ~(1 << RGN_TYPE_HUD);
|
||||||
DEF_SHOW_REGION_PROPERTY(show_region_hud, "Adjust Last Operation", "");
|
DEF_SHOW_REGION_PROPERTY(show_region_hud, "Adjust Last Operation", "");
|
||||||
}
|
}
|
||||||
|
if (region_type_mask & (1 << RGN_TYPE_NAV_BAR)) {
|
||||||
|
region_type_mask &= ~(1 << RGN_TYPE_NAV_BAR);
|
||||||
|
DEF_SHOW_REGION_PROPERTY(show_region_nav_bar, "Navigation Bar", "");
|
||||||
|
}
|
||||||
BLI_assert(region_type_mask == 0);
|
BLI_assert(region_type_mask == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8172,6 +8220,83 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
|
||||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
|
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_def_asset_catalog_filter_settings(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
static const EnumPropertyItem asset_catalog_filter_mode[] = {
|
||||||
|
{ASSET_CATALOG_SHOW_ALL_ASSETS,
|
||||||
|
"SHOW_ALL_ASSETS",
|
||||||
|
ICON_NONE,
|
||||||
|
"All Assets",
|
||||||
|
"Show all assets, regardless of catalogs"},
|
||||||
|
{ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG,
|
||||||
|
"SHOW_ASSETS_FROM_CATALOG",
|
||||||
|
ICON_NONE,
|
||||||
|
"From Catalog",
|
||||||
|
"Show assets assigned to a specific catalog"},
|
||||||
|
{ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG,
|
||||||
|
"SHOW_ASSETS_WITHOUT_CATALOG",
|
||||||
|
ICON_NONE,
|
||||||
|
"Assets Without Catalog",
|
||||||
|
"Show any asset that doesn't have a recognized asset catalog assigned to it"},
|
||||||
|
{0, NULL, 0, NULL, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "AssetCatalogFilterSettings", NULL);
|
||||||
|
RNA_def_struct_ui_text(
|
||||||
|
srna,
|
||||||
|
"Asset Catalog Filter Settings",
|
||||||
|
"Options to determine how catalogs should affect which assets are visible");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "filter_mode", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_items(prop, asset_catalog_filter_mode);
|
||||||
|
RNA_def_property_ui_text(prop,
|
||||||
|
"Asset Catalog Filter Mode",
|
||||||
|
"Determine how filtering based on asset catalogs should be done");
|
||||||
|
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "active_catalog_id", PROP_STRING, PROP_NONE);
|
||||||
|
RNA_def_property_string_funcs(prop,
|
||||||
|
"rna_AssetCatalogFilterSettings_active_catalog_id_get",
|
||||||
|
"rna_AssetCatalogFilterSettings_active_catalog_id_length",
|
||||||
|
NULL);
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
|
RNA_def_property_ui_text(prop, "Catalog UUID", "The UUID of the catalog to show assets from");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rna_def_space_assets(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
PropertyRNA *prop;
|
||||||
|
StructRNA *srna;
|
||||||
|
|
||||||
|
rna_def_asset_catalog_filter_settings(brna);
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "SpaceAssetBrowser", "Space");
|
||||||
|
RNA_def_struct_sdna(srna, "SpaceAssets");
|
||||||
|
RNA_def_struct_ui_text(srna, "Space Asset Browser", "Asset browser space data");
|
||||||
|
|
||||||
|
rna_def_space_generic_show_region_toggles(srna, (1 << RGN_TYPE_NAV_BAR) | (1 << RGN_TYPE_UI));
|
||||||
|
|
||||||
|
prop = rna_def_asset_library_reference_common(
|
||||||
|
srna, "RNA_SpaceAssetBrowser_asset_library_get", "RNA_SpaceAssetBrowser_asset_library_set");
|
||||||
|
RNA_def_property_ui_text(prop, "Asset Library", "");
|
||||||
|
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "catalog_filter", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
|
RNA_def_property_struct_type(prop, "AssetCatalogFilterSettings");
|
||||||
|
RNA_def_property_ui_text(prop,
|
||||||
|
"Asset Catalog Filter",
|
||||||
|
"Parameters to set up rules for filtering assets based on the catalogs "
|
||||||
|
"they are assigned to");
|
||||||
|
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "active_asset_idx", PROP_INT, PROP_NONE);
|
||||||
|
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void RNA_def_space(BlenderRNA *brna)
|
void RNA_def_space(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
rna_def_space(brna);
|
rna_def_space(brna);
|
||||||
|
@ -8200,6 +8325,7 @@ void RNA_def_space(BlenderRNA *brna)
|
||||||
rna_def_space_node(brna);
|
rna_def_space_node(brna);
|
||||||
rna_def_space_clip(brna);
|
rna_def_space_clip(brna);
|
||||||
rna_def_space_spreadsheet(brna);
|
rna_def_space_spreadsheet(brna);
|
||||||
|
rna_def_space_assets(brna);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2522,6 +2522,26 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna)
|
||||||
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
|
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_def_userdef_theme_space_assets(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
/* space_file */
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "ThemeAssetBrowser", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "ThemeSpace");
|
||||||
|
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
|
||||||
|
RNA_def_struct_ui_text(srna, "Theme Asset Browser", "Theme settings for the Asset Browser");
|
||||||
|
|
||||||
|
rna_def_userdef_theme_spaces_main(srna);
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "row_alternate", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||||
|
RNA_def_property_array(prop, 4);
|
||||||
|
RNA_def_property_ui_text(prop, "Alternate Rows", "Overlay color on every other row");
|
||||||
|
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
|
||||||
|
}
|
||||||
|
|
||||||
static void rna_def_userdef_theme_space_outliner(BlenderRNA *brna)
|
static void rna_def_userdef_theme_space_outliner(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
|
@ -3932,6 +3952,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
|
||||||
{12, "OUTLINER", ICON_OUTLINER, "Outliner", ""},
|
{12, "OUTLINER", ICON_OUTLINER, "Outliner", ""},
|
||||||
{14, "PREFERENCES", ICON_PREFERENCES, "Preferences", ""},
|
{14, "PREFERENCES", ICON_PREFERENCES, "Preferences", ""},
|
||||||
{15, "INFO", ICON_INFO, "Info", ""},
|
{15, "INFO", ICON_INFO, "Info", ""},
|
||||||
|
{24, "ASSET_BROWSER", ICON_ASSET_MANAGER, "Asset Browser", ""},
|
||||||
{16, "FILE_BROWSER", ICON_FILEBROWSER, "File Browser", ""},
|
{16, "FILE_BROWSER", ICON_FILEBROWSER, "File Browser", ""},
|
||||||
{17, "CONSOLE", ICON_CONSOLE, "Python Console", ""},
|
{17, "CONSOLE", ICON_CONSOLE, "Python Console", ""},
|
||||||
{20, "CLIP_EDITOR", ICON_TRACKER, "Movie Clip Editor", ""},
|
{20, "CLIP_EDITOR", ICON_TRACKER, "Movie Clip Editor", ""},
|
||||||
|
@ -4072,6 +4093,13 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
|
||||||
RNA_def_property_pointer_sdna(prop, NULL, "space_spreadsheet");
|
RNA_def_property_pointer_sdna(prop, NULL, "space_spreadsheet");
|
||||||
RNA_def_property_struct_type(prop, "ThemeSpreadsheet");
|
RNA_def_property_struct_type(prop, "ThemeSpreadsheet");
|
||||||
RNA_def_property_ui_text(prop, "Spreadsheet", "");
|
RNA_def_property_ui_text(prop, "Spreadsheet", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "asset_browser", PROP_POINTER, PROP_NONE);
|
||||||
|
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||||
|
RNA_def_property_pointer_sdna(prop, NULL, "space_assets");
|
||||||
|
RNA_def_property_struct_type(prop, "ThemeAssetBrowser");
|
||||||
|
RNA_def_property_ui_text(prop, "Asset Browser", "");
|
||||||
|
|
||||||
/* end space types */
|
/* end space types */
|
||||||
|
|
||||||
prop = RNA_def_property(srna, "bone_color_sets", PROP_COLLECTION, PROP_NONE);
|
prop = RNA_def_property(srna, "bone_color_sets", PROP_COLLECTION, PROP_NONE);
|
||||||
|
@ -4319,6 +4347,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
|
||||||
rna_def_userdef_theme_space_view3d(brna);
|
rna_def_userdef_theme_space_view3d(brna);
|
||||||
rna_def_userdef_theme_space_graph(brna);
|
rna_def_userdef_theme_space_graph(brna);
|
||||||
rna_def_userdef_theme_space_file(brna);
|
rna_def_userdef_theme_space_file(brna);
|
||||||
|
rna_def_userdef_theme_space_assets(brna);
|
||||||
rna_def_userdef_theme_space_nla(brna);
|
rna_def_userdef_theme_space_nla(brna);
|
||||||
rna_def_userdef_theme_space_action(brna);
|
rna_def_userdef_theme_space_action(brna);
|
||||||
rna_def_userdef_theme_space_image(brna);
|
rna_def_userdef_theme_space_image(brna);
|
||||||
|
|
|
@ -487,10 +487,9 @@ typedef struct wmNotifier {
|
||||||
#define ND_SPACE_SPREADSHEET (22 << 16)
|
#define ND_SPACE_SPREADSHEET (22 << 16)
|
||||||
|
|
||||||
/* NC_ASSET */
|
/* NC_ASSET */
|
||||||
/* Denotes that the AssetList is done reading some previews. NOT that the preview generation of
|
/* Denote that something in the contents of an AssetList may have changed. Triggers re-filtering of
|
||||||
* assets is done. */
|
* items. */
|
||||||
#define ND_ASSET_LIST (1 << 16)
|
#define ND_ASSET_LIST (1 << 16)
|
||||||
#define ND_ASSET_LIST_PREVIEW (2 << 16)
|
|
||||||
#define ND_ASSET_LIST_READING (3 << 16)
|
#define ND_ASSET_LIST_READING (3 << 16)
|
||||||
/* Catalog data changed, requiring a redraw of catalog UIs. Note that this doesn't denote a
|
/* Catalog data changed, requiring a redraw of catalog UIs. Note that this doesn't denote a
|
||||||
* reloading of asset libraries & their catalogs should happen. That only happens on explicit user
|
* reloading of asset libraries & their catalogs should happen. That only happens on explicit user
|
||||||
|
|
|
@ -643,6 +643,10 @@ static void wm_file_read_pre(bool use_data, bool /*use_userdef*/)
|
||||||
UI_view2d_zoom_cache_reset();
|
UI_view2d_zoom_cache_reset();
|
||||||
|
|
||||||
ED_preview_restart_queue_free();
|
ED_preview_restart_queue_free();
|
||||||
|
/* #AssetLibraryService and the contained #AssetLibrary instances are destroyed on file loading.
|
||||||
|
* Asset lists may still reference them, so clear the asset list storage entirely for now. Later
|
||||||
|
* on, asset lists should actually live in the library, so this can be solved differently. */
|
||||||
|
ED_assetlist_storage_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -411,6 +411,10 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
|
||||||
else if (STRPREFIX(opname, "FILE_OT")) {
|
else if (STRPREFIX(opname, "FILE_OT")) {
|
||||||
km = WM_keymap_find_all(wm, "File Browser", sl->spacetype, 0);
|
km = WM_keymap_find_all(wm, "File Browser", sl->spacetype, 0);
|
||||||
}
|
}
|
||||||
|
/* Asset browser */
|
||||||
|
else if (STRPREFIX(opname, "ASSET_OT")) {
|
||||||
|
km = WM_keymap_find_all(wm, "Asset Browser", sl->spacetype, 0);
|
||||||
|
}
|
||||||
/* Logic Editor */
|
/* Logic Editor */
|
||||||
else if (STRPREFIX(opname, "LOGIC_OT")) {
|
else if (STRPREFIX(opname, "LOGIC_OT")) {
|
||||||
km = WM_keymap_find_all(wm, "Logic Editor", sl->spacetype, 0);
|
km = WM_keymap_find_all(wm, "Logic Editor", sl->spacetype, 0);
|
||||||
|
|
Loading…
Reference in New Issue