[Bf-blender-cvs] [fd2519e0b69] master: UI: Drag & Drop to Properties Materials Panel

Azeem Bande-Ali noreply at git.blender.org
Fri Mar 4 00:30:13 CET 2022


Commit: fd2519e0b6948903892c3cfc373c903337979407
Author: Azeem Bande-Ali
Date:   Thu Mar 3 15:28:48 2022 -0800
Branches: master
https://developer.blender.org/rBfd2519e0b6948903892c3cfc373c903337979407

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

===================================================================

M	release/scripts/startup/bl_ui/properties_material.py
M	source/blender/editors/interface/interface_dropboxes.cc
M	source/blender/editors/interface/interface_ops.c
M	source/blender/makesrna/intern/rna_object.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 8c70987b3cf..9532d1d4ab0 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -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:
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);



More information about the Bf-blender-cvs mailing list