[Bf-blender-cvs] [4e23f08807b] master: Fix object moved to cursor when editing last operation after dropping object

Julian Eisel noreply at git.blender.org
Wed Jan 6 11:56:28 CET 2021


Commit: 4e23f08807bb0ccd361932f335768f645572d6bf
Author: Julian Eisel
Date:   Tue Jan 5 00:57:24 2021 +0100
Branches: master
https://developer.blender.org/rB4e23f08807bb0ccd361932f335768f645572d6bf

Fix object moved to cursor when editing last operation after dropping object

Steps to reproduce were:
* Drag object icon from the Outliner into the 3D view (or an object asset from
  the Asset Browser)
* Open the "Adjust Last Operation" panel
* Edit options in there - the object would move to the mouse location

The same issue happens with collection instance and object data adding (e.g.
via drag & drop). This patch addresses them too.

The operator used the event state stored in the window. This shouldn't be
accessed from the operator execute callback generally which happened here.
Especially not if the operator supports editing properties.

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

M	source/blender/editors/object/object_add.c
M	source/blender/editors/space_view3d/space_view3d.c

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

diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 03ff8808423..a01f19f4706 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -188,6 +188,80 @@ static const EnumPropertyItem align_options[] = {
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Local Helpers
+ * \{ */
+
+/**
+ * Operator properties for creating an object under a screen space (2D) coordinate.
+ * Used for object dropping like behavior (drag object and drop into 3D View).
+ */
+static void object_add_drop_xy_props(wmOperatorType *ot)
+{
+  PropertyRNA *prop;
+
+  prop = RNA_def_int(ot->srna,
+                     "drop_x",
+                     0,
+                     INT_MIN,
+                     INT_MAX,
+                     "Drop X",
+                     "X-coordinate (screen space) to place the new object under",
+                     INT_MIN,
+                     INT_MAX);
+  RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+  prop = RNA_def_int(ot->srna,
+                     "drop_y",
+                     0,
+                     INT_MIN,
+                     INT_MAX,
+                     "Drop Y",
+                     "Y-coordinate (screen space) to place the new object under",
+                     INT_MIN,
+                     INT_MAX);
+  RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+}
+
+static bool object_add_drop_xy_is_set(const wmOperator *op)
+{
+  return RNA_struct_property_is_set(op->ptr, "drop_x") &&
+         RNA_struct_property_is_set(op->ptr, "drop_y");
+}
+
+/**
+ * Query the currently set X- and Y-coordinate to position the new object under.
+ * \param r_mval: Returned pointer to the coordinate in region-space.
+ */
+static bool object_add_drop_xy_get(bContext *C, wmOperator *op, int (*r_mval)[2])
+{
+  if (!object_add_drop_xy_is_set(op)) {
+    (*r_mval)[0] = 0.0f;
+    (*r_mval)[1] = 0.0f;
+    return false;
+  }
+
+  const ARegion *region = CTX_wm_region(C);
+  (*r_mval)[0] = RNA_int_get(op->ptr, "drop_x") - region->winrct.xmin;
+  (*r_mval)[1] = RNA_int_get(op->ptr, "drop_y") - region->winrct.ymin;
+
+  return true;
+}
+
+/**
+ * Set the drop coordinate to the mouse position (if not already set) and call the operator's
+ * `exec()` callback.
+ */
+static int object_add_drop_xy_generic_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  if (!object_add_drop_xy_is_set(op)) {
+    RNA_int_set(op->ptr, "drop_x", event->x);
+    RNA_int_set(op->ptr, "drop_y", event->y);
+  }
+  return op->type->exec(C, op);
+}
+
+/** \} */
+
 /* -------------------------------------------------------------------- */
 /** \name Public Add Object API
  *
@@ -1447,10 +1521,8 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
     RNA_property_string_get(op->ptr, prop_name, name);
     collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
 
-    if (!RNA_property_is_set(op->ptr, prop_location)) {
-      const wmEvent *event = CTX_wm_window(C)->eventstate;
-      ARegion *region = CTX_wm_region(C);
-      const int mval[2] = {event->x - region->winrct.xmin, event->y - region->winrct.ymin};
+    int mval[2];
+    if (!RNA_property_is_set(op->ptr, prop_location) && object_add_drop_xy_get(C, op, &mval)) {
       ED_object_location_from_view(C, loc);
       ED_view3d_cursor3d_position(C, mval, false, loc);
       RNA_property_float_set_array(op->ptr, prop_location, loc);
@@ -1493,6 +1565,19 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
   return OPERATOR_FINISHED;
 }
 
+static int object_instance_add_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  if (!object_add_drop_xy_is_set(op)) {
+    RNA_int_set(op->ptr, "drop_x", event->x);
+    RNA_int_set(op->ptr, "drop_y", event->y);
+  }
+
+  if (!RNA_struct_property_is_set(op->ptr, "name")) {
+    return WM_enum_search_invoke(C, op, event);
+  }
+  return op->type->exec(C, op);
+}
+
 /* only used as menu */
 void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
 {
@@ -1504,7 +1589,7 @@ void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
   ot->idname = "OBJECT_OT_collection_instance_add";
 
   /* api callbacks */
-  ot->invoke = WM_enum_search_invoke;
+  ot->invoke = object_instance_add_invoke;
   ot->exec = collection_instance_add_exec;
   ot->poll = ED_operator_objectmode;
 
@@ -1519,6 +1604,8 @@ void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
   RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
   ot->prop = prop;
   ED_object_add_generic_props(ot, false);
+
+  object_add_drop_xy_props(ot);
 }
 
 /** \} */
@@ -1556,10 +1643,8 @@ static int object_data_instance_add_exec(bContext *C, wmOperator *op)
     return OPERATOR_CANCELLED;
   }
 
