Asset Shelf: Add optional operator to activate assets

The operator stored when registering the asset shelf will be called
with properties that reference the asset (a weak reference, split into
three properties already used in other asset-related operators). The
operator is called whenever a grid view item is activated, and is
meant to do things like import and activate a brush asset.

Previously Reviewed: https://projects.blender.org/blender/blender/pulls/117861

Pull Request: https://projects.blender.org/blender/blender/pulls/121402
This commit is contained in:
Hans Goudey
2024-05-03 19:24:00 +02:00
committed by Hans Goudey
parent 3f15c244f4
commit 798219225d
5 changed files with 84 additions and 15 deletions

View File

@@ -534,6 +534,9 @@ struct AssetShelfType {
int space_type;
/** Operator to call when activating a grid view item. */
std::string activate_operator;
AssetShelfTypeFlag flag;
short default_preview_size;

View File

@@ -21,6 +21,7 @@
#include "ED_asset_handle.hh"
#include "ED_asset_list.hh"
#include "ED_asset_menu_utils.hh"
#include "ED_asset_shelf.hh"
#include "UI_grid_view.hh"
@@ -192,16 +193,17 @@ void AssetViewItem::disable_asset_drag()
void AssetViewItem::build_grid_tile(uiLayout &layout) const
{
PointerRNA file_ptr = RNA_pointer_create(
nullptr,
&RNA_FileSelectEntry,
/* XXX passing file pointer here, should be asset handle or asset representation. */
const_cast<FileDirEntry *>(asset_.file_data));
const AssetView &asset_view = reinterpret_cast<const AssetView &>(this->get_view());
const AssetShelfType &shelf_type = *asset_view.shelf_.type;
uiBlock *block = uiLayoutGetBlock(&layout);
UI_but_context_ptr_set(
block, reinterpret_cast<uiBut *>(view_item_but_), "active_file", &file_ptr);
ui::PreviewGridItem::build_grid_tile(layout);
wmOperatorType *ot = WM_operatortype_find(shelf_type.activate_operator.c_str(), true);
PointerRNA op_props = PointerRNA_NULL;
if (ot) {
WM_operator_properties_create_ptr(&op_props, ot);
asset::operator_asset_reference_props_set(*handle_get_representation(&asset_), op_props);
}
ui::PreviewGridItem::build_grid_tile_button(layout, ot, &op_props);
}
void AssetViewItem::build_context_menu(bContext &C, uiLayout &column) const

View File

@@ -19,6 +19,7 @@
#include "UI_resources.hh"
struct bContext;
struct PointerRNA;
struct uiBlock;
struct uiButViewItem;
struct uiLayout;
@@ -204,6 +205,13 @@ class PreviewGridItem : public AbstractGridViewItem {
void build_grid_tile(uiLayout &layout) const override;
/**
* \note: Takes ownership of the operator properies defined in \a op_props.
*/
void build_grid_tile_button(uiLayout &layout,
const wmOperatorType *ot = nullptr,
const PointerRNA *op_props = nullptr) const;
/**
* Set a custom callback to execute when activating this view item. This way users don't have to
* sub-class #PreviewGridItem, just to implement custom activation behavior (a common thing to

View File

@@ -9,6 +9,7 @@
#include <cfloat>
#include <cmath>
#include <limits>
#include <optional>
#include <stdexcept>
#include "BKE_icons.h"
@@ -17,6 +18,8 @@
#include "WM_types.hh"
#include "RNA_access.hh"
#include "UI_interface.hh"
#include "interface_intern.hh"
@@ -405,23 +408,42 @@ PreviewGridItem::PreviewGridItem(StringRef identifier, StringRef label, int prev
{
}
void PreviewGridItem::build_grid_tile(uiLayout &layout) const
void PreviewGridItem::build_grid_tile_button(uiLayout &layout,
const wmOperatorType *ot,
const PointerRNA *op_props) const
{
const GridViewStyle &style = this->get_view().get_style();
uiBlock *block = uiLayoutGetBlock(&layout);
uiBut *but = uiDefBut(block,
uiBut *but;
if (ot) {
but = uiDefButO_ptr(block,
UI_BTYPE_PREVIEW_TILE,
0,
const_cast<wmOperatorType *>(ot),
WM_OP_INVOKE_REGION_WIN,
hide_label_ ? "" : label,
0,
0,
style.tile_width,
style.tile_height,
nullptr,
0,
0,
"");
but->opptr = MEM_new<PointerRNA>(__func__, *op_props);
}
else {
but = uiDefBut(block,
UI_BTYPE_PREVIEW_TILE,
0,
hide_label_ ? "" : label,
0,
0,
style.tile_width,
style.tile_height,
nullptr,
0,
0,
"");
}
/* Draw icons that are not previews or images as normal icons with a fixed icon size. Otherwise
* they will be upscaled to the button size. Should probably be done by the widget code. */
const int is_preview_flag = (BKE_icon_is_preview(preview_icon_id) ||
@@ -436,6 +458,11 @@ void PreviewGridItem::build_grid_tile(uiLayout &layout) const
but->emboss = UI_EMBOSS_NONE;
}
void PreviewGridItem::build_grid_tile(uiLayout &layout) const
{
this->build_grid_tile_button(layout);
}
void PreviewGridItem::set_on_activate_fn(ActivateFn fn)
{
activate_fn_ = fn;

View File

@@ -1279,6 +1279,24 @@ static StructRNA *rna_AssetShelf_register(Main *bmain,
return srna;
}
static void rna_AssetShelf_activate_operator_get(PointerRNA *ptr, char *value)
{
AssetShelf *shelf = static_cast<AssetShelf *>(ptr->data);
strcpy(value, shelf->type->activate_operator.c_str());
}
static int rna_AssetShelf_activate_operator_length(PointerRNA *ptr)
{
AssetShelf *shelf = static_cast<AssetShelf *>(ptr->data);
return shelf->type->activate_operator.size();
}
static void rna_AssetShelf_activate_operator_set(PointerRNA *ptr, const char *value)
{
AssetShelf *shelf = static_cast<AssetShelf *>(ptr->data);
shelf->type->activate_operator = value;
}
static StructRNA *rna_AssetShelf_refine(PointerRNA *shelf_ptr)
{
AssetShelf *shelf = (AssetShelf *)shelf_ptr->data;
@@ -2309,6 +2327,17 @@ static void rna_def_asset_shelf(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Options", "Options for this asset shelf type");
prop = RNA_def_property(srna, "bl_activate_operator", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop,
"rna_AssetShelf_activate_operator_get",
"rna_AssetShelf_activate_operator_length",
"rna_AssetShelf_activate_operator_set");
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
RNA_def_property_ui_text(
prop,
"Activate Operator",
"Operator to call when activating an item with asset reference properties");
prop = RNA_def_property(srna, "bl_default_preview_size", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, nullptr, "type->default_preview_size");
RNA_def_property_range(prop, 32, 256);