UI: Drag & Drop to Properties Materials Panel
Support drag/drop of materials to Properties Material Slots. See D13549 for more details. Differential Revision: https://developer.blender.org/D13549 Reviewed by Julian Eisel
This commit is contained in:
parent
471f27d66b
commit
fd2519e0b6
Notes:
blender-bot
2023-02-14 10:37:49 +01:00
Referenced by issue #90579, As a user I want update a material slot by dropping a material on the material list in the properties panel.
|
@ -28,6 +28,7 @@ class MATERIAL_UL_matslots(UIList):
|
|||
ma = slot.material
|
||||
|
||||
layout.context_pointer_set("id", ma)
|
||||
layout.context_pointer_set("material_slot", slot)
|
||||
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
if ma:
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
@ -61,6 +65,60 @@ static void ui_drop_name_copy(wmDrag *drag, wmDropBox *drop)
|
|||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Material Drag/Drop Operators */
|
||||
|
||||
static bool ui_drop_material_poll(bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
|
||||
{
|
||||
PointerRNA mat_slot = CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
|
||||
return WM_drag_is_ID_type(drag, ID_MA) && !RNA_pointer_is_null(&mat_slot);
|
||||
}
|
||||
|
||||
static void ui_drop_material_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
const ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_MA);
|
||||
RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
|
||||
}
|
||||
|
||||
static char *ui_drop_material_tooltip(bContext *C,
|
||||
wmDrag *drag,
|
||||
const int UNUSED(xy[2]),
|
||||
struct wmDropBox *UNUSED(drop))
|
||||
{
|
||||
PointerRNA rna_ptr = CTX_data_pointer_get_type(C, "object", &RNA_Object);
|
||||
Object *ob = (Object *)rna_ptr.data;
|
||||
BLI_assert(ob);
|
||||
|
||||
PointerRNA mat_slot = CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
|
||||
BLI_assert(mat_slot.data);
|
||||
|
||||
const int target_slot = RNA_int_get(&mat_slot, "slot_index") + 1;
|
||||
|
||||
PointerRNA rna_prev_material = RNA_pointer_get(&mat_slot, "material");
|
||||
Material *prev_mat_in_slot = (Material *)rna_prev_material.data;
|
||||
const char *dragged_material_name = WM_drag_get_item_name(drag);
|
||||
|
||||
char *result;
|
||||
if (prev_mat_in_slot) {
|
||||
const char *tooltip = TIP_("Drop %s on slot %d (replacing %s) of %s");
|
||||
result = BLI_sprintfN(tooltip,
|
||||
dragged_material_name,
|
||||
target_slot,
|
||||
prev_mat_in_slot->id.name + 2,
|
||||
ob->id.name + 2);
|
||||
}
|
||||
else if (target_slot == ob->actcol) {
|
||||
const char *tooltip = TIP_("Drop %s on slot %d (active slot) of %s");
|
||||
result = BLI_sprintfN(tooltip, dragged_material_name, target_slot, ob->id.name + 2);
|
||||
}
|
||||
else {
|
||||
const char *tooltip = TIP_("Drop %s on slot %d of %s");
|
||||
result = BLI_sprintfN(tooltip, dragged_material_name, target_slot, ob->id.name + 2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void ED_dropboxes_ui()
|
||||
{
|
||||
|
@ -78,4 +136,10 @@ void ED_dropboxes_ui()
|
|||
ui_drop_name_copy,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
nullptr);
|
||||
WM_dropbox_add(lb,
|
||||
"UI_OT_drop_material",
|
||||
ui_drop_material_poll,
|
||||
ui_drop_material_copy,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
ui_drop_material_tooltip);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h" /* for handling geometry nodes properties */
|
||||
#include "DNA_object_types.h" /* for OB_DATA_SUPPORT_ID */
|
||||
#include "DNA_screen_types.h"
|
||||
|
@ -27,6 +28,7 @@
|
|||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_override.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
|
@ -2109,6 +2111,86 @@ static void UI_OT_tree_view_item_rename(wmOperatorType *ot)
|
|||
|
||||
ot->flag = OPTYPE_INTERNAL;
|
||||
}
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Material Drag/Drop Operator
|
||||
*
|
||||
* \{ */
|
||||
|
||||
static bool ui_drop_material_poll(bContext *C)
|
||||
{
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "object", &RNA_Object);
|
||||
Object *ob = ptr.data;
|
||||
if (ob == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PointerRNA mat_slot = CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
|
||||
if (RNA_pointer_is_null(&mat_slot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ui_drop_material_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
if (!RNA_struct_property_is_set(op->ptr, "session_uuid")) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
const uint32_t session_uuid = (uint32_t)RNA_int_get(op->ptr, "session_uuid");
|
||||
Material *ma = (Material *)BKE_libblock_find_session_uuid(bmain, ID_MA, session_uuid);
|
||||
if (ma == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "object", &RNA_Object);
|
||||
Object *ob = ptr.data;
|
||||
BLI_assert(ob);
|
||||
|
||||
PointerRNA mat_slot = CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot);
|
||||
BLI_assert(mat_slot.data);
|
||||
const int target_slot = RNA_int_get(&mat_slot, "slot_index") + 1;
|
||||
|
||||
/* only drop grease pencil material on grease pencil objects */
|
||||
if ((ma->gp_style != NULL) && (ob->type != OB_GPENCIL)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_object_material_assign(bmain, ob, ma, target_slot, BKE_MAT_ASSIGN_USERPREF);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_drop_material(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Drop Material in Material slots";
|
||||
ot->description = "Drag material to Material slots in Properties";
|
||||
ot->idname = "UI_OT_drop_material";
|
||||
|
||||
ot->poll = ui_drop_material_poll;
|
||||
ot->exec = ui_drop_material_exec;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
|
||||
PropertyRNA *prop = RNA_def_int(ot->srna,
|
||||
"session_uuid",
|
||||
0,
|
||||
INT32_MIN,
|
||||
INT32_MAX,
|
||||
"Session UUID",
|
||||
"Session UUID of the data-block to assign",
|
||||
INT32_MIN,
|
||||
INT32_MAX);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@ -2130,6 +2212,7 @@ void ED_operatortypes_ui(void)
|
|||
WM_operatortype_append(UI_OT_jump_to_target_button);
|
||||
WM_operatortype_append(UI_OT_drop_color);
|
||||
WM_operatortype_append(UI_OT_drop_name);
|
||||
WM_operatortype_append(UI_OT_drop_material);
|
||||
#ifdef WITH_PYTHON
|
||||
WM_operatortype_append(UI_OT_editsource);
|
||||
WM_operatortype_append(UI_OT_edittranslation_init);
|
||||
|
|
|
@ -2454,6 +2454,10 @@ static void rna_def_material_slot(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Material", "Material data-block used by this material slot");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_MaterialSlot_update");
|
||||
|
||||
prop = RNA_def_property(srna, "slot_index", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_int_funcs(prop, "rna_MaterialSlot_index", NULL, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(
|
||||
prop, "rna_MaterialSlot_name_get", "rna_MaterialSlot_name_length", NULL);
|
||||
|
|
Loading…
Reference in New Issue