-  if (!RNA_property_is_set(op->ptr, prop_location)) {
-    const wmEvent *event = CTX_wm_window(C)->eventstate;
-    ARegion *region = CTX_wm_region(C);
-    const int mval[2] = {event->x - region->winrct.xmin, event->y - region->winrct.ymin};
+  int mval[2];
+  if (!RNA_property_is_set(op->ptr, prop_location) && object_add_drop_xy_get(C, op, &mval)) {
     ED_object_location_from_view(C, loc);
     ED_view3d_cursor3d_position(C, mval, false, loc);
     RNA_property_float_set_array(op->ptr, prop_location, loc);
@@ -1591,6 +1676,7 @@ void OBJECT_OT_data_instance_add(wmOperatorType *ot)
   ot->idname = "OBJECT_OT_data_instance_add";
 
   /* api callbacks */
+  ot->invoke = object_add_drop_xy_generic_invoke;
   ot->exec = object_data_instance_add_exec;
   ot->poll = ED_operator_objectmode;
 
@@ -1602,6 +1688,8 @@ void OBJECT_OT_data_instance_add(wmOperatorType *ot)
   PropertyRNA *prop = RNA_def_enum(ot->srna, "type", rna_enum_id_type_items, 0, "Type", "");
   RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
   ED_object_add_generic_props(ot, false);
+
+  object_add_drop_xy_props(ot);
 }
 
 /** \} */
@@ -3228,8 +3316,6 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
 
 static int object_add_named_exec(bContext *C, wmOperator *op)
 {
-  wmWindow *win = CTX_wm_window(C);
-  const wmEvent *event = win ? win->eventstate : NULL;
   Main *bmain = CTX_data_main(C);
   Scene *scene = CTX_data_scene(C);
   ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -3258,9 +3344,8 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
 
   basen->object->restrictflag &= ~OB_RESTRICT_VIEWPORT;
 
-  if (event) {
-    ARegion *region = CTX_wm_region(C);
-    const int mval[2] = {event->x - region->winrct.xmin, event->y - region->winrct.ymin};
+  int mval[2];
+  if (object_add_drop_xy_get(C, op, &mval)) {
     ED_object_location_from_view(C, basen->object->loc);
     ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
   }
@@ -3290,6 +3375,7 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
   ot->idname = "OBJECT_OT_add_named";
 
   /* api callbacks */
+  ot->invoke = object_add_drop_xy_generic_invoke;
   ot->exec = object_add_named_exec;
   ot->poll = ED_operator_objectmode;
 
@@ -3302,6 +3388,8 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
                   "Linked",
                   "Duplicate object but not object data, linking to the original data");
   RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Object name to add");
+
+  object_add_drop_xy_props(ot);
 }
 
 /** \} */
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 82a20451d26..34d342ddd94 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -616,7 +616,6 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
   ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_GR);
 
-  drop->opcontext = WM_OP_EXEC_DEFAULT;
   RNA_string_set(drop->ptr, "name", id->name + 2);
 }



More information about the Bf-blender-cvs mailing list