Brush Assets: Support adding shortcut to asset shelf items #117861
@ -6802,21 +6802,6 @@ def km_node_link_modal_map(_params):
|
||||
return keymap
|
||||
|
||||
|
||||
def km_asset_shelf_brushes(_params):
|
||||
items = []
|
||||
keymap = (
|
||||
"Asset Shelf",
|
||||
{"space_type": 'EMPTY', "region_type": 'WINDOW'},
|
||||
{"items": items},
|
||||
)
|
||||
|
||||
items.extend([
|
||||
("brush.asset_select", {"type": 'LEFTMOUSE', "value": 'CLICK'}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
||||
|
||||
# Fallback for gizmos that don't have custom a custom key-map.
|
||||
def km_generic_gizmo(_params):
|
||||
keymap = (
|
||||
@ -8652,9 +8637,6 @@ def generate_keymaps(params=None):
|
||||
km_curve_pen_modal_map(params),
|
||||
km_node_link_modal_map(params),
|
||||
|
||||
# Asset Shelf Keymaps.
|
||||
km_asset_shelf_brushes(params),
|
||||
|
||||
# Gizmos.
|
||||
km_generic_gizmo(params),
|
||||
km_generic_gizmo_drag(params),
|
||||
|
@ -8785,6 +8785,7 @@ class VIEW3D_PT_viewport_debug(Panel):
|
||||
class BrushAssetShelf:
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_options = {'NO_ASSET_DRAG'}
|
||||
bl_activate_operator = "BRUSH_OT_asset_select"
|
||||
bl_default_preview_size = 40
|
||||
|
||||
@classmethod
|
||||
|
@ -523,6 +523,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;
|
||||
|
@ -23,6 +23,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"
|
||||
@ -206,16 +207,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;
|
||||
HooglyBoogly marked this conversation as resolved
Outdated
|
||||
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
|
||||
|
@ -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,
|
||||
HooglyBoogly marked this conversation as resolved
Julian Eisel
commented
Would add default arguments for convenience, but also to simply communicate that these are optional. Would add default arguments for convenience, but also to simply communicate that these are optional.
|
||||
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
|
||||
|
@ -2335,6 +2335,7 @@ static void ui_apply_but(
|
||||
switch (but_type) {
|
||||
case UI_BTYPE_BUT:
|
||||
case UI_BTYPE_DECORATOR:
|
||||
case UI_BTYPE_PREVIEW_TILE:
|
||||
ui_apply_but_BUT(C, but, data);
|
||||
break;
|
||||
case UI_BTYPE_TEXT:
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
#include "interface_intern.hh"
|
||||
|
||||
@ -409,25 +411,44 @@ 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,
|
||||
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,
|
||||
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) ||
|
||||
@ -442,6 +463,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;
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "ED_asset_handle.hh"
|
||||
#include "ED_asset_list.hh"
|
||||
#include "ED_asset_mark_clear.hh"
|
||||
#include "ED_asset_menu_utils.hh"
|
||||
#include "ED_image.hh"
|
||||
#include "ED_paint.hh"
|
||||
#include "ED_screen.hh"
|
||||
@ -987,21 +988,18 @@ static void PAINT_OT_brush_select(wmOperatorType *ot)
|
||||
|
||||
/**************************** Brush Assets **********************************/
|
||||
|
||||
static bool brush_asset_select_poll(bContext *C)
|
||||
{
|
||||
if (BKE_paint_get_active_from_context(C) == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CTX_wm_asset(C) != nullptr;
|
||||
}
|
||||
|
||||
static int brush_asset_select_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::ed;
|
||||
/* This operator currently covers both cases: the file/asset browser file list and the asset list
|
||||
* used for the asset-view template. Once the asset list design is used by the Asset Browser,
|
||||
* this can be simplified to just that case. */
|
||||
blender::asset_system::AssetRepresentation *asset = CTX_wm_asset(C);
|
||||
const asset_system::AssetRepresentation *asset =
|
||||
asset::operator_asset_reference_props_get_asset_from_all_library(*C, *op->ptr, op->reports);
|
||||
if (!asset) {
|
||||
return OPERATOR_CANCELLED;
|
||||
Julian Eisel
commented
Best do some report so this doesn't just fail silently. Best do some report so this doesn't just fail silently.
Hans Goudey
commented
`operator_asset_reference_props_get_asset_from_all_library` handles the reports already
|
||||
}
|
||||
|
||||
AssetWeakReference *brush_asset_reference = asset->make_weak_reference();
|
||||
Brush *brush = BKE_brush_asset_runtime_ensure(CTX_data_main(C), brush_asset_reference);
|
||||
@ -1023,12 +1021,14 @@ static int brush_asset_select_exec(bContext *C, wmOperator *op)
|
||||
|
||||
static void BRUSH_OT_asset_select(wmOperatorType *ot)
|
||||
{
|
||||
using namespace blender::ed;
|
||||
ot->name = "Select Brush Asset";
|
||||
ot->description = "Select a brush asset as current sculpt and paint tool";
|
||||
ot->idname = "BRUSH_OT_asset_select";
|
||||
|
||||
ot->exec = brush_asset_select_exec;
|
||||
ot->poll = brush_asset_select_poll;
|
||||
|
||||
asset::operator_asset_reference_props_register(*ot->srna);
|
||||
}
|
||||
|
||||
/* FIXME Quick dirty hack to generate a weak ref from 'raw' paths.
|
||||
|
@ -1303,6 +1303,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;
|
||||
@ -2321,6 +2339,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);
|
||||
|
@ -204,11 +204,9 @@ wmKeyMap *WM_keymap_guess_from_context(const bContext *C)
|
||||
wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
|
||||
{
|
||||
/* Op types purposely skipped for now:
|
||||
* BRUSH_OT
|
||||
* BOID_OT
|
||||
* BUTTONS_OT
|
||||
* CONSTRAINT_OT
|
||||
* PAINT_OT
|
||||
* ED_OT
|
||||
* FLUID_OT
|
||||
* TEXTURE_OT
|
||||
@ -331,7 +329,7 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
|
||||
km = WM_keymap_find_all(
|
||||
wm, "Paint Face Mask (Weight, Vertex, Texture)", SPACE_EMPTY, RGN_TYPE_WINDOW);
|
||||
}
|
||||
else if (STRPREFIX(opname, "PAINT_OT")) {
|
||||
else if (STRPREFIX(opname, "PAINT_OT") || STRPREFIX(opname, "BRUSH_OT")) {
|
||||
/* check for relevant mode */
|
||||
switch (CTX_data_mode_enum(C)) {
|
||||
case CTX_MODE_PAINT_WEIGHT:
|
||||
@ -346,6 +344,9 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
|
||||
case CTX_MODE_SCULPT:
|
||||
km = WM_keymap_find_all(wm, "Sculpt", SPACE_EMPTY, RGN_TYPE_WINDOW);
|
||||
break;
|
||||
case CTX_MODE_SCULPT_CURVES:
|
||||
km = WM_keymap_find_all(wm, "Sculpt Curves", SPACE_EMPTY, RGN_TYPE_WINDOW);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user
This function does not check if
ot
is null (butWM_operator_properties_create
does check).