diff options
author | Azeem Bande-Ali <azeemba> | 2022-03-04 02:28:48 +0300 |
---|---|---|
committer | Harley Acheson <harley.acheson@gmail.com> | 2022-03-04 02:28:48 +0300 |
commit | fd2519e0b6948903892c3cfc373c903337979407 (patch) | |
tree | 4150c341b86662fc66c9dd6edf44cd98dc155225 /source/blender | |
parent | 471f27d66bd71e80db82c41db2a6fd58f854b46a (diff) |
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
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/interface/interface_dropboxes.cc | 64 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_ops.c | 83 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 4 |
3 files changed, 151 insertions, 0 deletions
diff --git a/source/blender/editors/interface/interface_dropboxes.cc b/source/blender/editors/interface/interface_dropboxes.cc index a24554ef68d..40d1a0ca6f5 100644 --- a/source/blender/editors/interface/interface_dropboxes.cc +++ b/source/blender/editors/interface/interface_dropboxes.cc @@ -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); } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 498c22748ce..0722584c7d8 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -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); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index c598e63a32a..7164f24c2f7 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -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); |