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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to