WIP: Rewrite asset browser as separate editor #104978
|
@ -1085,6 +1085,35 @@ const bTheme U_theme_default = {
|
|||
.edited_object = RGBA(0x00806266),
|
||||
.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 = {
|
||||
{
|
||||
.solid = RGBA(0x9a0000ff),
|
||||
|
|
|
@ -1388,6 +1388,42 @@
|
|||
</space_list>
|
||||
</ThemeSpreadsheet>
|
||||
</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>
|
||||
<ThemeBoneColorSet
|
||||
normal="#9a0000"
|
||||
|
|
|
@ -2186,7 +2186,6 @@ def km_info(params):
|
|||
|
||||
return keymap
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Editor (File Browser)
|
||||
|
||||
|
@ -2344,6 +2343,28 @@ def km_file_browser_buttons(_params):
|
|||
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)
|
||||
|
||||
|
@ -8057,6 +8078,7 @@ def generate_keymaps(params=None):
|
|||
km_node_editor(params),
|
||||
km_spreadsheet_generic(params),
|
||||
km_info(params),
|
||||
km_asset_browser(params),
|
||||
km_file_browser(params),
|
||||
km_file_browser_main(params),
|
||||
km_file_browser_buttons(params),
|
||||
|
|
|
@ -4161,6 +4161,7 @@ def generate_keymaps_impl(params=None):
|
|||
km_clip_editor(params),
|
||||
km_clip_graph_editor(params),
|
||||
km_clip_dopesheet_editor(params),
|
||||
# TODO asset browser
|
||||
|
||||
# Animation.
|
||||
km_frames(params),
|
||||
|
|
|
@ -60,6 +60,7 @@ _modules = [
|
|||
"space_toolsystem_common",
|
||||
"space_toolsystem_toolbar",
|
||||
|
||||
"space_assets",
|
||||
"space_clip",
|
||||
"space_console",
|
||||
"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()
|
||||
|
||||
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()
|
||||
self.draw_asset_browser_buttons(context)
|
||||
else:
|
||||
|
@ -638,19 +638,19 @@ class AssetBrowserMenu:
|
|||
return SpaceAssetInfo.is_asset_browser_poll(context)
|
||||
|
||||
|
||||
class ASSETBROWSER_MT_editor_menus(AssetBrowserMenu, Menu):
|
||||
bl_idname = "ASSETBROWSER_MT_editor_menus"
|
||||
class ASSETBROWSEROLD_MT_editor_menus(AssetBrowserMenu, Menu):
|
||||
bl_idname = "ASSETBROWSEROLD_MT_editor_menus"
|
||||
bl_label = ""
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
layout.menu("ASSETBROWSER_MT_view")
|
||||
layout.menu("ASSETBROWSER_MT_select")
|
||||
layout.menu("ASSETBROWSEROLD_MT_view")
|
||||
layout.menu("ASSETBROWSEROLD_MT_select")
|
||||
layout.menu("ASSETBROWSER_MT_catalog")
|
||||
|
||||
|
||||
class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu):
|
||||
class ASSETBROWSEROLD_MT_view(AssetBrowserMenu, Menu):
|
||||
bl_label = "View"
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -671,7 +671,7 @@ class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu):
|
|||
layout.menu("INFO_MT_area")
|
||||
|
||||
|
||||
class ASSETBROWSER_MT_select(AssetBrowserMenu, Menu):
|
||||
class ASSETBROWSEROLD_MT_select(AssetBrowserMenu, Menu):
|
||||
bl_label = "Select"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -700,7 +700,7 @@ class ASSETBROWSER_MT_catalog(AssetBrowserMenu, Menu):
|
|||
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_label = "Asset Metadata"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
@ -750,7 +750,7 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
|
|||
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"
|
||||
|
||||
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.separator()
|
||||
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"
|
||||
|
||||
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")
|
||||
|
||||
|
||||
class ASSETBROWSER_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
|
||||
class ASSETBROWSEROLD_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
|
||||
bl_label = "Tags"
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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="")
|
||||
|
||||
|
||||
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):
|
||||
tag = item
|
||||
|
||||
|
@ -850,15 +850,15 @@ classes = (
|
|||
FILEBROWSER_MT_view_pie,
|
||||
ASSETBROWSER_PT_display,
|
||||
ASSETBROWSER_PT_filter,
|
||||
ASSETBROWSER_MT_editor_menus,
|
||||
ASSETBROWSER_MT_view,
|
||||
ASSETBROWSER_MT_select,
|
||||
ASSETBROWSEROLD_MT_editor_menus,
|
||||
ASSETBROWSEROLD_MT_view,
|
||||
ASSETBROWSEROLD_MT_select,
|
||||
ASSETBROWSER_MT_catalog,
|
||||
ASSETBROWSER_MT_metadata_preview_menu,
|
||||
ASSETBROWSER_PT_metadata,
|
||||
ASSETBROWSER_PT_metadata_preview,
|
||||
ASSETBROWSER_PT_metadata_tags,
|
||||
ASSETBROWSER_UL_metadata_tags,
|
||||
ASSETBROWSEROLD_MT_metadata_preview_menu,
|
||||
ASSETBROWSEROLD_PT_metadata,
|
||||
ASSETBROWSEROLD_PT_metadata_preview,
|
||||
ASSETBROWSEROLD_PT_metadata_tags,
|
||||
ASSETBROWSEROLD_UL_metadata_tags,
|
||||
ASSETBROWSER_MT_context_menu,
|
||||
)
|
||||
|
||||
|
|
|
@ -1228,8 +1228,7 @@ class ThemeGenericClassGenerator:
|
|||
("Scroll Bar", "wcol_scroll"),
|
||||
("Progress Bar", "wcol_progress"),
|
||||
("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"),
|
||||
]
|
||||
|
||||
|
|
|
@ -205,6 +205,7 @@ struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C);
|
|||
struct SpaceClip *CTX_wm_space_clip(const bContext *C);
|
||||
struct SpaceTopBar *CTX_wm_space_topbar(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_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);
|
||||
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);
|
||||
|
||||
|
|
|
@ -929,6 +929,15 @@ SpaceSpreadsheet *CTX_wm_space_spreadsheet(const bContext *C)
|
|||
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)
|
||||
{
|
||||
C->wm.manager = wm;
|
||||
|
@ -1493,6 +1502,17 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid)
|
|||
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)
|
||||
{
|
||||
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) {
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case SPACE_ASSETS:
|
||||
case SPACE_INFO:
|
||||
case SPACE_IMASEL:
|
||||
case SPACE_SOUND:
|
||||
|
|
|
@ -104,6 +104,9 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
|||
*/
|
||||
{
|
||||
/* 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
|
||||
|
|
|
@ -27,6 +27,7 @@ if(WITH_BLENDER)
|
|||
add_subdirectory(sound)
|
||||
add_subdirectory(space_action)
|
||||
add_subdirectory(space_api)
|
||||
add_subdirectory(space_assets)
|
||||
add_subdirectory(space_buttons)
|
||||
add_subdirectory(space_clip)
|
||||
add_subdirectory(space_console)
|
||||
|
|
|
@ -33,6 +33,7 @@ set(SRC
|
|||
intern/asset_ops.cc
|
||||
intern/asset_temp_id_consumer.cc
|
||||
intern/asset_type.cc
|
||||
intern/asset_view_catalog_filter.cc
|
||||
|
||||
ED_asset_catalog.h
|
||||
ED_asset_catalog.hh
|
||||
|
@ -46,6 +47,7 @@ set(SRC
|
|||
ED_asset_mark_clear.h
|
||||
ED_asset_temp_id_consumer.h
|
||||
ED_asset_type.h
|
||||
ED_asset_view_catalog_filter.h
|
||||
intern/asset_library_reference.hh
|
||||
)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ struct AssetHandle;
|
|||
|
||||
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_identifier(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);
|
||||
ID_Type ED_asset_handle_get_id_type(const struct AssetHandle *asset);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct AssetCatalogFilterSettings;
|
||||
struct AssetLibraryReference;
|
||||
struct ID;
|
||||
struct bContext;
|
||||
|
@ -26,11 +27,12 @@ struct wmNotifier;
|
|||
*/
|
||||
void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_reference,
|
||||
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);
|
||||
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);
|
||||
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).
|
||||
*
|
||||
|
@ -50,11 +52,18 @@ void ED_assetlist_storage_id_remap(struct ID *id_old, struct ID *id_new);
|
|||
*/
|
||||
void ED_assetlist_storage_exit(void);
|
||||
|
||||
AssetHandle ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
||||
int asset_index);
|
||||
AssetHandle *ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
||||
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 AssetLibrary *ED_assetlist_library_get(
|
||||
const struct AssetLibraryReference *library_reference);
|
||||
|
||||
/**
|
||||
* \return True if the region needs a UI redraw.
|
||||
*/
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
|
@ -29,8 +30,12 @@ blender::asset_system::AssetLibrary *ED_assetlist_library_get_once_available(
|
|||
const AssetLibraryReference &library_reference);
|
||||
|
||||
/* 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,
|
||||
* 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return AS_asset_representation_metadata_get(asset_handle->file_data->asset);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "AS_asset_library.hh"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
|
@ -21,6 +22,7 @@
|
|||
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_preferences.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 {
|
||||
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_;
|
||||
PreviewTimer previews_timer_;
|
||||
|
||||
public:
|
||||
AssetList() = delete;
|
||||
|
@ -109,14 +92,15 @@ class AssetList : NonCopyable {
|
|||
|
||||
void setup();
|
||||
void fetch(const bContext &C);
|
||||
void ensurePreviewsJob(const bContext *C);
|
||||
void setCatalogFilterSettings(const AssetCatalogFilterSettings &settings);
|
||||
void clear(bContext *C);
|
||||
|
||||
AssetHandle asset_get_by_index(int index) const;
|
||||
AssetHandle *asset_get_by_index(int index) const;
|
||||
|
||||
bool needsRefetch() const;
|
||||
bool isLoaded() const;
|
||||
asset_system::AssetLibrary *asset_library() const;
|
||||
AssetHandle &asset_handle_from_file(const FileDirEntry &) const;
|
||||
void iterate(AssetListIterFn fn) const;
|
||||
bool listen(const wmNotifier ¬ifier) const;
|
||||
int size() const;
|
||||
|
@ -167,6 +151,7 @@ void AssetList::fetch(const bContext &C)
|
|||
if (filelist_needs_force_reset(files)) {
|
||||
filelist_readjob_stop(files, CTX_wm_manager(&C));
|
||||
filelist_clear_from_reset_tag(files);
|
||||
asset_handle_map_.clear();
|
||||
}
|
||||
|
||||
if (filelist_needs_reading(files)) {
|
||||
|
@ -178,6 +163,12 @@ void AssetList::fetch(const bContext &C)
|
|||
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
|
||||
{
|
||||
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_));
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
FileList *files = filelist_;
|
||||
|
@ -204,7 +204,7 @@ void AssetList::iterate(AssetListIterFn fn) const
|
|||
continue;
|
||||
}
|
||||
|
||||
AssetHandle asset_handle = {file};
|
||||
AssetHandle &asset_handle = asset_handle_from_file(*file);
|
||||
if (!fn(asset_handle)) {
|
||||
/* If the callback returns false, we stop iterating. */
|
||||
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)
|
||||
{
|
||||
/* Based on #ED_fileselect_clear() */
|
||||
|
@ -244,13 +220,18 @@ void AssetList::clear(bContext *C)
|
|||
filelist_readjob_stop(files, CTX_wm_manager(C));
|
||||
filelist_freelib(files);
|
||||
filelist_clear(files);
|
||||
asset_handle_map_.clear();
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
void ED_assetlist_ensure_previews_job(const AssetLibraryReference *library_reference,
|
||||
const bContext *C)
|
||||
void ED_assetlist_catalog_filter_set(const struct AssetLibraryReference *library_reference,
|
||||
const struct AssetCatalogFilterSettings *settings)
|
||||
{
|
||||
|
||||
AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
||||
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();
|
||||
}
|
||||
|
||||
AssetHandle ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
||||
int asset_index)
|
||||
AssetHandle *ED_assetlist_asset_get_by_index(const AssetLibraryReference *library_reference,
|
||||
int asset_index)
|
||||
{
|
||||
const AssetList *list = AssetListStorage::lookup_list(*library_reference);
|
||||
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 *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);
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
{
|
||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
if (!sfile) {
|
||||
return false;
|
||||
}
|
||||
const AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
||||
const AssetLibrary *asset_library = get_asset_library(C);
|
||||
if (!asset_library) {
|
||||
return false;
|
||||
}
|
||||
|
@ -449,16 +460,20 @@ static bool asset_catalog_operator_poll(bContext *C)
|
|||
|
||||
static int asset_catalog_new_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
struct AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
||||
AssetLibrary *asset_library = get_asset_library(C);
|
||||
char *parent_path = RNA_string_get_alloc(op->ptr, "parent_path", nullptr, 0, nullptr);
|
||||
|
||||
blender::asset_system::AssetCatalog *new_catalog = ED_asset_catalog_add(
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
|
@ -489,8 +504,7 @@ static void ASSET_OT_catalog_new(struct wmOperatorType *ot)
|
|||
|
||||
static int asset_catalog_delete_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
struct AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
||||
AssetLibrary *asset_library = get_asset_library(C);
|
||||
char *catalog_id_str = RNA_string_get_alloc(op->ptr, "catalog_id", nullptr, 0, nullptr);
|
||||
asset_system::CatalogID catalog_id;
|
||||
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)
|
||||
{
|
||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
if (!sfile) {
|
||||
return nullptr;
|
||||
if (const SpaceFile *sfile = CTX_wm_space_file(C)) {
|
||||
AssetLibrary *asset_lib = ED_fileselect_active_asset_library_get(sfile);
|
||||
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 AS_asset_library_get_catalog_service(asset_lib);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -572,7 +589,7 @@ static int asset_catalog_redo_exec(bContext *C, wmOperator * /*op*/)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -649,8 +666,7 @@ static bool asset_catalogs_save_poll(bContext *C)
|
|||
|
||||
static int asset_catalogs_save_exec(bContext *C, wmOperator * /*op*/)
|
||||
{
|
||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
::AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
|
||||
::AssetLibrary *asset_library = get_asset_library(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)
|
||||
{
|
||||
/* This operator only works when the asset browser is set to Current File. */
|
||||
const SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
if (sfile == nullptr) {
|
||||
const AssetLibraryReference *asset_library_ref = CTX_wm_asset_library_ref(C);
|
||||
if (asset_library_ref == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (!ED_fileselect_is_local_asset_library(sfile)) {
|
||||
|
||||
if (asset_library_ref->type == ASSET_LIBRARY_LOCAL) {
|
||||
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
|
||||
* \{ */
|
||||
|
||||
void ED_spacetype_assets(void);
|
||||
void ED_spacetype_outliner(void);
|
||||
void ED_spacetype_view3d(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_rows > 0);
|
||||
|
||||
const int space_x = style->columnspace;
|
||||
const int space_y = style->buttonspacey;
|
||||
const int space_x = litem->align ? 0 : style->columnspace;
|
||||
const int space_y = litem->align ? 0 : style->buttonspacey;
|
||||
|
||||
blender::Array<int, 64> widths(gflow->tot_columns);
|
||||
blender::Array<int, 64> heights(gflow->tot_rows);
|
||||
|
|
|
@ -38,7 +38,9 @@ struct AssetViewListData {
|
|||
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);
|
||||
if (id != nullptr) {
|
||||
|
@ -54,13 +56,14 @@ static void asset_view_item_but_drag_set(uiBut *but, AssetHandle *asset_handle)
|
|||
|
||||
if (blend_path[0]) {
|
||||
ImBuf *imbuf = ED_assetlist_asset_image_get(asset_handle);
|
||||
UI_but_drag_set_asset(but,
|
||||
asset_handle,
|
||||
BLI_strdup(blend_path),
|
||||
import_method,
|
||||
ED_asset_handle_get_preview_icon_id(asset_handle),
|
||||
imbuf,
|
||||
1.0f);
|
||||
UI_but_drag_set_asset(
|
||||
but,
|
||||
asset_handle,
|
||||
BLI_strdup(blend_path),
|
||||
import_method,
|
||||
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, asset_handle),
|
||||
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;
|
||||
|
||||
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;
|
||||
RNA_pointer_create(&list_data->screen->id,
|
||||
|
@ -88,30 +92,31 @@ static void asset_view_draw_item(uiList *ui_list,
|
|||
|
||||
uiBlock *block = uiLayoutGetBlock(layout);
|
||||
const bool show_names = list_data->show_names;
|
||||
/* TODO ED_fileselect_init_layout(). Share somehow? */
|
||||
const float size_x = (96.0f / 20.0f) * UI_UNIT_X;
|
||||
const float size_y = (96.0f / 20.0f) * UI_UNIT_Y - (show_names ? 0 : UI_UNIT_Y);
|
||||
uiBut *but = uiDefIconTextBut(block,
|
||||
UI_BTYPE_PREVIEW_TILE,
|
||||
0,
|
||||
ED_asset_handle_get_preview_icon_id(&asset_handle),
|
||||
show_names ? ED_asset_handle_get_name(&asset_handle) : "",
|
||||
0,
|
||||
0,
|
||||
size_x,
|
||||
size_y,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
ui_def_but_icon(but,
|
||||
ED_asset_handle_get_preview_icon_id(&asset_handle),
|
||||
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
||||
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
||||
const int size_x = UI_preview_tile_size_x();
|
||||
const int size_y = show_names ? UI_preview_tile_size_y() : UI_preview_tile_size_y_no_label();
|
||||
uiBut *but = uiDefIconTextBut(
|
||||
block,
|
||||
UI_BTYPE_PREVIEW_TILE,
|
||||
0,
|
||||
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, &asset_handle),
|
||||
show_names ? ED_asset_handle_get_name(&asset_handle) : "",
|
||||
0,
|
||||
0,
|
||||
size_x,
|
||||
size_y,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
ui_def_but_icon(
|
||||
but,
|
||||
ED_assetlist_asset_preview_icon_id_request(&list_data->asset_library_ref, &asset_handle),
|
||||
/* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
|
||||
UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
|
||||
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,
|
||||
[&name_filter, list_data, &filter_settings](
|
||||
const PointerRNA &itemptr, blender::StringRefNull name, int index) {
|
||||
AssetHandle asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||
AssetHandle *asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, asset)) {
|
||||
return UI_LIST_ITEM_NEVER_SHOW;
|
||||
}
|
||||
return name_filter(itemptr, name, index);
|
||||
|
@ -139,8 +144,8 @@ static void asset_view_filter_items(uiList *ui_list,
|
|||
dataptr,
|
||||
propname,
|
||||
[list_data](const PointerRNA & /*itemptr*/, int index) -> std::string {
|
||||
AssetHandle asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
||||
return ED_asset_handle_get_name(&asset);
|
||||
AssetHandle *asset = ED_assetlist_asset_get_by_index(&list_data->asset_library_ref, index);
|
||||
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_ensure_previews_job(&asset_library_ref, C);
|
||||
const int tot_items = ED_assetlist_size(&asset_library_ref);
|
||||
|
||||
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_TOPBAR);
|
||||
SPACE_MENU_NOP(SPACE_SPREADSHEET);
|
||||
/* TODO */
|
||||
SPACE_MENU_NOP(SPACE_ASSETS);
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
rcti trect = *rect;
|
||||
const float text_size = UI_UNIT_Y;
|
||||
float font_dims[2] = {0.0f, 0.0f};
|
||||
const bool has_text = name && name[0];
|
||||
const float padding = PREVIEW_PAD;
|
||||
|
||||
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 */
|
||||
rect->ymin += text_size;
|
||||
rect->ymin += round_fl_to_int(font_dims[1] + 2 * padding);
|
||||
}
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
widget_draw_preview(BIFIconID(iconid), 1.0f, rect);
|
||||
|
@ -5480,15 +5484,9 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle,
|
|||
return;
|
||||
}
|
||||
|
||||
BLF_width_and_height(
|
||||
fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
|
||||
|
||||
/* text rect */
|
||||
trect.ymin += U.widget_unit / 2;
|
||||
trect.ymax = trect.ymin + font_dims[1];
|
||||
if (trect.xmax > rect->xmax - PREVIEW_PAD) {
|
||||
trect.xmax = rect->xmax - PREVIEW_PAD;
|
||||
}
|
||||
BLI_rcti_pad(&trect, -padding * 2, -padding * 2);
|
||||
trect.ymax = round_fl_to_int(trect.ymin + font_dims[1]);
|
||||
|
||||
{
|
||||
char drawstr[UI_MAX_DRAW_STR];
|
||||
|
|
|
@ -140,6 +140,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
|
|||
case SPACE_SPREADSHEET:
|
||||
ts = &btheme->space_spreadsheet;
|
||||
break;
|
||||
case SPACE_ASSETS:
|
||||
ts = &btheme->space_assets;
|
||||
break;
|
||||
default:
|
||||
ts = &btheme->space_view3d;
|
||||
break;
|
||||
|
|
|
@ -23,6 +23,7 @@ set(SRC
|
|||
set(LIB
|
||||
bf_editor_geometry
|
||||
bf_editor_space_action
|
||||
bf_editor_space_assets
|
||||
bf_editor_space_buttons
|
||||
bf_editor_space_clip
|
||||
bf_editor_space_console
|
||||
|
|
|
@ -63,6 +63,7 @@ void ED_spacetypes_init(void)
|
|||
U.widget_unit = 20;
|
||||
|
||||
/* Create space types. */
|
||||
ED_spacetype_assets();
|
||||
ED_spacetype_outliner();
|
||||
ED_spacetype_view3d();
|
||||
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::asset_system;
|
||||
|
||||
namespace blender::ed::asset_browser {
|
||||
namespace blender::ed::space_file::asset_browser {
|
||||
|
||||
class AssetCatalogTreeViewAllItem;
|
||||
|
||||
|
@ -218,11 +218,11 @@ AssetCatalogTreeViewAllItem &AssetCatalogTreeView::add_all_item()
|
|||
|
||||
AssetCatalogTreeViewAllItem &item = add_tree_item<AssetCatalogTreeViewAllItem>(IFACE_("All"));
|
||||
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);
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -234,23 +234,24 @@ void AssetCatalogTreeView::add_unassigned_item()
|
|||
IFACE_("Unassigned"), ICON_FILE_HIDDEN);
|
||||
|
||||
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);
|
||||
});
|
||||
item.set_is_active_fn(
|
||||
[params]() { return params->asset_catalog_visibility == FILE_SHOW_ASSETS_WITHOUT_CATALOG; });
|
||||
item.set_is_active_fn([params]() {
|
||||
return params->asset_catalog_visibility == ASSET_CATALOG_SHOW_ASSETS_WITHOUT_CATALOG;
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -670,98 +671,11 @@ bool AssetCatalogTreeViewUnassignedItem::DropTarget::on_drop(struct bContext *C,
|
|||
C, get_view<AssetCatalogTreeView>(), drag, CatalogID{});
|
||||
}
|
||||
|
||||
} // namespace blender::ed::asset_browser
|
||||
} // namespace blender::ed::space_file::asset_browser
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
namespace blender::ed::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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
namespace asset_browser = blender::ed::space_file::asset_browser;
|
||||
|
||||
void file_create_asset_catalog_tree_view_in_layout(::AssetLibrary *asset_library,
|
||||
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(
|
||||
*block,
|
||||
"asset catalog tree view",
|
||||
std::make_unique<ed::asset_browser::AssetCatalogTreeView>(
|
||||
asset_library, params, *space_file));
|
||||
std::make_unique<asset_browser::AssetCatalogTreeView>(asset_library, params, *space_file));
|
||||
|
||||
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 */
|
||||
|
||||
/* C-handle for #ed::asset_browser::AssetCatalogFilterSettings. */
|
||||
typedef struct FileAssetCatalogFilterSettingsHandle FileAssetCatalogFilterSettingsHandle;
|
||||
|
||||
void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library,
|
||||
struct uiLayout *layout,
|
||||
SpaceFile *space_file,
|
||||
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
|
||||
struct SpaceFile *space_file,
|
||||
struct FileAssetSelectParams *params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "DNA_asset_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "ED_asset_view_catalog_filter.h"
|
||||
#include "ED_datafiles.h"
|
||||
#include "ED_fileselect.h"
|
||||
#include "ED_screen.h"
|
||||
|
@ -197,7 +198,7 @@ struct FileListFilter {
|
|||
char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
|
||||
short flags;
|
||||
|
||||
FileAssetCatalogFilterSettingsHandle *asset_catalog_filter;
|
||||
AssetViewCatalogFilterSettingsHandle *asset_catalog_filter;
|
||||
};
|
||||
|
||||
/** #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 "
|
||||
"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);
|
||||
|
||||
/* 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)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1024,17 +1026,16 @@ void filelist_setindexer(FileList *filelist, const FileIndexerType *indexer)
|
|||
filelist->indexer = indexer;
|
||||
}
|
||||
|
||||
void filelist_set_asset_catalog_filter_options(
|
||||
FileList *filelist,
|
||||
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
|
||||
const ::bUUID *catalog_id)
|
||||
void filelist_set_asset_catalog_filter_options(FileList *filelist,
|
||||
AssetCatalogFilterMode catalog_visibility,
|
||||
const ::bUUID *catalog_id)
|
||||
{
|
||||
if (!filelist->filter_data.asset_catalog_filter) {
|
||||
/* 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);
|
||||
|
||||
if (needs_update) {
|
||||
|
@ -1468,6 +1469,26 @@ static int filelist_intern_free_main_files(FileList *filelist)
|
|||
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)
|
||||
{
|
||||
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);
|
||||
FileListEntryPreview *preview = preview_taskdata->preview;
|
||||
|
||||
/* XXX #THB_SOURCE_IMAGE for "historic" reasons. The case of an undefined source should be
|
||||
* handled better. */
|
||||
ThumbSource source = THB_SOURCE_IMAGE;
|
||||
ThumbSource source = static_cast<ThumbSource>(filelist_preview_source_get(preview->flags));
|
||||
|
||||
// printf("%s: Start (%d)...\n", __func__, threadid);
|
||||
|
||||
// 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);
|
||||
/* 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. */
|
||||
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,
|
||||
|
|
|
@ -55,12 +55,11 @@ void filelist_setfilter_options(struct FileList *filelist,
|
|||
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
|
||||
* #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(
|
||||
struct FileList *filelist,
|
||||
eFileSel_Params_AssetCatalogVisibility catalog_visibility,
|
||||
const struct bUUID *catalog_id);
|
||||
void filelist_set_asset_catalog_filter_options(struct FileList *filelist,
|
||||
AssetCatalogFilterMode catalog_visibility,
|
||||
const struct bUUID *catalog_id);
|
||||
void filelist_tag_needs_filtering(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(struct FileList *filelist, int index);
|
||||
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);
|
||||
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);
|
||||
params->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
|
||||
params->asset_catalog_visibility = ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG;
|
||||
params->catalog_id = catalog_id;
|
||||
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();
|
||||
|
||||
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();
|
||||
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;
|
||||
|
||||
ED_assetlist_storage_fetch(&library_ref, &C);
|
||||
ED_assetlist_ensure_previews_job(&library_ref, &C);
|
||||
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||
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;
|
||||
|
||||
ED_assetlist_storage_fetch(&library_ref, &C);
|
||||
ED_assetlist_ensure_previews_job(&library_ref, &C);
|
||||
ED_assetlist_iterate(library_ref, [&](AssetHandle asset) {
|
||||
if (!ED_asset_filter_matches_asset(&filter_settings, &asset)) {
|
||||
return true;
|
||||
|
|
|
@ -201,6 +201,7 @@ typedef struct AssetWeakReference {
|
|||
#
|
||||
typedef struct AssetHandle {
|
||||
const struct FileDirEntry *file_data;
|
||||
struct PreviewImage *preview;
|
||||
} AssetHandle;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -830,10 +830,10 @@ typedef struct FileAssetSelectParams {
|
|||
FileSelectParams base_params;
|
||||
|
||||
AssetLibraryReference asset_library_ref;
|
||||
short asset_catalog_visibility; /* eFileSel_Params_AssetCatalogVisibility */
|
||||
short asset_catalog_visibility; /* AssetCatalogFilterMode */
|
||||
char _pad[6];
|
||||
/** If #asset_catalog_visibility is #FILE_SHOW_ASSETS_FROM_CATALOG, this sets the ID of the
|
||||
* catalog to show. */
|
||||
/** If #asset_catalog_visibility is #ASSET_CATALOG_SHOW_ASSETS_FROM_CATALOG, this sets the ID of
|
||||
* the catalog to show. */
|
||||
bUUID catalog_id;
|
||||
|
||||
short import_type; /* eFileAssetImportType */
|
||||
|
@ -1040,12 +1040,6 @@ typedef enum eFileSel_Params_Flag {
|
|||
} eFileSel_Params_Flag;
|
||||
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`.
|
||||
* \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)
|
||||
* \{ */
|
||||
|
@ -2075,9 +2105,10 @@ typedef enum eSpace_Type {
|
|||
SPACE_CLIP = 20,
|
||||
SPACE_TOPBAR = 21,
|
||||
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;
|
||||
|
||||
/* use for function args */
|
||||
|
|
|
@ -507,6 +507,7 @@ typedef struct bTheme {
|
|||
ThemeSpace space_topbar;
|
||||
ThemeSpace space_statusbar;
|
||||
ThemeSpace space_spreadsheet;
|
||||
ThemeSpace space_assets;
|
||||
|
||||
/* 20 sets of bone colors for this theme */
|
||||
ThemeWireColor tarm[20];
|
||||
|
@ -524,7 +525,7 @@ typedef struct bTheme {
|
|||
#define UI_THEMESPACE_START(btheme) \
|
||||
(CHECK_TYPE_INLINE(btheme, bTheme *), &((btheme)->space_properties))
|
||||
#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 {
|
||||
struct bAddon *next, *prev;
|
||||
|
|
|
@ -73,13 +73,17 @@ static int rna_AssetTag_editable(PointerRNA *ptr, const char **r_info)
|
|||
{
|
||||
AssetTag *asset_tag = ptr->data;
|
||||
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,
|
||||
"The owner of the asset tag pointer is not the asset ID containing the 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 :
|
||||
0;
|
||||
}
|
||||
|
|
|
@ -140,6 +140,14 @@ static PointerRNA rna_Context_asset_file_handle_get(PointerRNA *ptr)
|
|||
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)
|
||||
{
|
||||
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 "
|
||||
"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 */
|
||||
prop = RNA_def_property(srna, "blend_data", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
|
|
@ -165,6 +165,11 @@ const EnumPropertyItem rna_enum_space_type_items[] = {
|
|||
ICON_PROPERTIES,
|
||||
"Properties",
|
||||
"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_SPREADSHEET,
|
||||
"SPREADSHEET",
|
||||
|
@ -617,6 +622,8 @@ static StructRNA *rna_Space_refine(struct PointerRNA *ptr)
|
|||
return &RNA_SpaceClipEditor;
|
||||
case SPACE_SPREADSHEET:
|
||||
return &RNA_SpaceSpreadsheet;
|
||||
case SPACE_ASSETS:
|
||||
return &RNA_SpaceAssetBrowser;
|
||||
|
||||
/* Currently no type info. */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
|
@ -3352,7 +3373,7 @@ static void rna_FileAssetSelectParams_catalog_id_set(PointerRNA *ptr, const char
|
|||
|
||||
if (value[0] == '\0') {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3363,7 +3384,30 @@ static void rna_FileAssetSelectParams_catalog_id_set(PointerRNA *ptr, const char
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -3463,6 +3507,10 @@ static void rna_def_space_generic_show_region_toggles(StructRNA *srna, int regio
|
|||
region_type_mask &= ~(1 << RGN_TYPE_HUD);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -8172,6 +8220,83 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
|
|||
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)
|
||||
{
|
||||
rna_def_space(brna);
|
||||
|
@ -8200,6 +8325,7 @@ void RNA_def_space(BlenderRNA *brna)
|
|||
rna_def_space_node(brna);
|
||||
rna_def_space_clip(brna);
|
||||
rna_def_space_spreadsheet(brna);
|
||||
rna_def_space_assets(brna);
|
||||
}
|
||||
|
||||
#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");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -3932,6 +3952,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
|
|||
{12, "OUTLINER", ICON_OUTLINER, "Outliner", ""},
|
||||
{14, "PREFERENCES", ICON_PREFERENCES, "Preferences", ""},
|
||||
{15, "INFO", ICON_INFO, "Info", ""},
|
||||
{24, "ASSET_BROWSER", ICON_ASSET_MANAGER, "Asset Browser", ""},
|
||||
{16, "FILE_BROWSER", ICON_FILEBROWSER, "File Browser", ""},
|
||||
{17, "CONSOLE", ICON_CONSOLE, "Python Console", ""},
|
||||
{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_struct_type(prop, "ThemeSpreadsheet");
|
||||
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 */
|
||||
|
||||
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_graph(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_action(brna);
|
||||
rna_def_userdef_theme_space_image(brna);
|
||||
|
|
|
@ -487,10 +487,9 @@ typedef struct wmNotifier {
|
|||
#define ND_SPACE_SPREADSHEET (22 << 16)
|
||||
|
||||
/* NC_ASSET */
|
||||
/* Denotes that the AssetList is done reading some previews. NOT that the preview generation of
|
||||
* assets is done. */
|
||||
/* Denote that something in the contents of an AssetList may have changed. Triggers re-filtering of
|
||||
* items. */
|
||||
#define ND_ASSET_LIST (1 << 16)
|
||||
#define ND_ASSET_LIST_PREVIEW (2 << 16)
|
||||
#define ND_ASSET_LIST_READING (3 << 16)
|
||||
/* 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
|
||||
|
|
|
@ -643,6 +643,10 @@ static void wm_file_read_pre(bool use_data, bool /*use_userdef*/)
|
|||
UI_view2d_zoom_cache_reset();
|
||||
|
||||
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")) {
|
||||
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 */
|
||||
else if (STRPREFIX(opname, "LOGIC_OT")) {
|
||||
km = WM_keymap_find_all(wm, "Logic Editor", sl->spacetype, 0);
|
||||
|
|
Loading…
Reference in New Issue