Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2021-01-05 02:57:24 +0300
committerJulian Eisel <julian@blender.org>2021-01-06 13:55:21 +0300
commit4e23f08807bb0ccd361932f335768f645572d6bf (patch)
tree13d65c9205bd795aa05bc84e8dfe96da4cc02cbe /source/blender/editors/object
parent290b6d7ef327d963084792b65f7d8c79810b5e1f (diff)
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.
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/object_add.c116
1 files changed, 102 insertions, 14 deletions
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
@@ -189,6 +189,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);
}
/** \} */