[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))
+ ¶ms.id,
+ ¶ms.type_id,
+ ¶ms.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, ¶ms.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