[Bf-blender-cvs] [4d9eb2c5895] custom-manipulators: RNA/Python API for defining py-manipulator callbacks

Campbell Barton noreply at git.blender.org
Thu Jun 22 10:00:12 CEST 2017


Commit: 4d9eb2c5895a3fef36fc976cacd1c64422c1d239
Author: Campbell Barton
Date:   Thu Jun 22 18:04:39 2017 +1000
Branches: custom-manipulators
https://developer.blender.org/rB4d9eb2c5895a3fef36fc976cacd1c64422c1d239

RNA/Python API for defining py-manipulator callbacks

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

M	release/scripts/modules/bpy_types.py
M	source/blender/makesrna/intern/rna_wm_manipulator_api.c
M	source/blender/python/intern/CMakeLists.txt
M	source/blender/python/intern/bpy.c
M	source/blender/python/intern/bpy_manipulator_wrap.c
A	source/blender/python/intern/bpy_rna_manipulator.c
A	source/blender/python/intern/bpy_rna_manipulator.h
M	source/blender/windowmanager/intern/wm_init_exit.c
M	source/blender/windowmanager/manipulators/WM_manipulator_types.h
M	source/blender/windowmanager/manipulators/intern/wm_manipulator.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_target_props.c
M	source/blender/windowmanager/manipulators/wm_manipulator_fn.h

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

diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 28dd6657b0d..89d8e0746a6 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -618,6 +618,8 @@ class Manipulator(StructRNA, metaclass=OrderedMeta):
             return delattr(properties, attr)
         return super().__delattr__(attr)
 
+    target_set_handler = _bpy._rna_manipulator_target_set_handler
+
 
 # Only defined so operators members can be used by accessing self.order
 # with doc generation 'self.properties.bl_rna.properties' can fail
diff --git a/source/blender/makesrna/intern/rna_wm_manipulator_api.c b/source/blender/makesrna/intern/rna_wm_manipulator_api.c
index c413eff76b7..ce842043cce 100644
--- a/source/blender/makesrna/intern/rna_wm_manipulator_api.c
+++ b/source/blender/makesrna/intern/rna_wm_manipulator_api.c
@@ -69,7 +69,7 @@ static void rna_manipulator_draw_preset_facemap(
 	ED_manipulator_draw_preset_facemap(mpr, scene, ob, facemap, select_id);
 }
 
-static void rna_manipulator_target_prop_set_property(
+static void rna_manipulator_target_set_prop(
         wmManipulator *mpr, ReportList *reports, const char *target_propname,
         PointerRNA *ptr, const char *propname, int index)
 {
@@ -193,10 +193,11 @@ void RNA_api_manipulator(StructRNA *srna)
 	/* -------------------------------------------------------------------- */
 	/* Property API */
 
-	func = RNA_def_function(srna, "target_prop_set_property", "rna_manipulator_target_prop_set_property");
+	/* note, 'target_set_handler' is defined in 'bpy_rna_manipulator.c' */
+	func = RNA_def_function(srna, "target_set_prop", "rna_manipulator_target_set_prop");
 	RNA_def_function_flag(func, FUNC_USE_REPORTS);
 	RNA_def_function_ui_description(func, "");
-	parm = RNA_def_string(func, "target_property", NULL, 0, "", "Target property");
+	parm = RNA_def_string(func, "target", NULL, 0, "", "Target property");
 	RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
 	/* similar to UILayout.prop */
 	parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property");
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index ddd1c53c671..967e90d22cb 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -76,6 +76,7 @@ set(SRC
 	bpy_rna_callback.c
 	bpy_rna_driver.c
 	bpy_rna_id_collection.c
+	bpy_rna_manipulator.c
 	bpy_traceback.c
 	bpy_util.c
 	bpy_utils_previews.c
@@ -108,6 +109,7 @@ set(SRC
 	bpy_rna_callback.h
 	bpy_rna_driver.h
 	bpy_rna_id_collection.h
+	bpy_rna_manipulator.h
 	bpy_traceback.h
 	bpy_util.h
 	bpy_utils_previews.h
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 5bbfb4912e6..4a29d4f8da1 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -46,6 +46,7 @@
 #include "bpy_rna.h"
 #include "bpy_app.h"
 #include "bpy_rna_id_collection.h"
+#include "bpy_rna_manipulator.h"
 #include "bpy_props.h"
 #include "bpy_library.h"
 #include "bpy_operator.h"
@@ -327,6 +328,8 @@ void BPy_init_modules(void)
 
 	BPY_rna_id_collection_module(mod);
 
+	BPY_rna_manipulator_module(mod);
+
 	bpy_import_test("bpy_types");
 	PyModule_AddObject(mod, "data", BPY_rna_module()); /* imports bpy_types by running this */
 	bpy_import_test("bpy_types");
diff --git a/source/blender/python/intern/bpy_manipulator_wrap.c b/source/blender/python/intern/bpy_manipulator_wrap.c
index f8dd5232dbb..53b6285e880 100644
--- a/source/blender/python/intern/bpy_manipulator_wrap.c
+++ b/source/blender/python/intern/bpy_manipulator_wrap.c
@@ -65,7 +65,7 @@ static bool bpy_manipulatortype_target_property_def(
 		char *id;
 		char *type_id; int type;
 		int array_length;
-	} args = {
+	} params = {
 		.id = NULL, /* not optional */
 		.type = PROP_FLOAT,
 		.type_id = NULL,
@@ -75,34 +75,34 @@ static bool bpy_manipulatortype_target_property_def(
 	if (!_PyArg_ParseTupleAndKeywordsFast(
 	        empty_tuple, item,
 	        &_parser,
-	        &args.id,
-	        &args.type_id,
-	        &args.array_length))
+	        &params.id,
+	        &params.type_id,
+	        &params.array_length))
 	{
 		goto fail;
 	}
 
-	if (args.id == NULL) {
+	if (params.id == NULL) {
 		PyErr_SetString(PyExc_ValueError, "'id' argument not given");
 		goto fail;
 	}
 
-	if ((args.type_id != NULL) &&
+	if ((params.type_id != NULL) &&
 	    pyrna_enum_value_from_id(
-	        rna_enum_property_type_items, args.type_id, &args.type, "'type' enum value") == -1)
+	        rna_enum_property_type_items, params.type_id, &params.type, "'type' enum value") == -1)
 	{
 		goto fail;
 	}
 	else {
-		args.type = rna_enum_property_type_items[args.type].value;
+		params.type = rna_enum_property_type_items[params.type].value;
 	}
 
-	if ((args.array_length < 1 || args.array_length > RNA_MAX_ARRAY_LENGTH)) {
+	if ((params.array_length < 1 || params.array_length > RNA_MAX_ARRAY_LENGTH)) {
 		PyErr_SetString(PyExc_ValueError, "'array_length' out of range");
 		goto fail;
 	}
 
-	WM_manipulatortype_target_property_def(wt, args.id, args.type, args.array_length);
+	WM_manipulatortype_target_property_def(wt, params.id, params.type, params.array_length);
 	Py_DECREF(empty_tuple);
 	return true;
 
diff --git a/source/blender/python/intern/bpy_rna_manipulator.c b/source/blender/python/intern/bpy_rna_manipulator.c
new file mode 100644
index 00000000000..2ea29f4ec41
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_manipulator.c
@@ -0,0 +1,266 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_rna_manipulator.c
+ *  \ingroup pythonintern
+ *
+ * .
+ */
+
+#include <Python.h>
+#include <stddef.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_main.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "bpy_util.h"
+#include "bpy_rna_manipulator.h"
+
+#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_types.h"
+#include "RNA_enum_types.h"
+
+#include "bpy_rna.h"
+
+enum {
+	BPY_MANIPULATOR_FN_SLOT_GET = 0,
+	BPY_MANIPULATOR_FN_SLOT_SET,
+	BPY_MANIPULATOR_FN_SLOT_RANGE,
+};
+#define BPY_MANIPULATOR_FN_SLOT_LEN (BPY_MANIPULATOR_FN_SLOT_RANGE + 1)
+
+struct BPyManipulatorHandlerUserData {
+
+	PyObject *fn_slots[BPY_MANIPULATOR_FN_SLOT_LEN];
+};
+
+static void py_rna_manipulator_handler_get_cb(
+        const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+        float *value)
+{
+	PyGILState_STATE gilstate = PyGILState_Ensure();
+
+	struct BPyManipulatorHandlerUserData *data = mpr_prop->custom_func.user_data;
+	PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_MANIPULATOR_FN_SLOT_GET], NULL);
+	if (ret == NULL) {
+		goto fail;
+	}
+
+	if (mpr_prop->type->type == PROP_FLOAT) {
+		if (mpr_prop->type->array_length == 1) {
+			if (((*value = PyFloat_AsDouble(ret)) == -1.0f && PyErr_Occurred()) == 0) {
+				goto fail;
+			}
+		}
+		else {
+			if (PyC_AsArray(value, ret, mpr_prop->type->array_length, &PyFloat_Type, false,
+			                "Manipulator get callback: ") == -1)
+			{
+				goto fail;
+			}
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_AttributeError, "internal error, unsupported type");
+		goto fail;
+	}
+
+	Py_DECREF(ret);
+
+	PyGILState_Release(gilstate);
+	return;
+
+fail:
+	PyErr_Print();
+	PyErr_Clear();
+
+	PyGILState_Release(gilstate);
+}
+
+static void py_rna_manipulator_handler_set_cb(
+        const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+        const float *value)
+{
+	PyGILState_STATE gilstate = PyGILState_Ensure();
+
+	struct BPyManipulatorHandlerUserData *data = mpr_prop->custom_func.user_data;
+
+	PyObject *args = PyTuple_New(1);
+
+	if (mpr_prop->type->type == PROP_FLOAT) {
+		PyObject *py_value;
+		if (mpr_prop->type->array_length == 1) {
+			py_value = PyFloat_FromDouble(*value);
+		}
+		else {
+			py_value =  PyC_FromArray((void *)value, mpr_prop->type->array_length, &PyFloat_Type, false,
+			                          "Manipulator set callback: ");
+		}
+		if (py_value == NULL) {
+			goto fail;
+		}
+		PyTuple_SET_ITEM(args, 0, py_value);
+	}
+	else {
+		PyErr_SetString(PyExc_AttributeError, "internal error, unsupported type");
+		goto fail;
+	}
+
+	PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_MANIPULATOR_FN_SLOT_SET], args);
+	if (ret == NULL) {
+		goto fail;
+	}
+	Py_DECREF(ret);
+
+	PyGILState_Release(gilstate);
+	return;
+
+fail:
+	PyErr_Print();
+	PyErr_Clear();
+
+	Py_DECREF(args);
+
+	PyGILState_Release(gilstate);
+}
+
+static void py_rna_manipulator_handler_free_cb(
+        const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop)
+{
+	struct BPyManipulatorHandlerUserData *data = mpr_prop->custom_func.user_data;
+
+	PyGILState_STATE gilstate = PyGILState_Ensure();
+	for (int i = 0; i < BPY_MANIPULATOR_FN_SLOT_LEN; i++) {
+		Py_XDECREF(data->fn_slots[i]);
+	}
+	PyGILState_Release(gilstate);
+
+	MEM_freeN(data);
+
+}
+
+PyDoc_STRVAR(bpy_manipulator_target_set_handler_doc,
+".. method:: target_set_handler():\n"
+"\n"
+"   TODO.\n"
+);
+static PyObject *bpy_manipulator_target_set_handler(PyObject *UNUSED(self), PyObject *args, PyObject *kwds)
+{
+	/* Note: this is a counter-part to RNA function:
+	 * 'Manipulator.target_set_prop' (see: rna_wm_manipulator_api.c). conventions should match. */
+	static const char * const _keyword

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list