| 
									
										
										
										
											2022-02-11 09:07:11 +11:00
										 |  |  | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup pythonintern | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |  * This file defines utility methods for `bpy.types.Gizmo`. | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Python.h>
 | 
					
						
							|  |  |  | #include <stddef.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | #include "BLI_alloca.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 21:30:03 +11:00
										 |  |  | #include "bpy_capi_utils.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:16:34 +02:00
										 |  |  | #include "bpy_rna_gizmo.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "../generic/py_capi_utils.h"
 | 
					
						
							|  |  |  | #include "../generic/python_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | #include "RNA_enum_types.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:54:46 +01:00
										 |  |  | #include "RNA_prototypes.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "RNA_types.h"
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "bpy_rna.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Parsing Utility Functions
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Functions used as callbacks for #PyArg_ParseTuple `O&` format string. | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct BPyGizmoWithTarget { | 
					
						
							|  |  |  |   wmGizmo *gz; /* Must be first. */ | 
					
						
							|  |  |  |   wmGizmoProperty *gz_prop; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct BPyGizmoWithTargetType { | 
					
						
							|  |  |  |   wmGizmo *gz; /* Must be first. */ | 
					
						
							|  |  |  |   const wmGizmoPropertyType *gz_prop_type; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int py_rna_gizmo_parse(PyObject *o, void *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* No type checking (this is `self` not a user defined argument). */ | 
					
						
							|  |  |  |   BLI_assert(BPy_StructRNA_Check(o)); | 
					
						
							| 
									
										
										
										
											2021-11-05 15:49:04 +11:00
										 |  |  |   BLI_assert(RNA_struct_is_a(((const BPy_StructRNA *)o)->ptr.type, &RNA_Gizmo)); | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  |   wmGizmo **gz_p = p; | 
					
						
							|  |  |  |   *gz_p = ((const BPy_StructRNA *)o)->ptr.data; | 
					
						
							|  |  |  |   return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int py_rna_gizmo_target_id_parse(PyObject *o, void *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct BPyGizmoWithTarget *gizmo_with_target = p; | 
					
						
							|  |  |  |   /* Must be set by `py_rna_gizmo_parse`. */ | 
					
						
							|  |  |  |   wmGizmo *gz = gizmo_with_target->gz; | 
					
						
							|  |  |  |   BLI_assert(gz != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyUnicode_Check(o)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "expected a string (got %.200s)", Py_TYPE(o)->tp_name); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const char *gz_prop_id = PyUnicode_AsUTF8(o); | 
					
						
							|  |  |  |   wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, gz_prop_id); | 
					
						
							|  |  |  |   if (gz_prop == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "Gizmo target property '%s.%s' not found!", | 
					
						
							|  |  |  |                  gz->type->idname, | 
					
						
							|  |  |  |                  gz_prop_id); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   gizmo_with_target->gz_prop = gz_prop; | 
					
						
							|  |  |  |   return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 20:06:09 +11:00
										 |  |  | static int py_rna_gizmo_target_id_parse_and_ensure_is_valid(PyObject *o, void *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (py_rna_gizmo_target_id_parse(o, p) == 0) { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   struct BPyGizmoWithTarget *gizmo_with_target = p; | 
					
						
							|  |  |  |   wmGizmo *gz = gizmo_with_target->gz; | 
					
						
							|  |  |  |   wmGizmoProperty *gz_prop = gizmo_with_target->gz_prop; | 
					
						
							|  |  |  |   if (!WM_gizmo_target_property_is_valid(gz_prop)) { | 
					
						
							|  |  |  |     const char *gz_prop_id = PyUnicode_AsUTF8(o); | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "Gizmo target property '%s.%s' has not been initialized, " | 
					
						
							|  |  |  |                  "Call \"target_set_prop\" first!", | 
					
						
							|  |  |  |                  gz->type->idname, | 
					
						
							|  |  |  |                  gz_prop_id); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  | static int py_rna_gizmo_target_type_id_parse(PyObject *o, void *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct BPyGizmoWithTargetType *gizmo_with_target = p; | 
					
						
							|  |  |  |   /* Must be set first. */ | 
					
						
							|  |  |  |   wmGizmo *gz = gizmo_with_target->gz; | 
					
						
							|  |  |  |   BLI_assert(gz != NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyUnicode_Check(o)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "expected a string (got %.200s)", Py_TYPE(o)->tp_name); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const char *gz_prop_id = PyUnicode_AsUTF8(o); | 
					
						
							|  |  |  |   const wmGizmoPropertyType *gz_prop_type = WM_gizmotype_target_property_find(gz->type, | 
					
						
							|  |  |  |                                                                               gz_prop_id); | 
					
						
							|  |  |  |   if (gz_prop_type == NULL) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  |                  "Gizmo target property '%s.%s' not found!", | 
					
						
							|  |  |  |                  gz->type->idname, | 
					
						
							|  |  |  |                  gz_prop_id); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   gizmo_with_target->gz_prop_type = gz_prop_type; | 
					
						
							|  |  |  |   return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | /** \name Gizmo Target Property Define API
 | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | enum { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BPY_GIZMO_FN_SLOT_GET = 0, | 
					
						
							|  |  |  |   BPY_GIZMO_FN_SLOT_SET, | 
					
						
							|  |  |  |   BPY_GIZMO_FN_SLOT_RANGE_GET, | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | #define BPY_GIZMO_FN_SLOT_LEN (BPY_GIZMO_FN_SLOT_RANGE_GET + 1)
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | struct BPyGizmoHandlerUserData { | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyObject *fn_slots[BPY_GIZMO_FN_SLOT_LEN]; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void py_rna_gizmo_handler_get_cb(const wmGizmo *UNUSED(gz), | 
					
						
							|  |  |  |                                         wmGizmoProperty *gz_prop, | 
					
						
							|  |  |  |                                         void *value_p) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; | 
					
						
							|  |  |  |   PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_GIZMO_FN_SLOT_GET], NULL); | 
					
						
							|  |  |  |   if (ret == NULL) { | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gz_prop->type->data_type == PROP_FLOAT) { | 
					
						
							|  |  |  |     float *value = value_p; | 
					
						
							|  |  |  |     if (gz_prop->type->array_length == 1) { | 
					
						
							|  |  |  |       if ((*value = PyFloat_AsDouble(ret)) == -1.0f && PyErr_Occurred()) { | 
					
						
							|  |  |  |         goto fail; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       if (PyC_AsArray(value, | 
					
						
							| 
									
										
										
										
											2021-07-27 22:26:33 +10:00
										 |  |  |                       sizeof(*value), | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                       ret, | 
					
						
							|  |  |  |                       gz_prop->type->array_length, | 
					
						
							|  |  |  |                       &PyFloat_Type, | 
					
						
							|  |  |  |                       "Gizmo get callback: ") == -1) { | 
					
						
							|  |  |  |         goto fail; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "internal error, unsupported type"); | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyErr_Print(); | 
					
						
							|  |  |  |   PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-14 10:16:02 +11:00
										 |  |  |   Py_XDECREF(ret); | 
					
						
							| 
									
										
										
										
											2021-07-29 14:31:03 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void py_rna_gizmo_handler_set_cb(const wmGizmo *UNUSED(gz), | 
					
						
							|  |  |  |                                         wmGizmoProperty *gz_prop, | 
					
						
							|  |  |  |                                         const void *value_p) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyObject *args = PyTuple_New(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gz_prop->type->data_type == PROP_FLOAT) { | 
					
						
							|  |  |  |     const float *value = value_p; | 
					
						
							|  |  |  |     PyObject *py_value; | 
					
						
							|  |  |  |     if (gz_prop->type->array_length == 1) { | 
					
						
							|  |  |  |       py_value = PyFloat_FromDouble(*value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       py_value = PyC_Tuple_PackArray_F32(value, gz_prop->type->array_length); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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_GIZMO_FN_SLOT_SET], args); | 
					
						
							|  |  |  |   if (ret == NULL) { | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-07-29 14:31:03 +10:00
										 |  |  |   Py_DECREF(args); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_DECREF(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyErr_Print(); | 
					
						
							|  |  |  |   PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   Py_DECREF(args); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void py_rna_gizmo_handler_range_get_cb(const wmGizmo *UNUSED(gz), | 
					
						
							|  |  |  |                                               wmGizmoProperty *gz_prop, | 
					
						
							|  |  |  |                                               void *value_p) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PyObject *ret = PyObject_CallObject(data->fn_slots[BPY_GIZMO_FN_SLOT_RANGE_GET], NULL); | 
					
						
							|  |  |  |   if (ret == NULL) { | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PyTuple_Check(ret)) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "Expected a tuple, not %.200s", Py_TYPE(ret)->tp_name); | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PyTuple_GET_SIZE(ret) != 2) { | 
					
						
							|  |  |  |     PyErr_Format(PyExc_TypeError, "Expected a tuple of size 2, not %d", PyTuple_GET_SIZE(ret)); | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gz_prop->type->data_type == PROP_FLOAT) { | 
					
						
							|  |  |  |     float range[2]; | 
					
						
							|  |  |  |     for (int i = 0; i < 2; i++) { | 
					
						
							|  |  |  |       if (((range[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(ret, i))) == -1.0f && PyErr_Occurred()) == | 
					
						
							|  |  |  |           0) { | 
					
						
							|  |  |  |         /* pass */ | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         goto fail; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     memcpy(value_p, range, sizeof(range)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     PyErr_SetString(PyExc_AttributeError, "internal error, unsupported type"); | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_DECREF(ret); | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyErr_Print(); | 
					
						
							|  |  |  |   PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-29 14:31:03 +10:00
										 |  |  |   Py_XDECREF(ret); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | static void py_rna_gizmo_handler_free_cb(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct BPyGizmoHandlerUserData *data = gz_prop->custom_func.user_data; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   for (int i = 0; i < BPY_GIZMO_FN_SLOT_LEN; i++) { | 
					
						
							|  |  |  |     Py_XDECREF(data->fn_slots[i]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   MEM_freeN(data); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | PyDoc_STRVAR( | 
					
						
							|  |  |  |     bpy_gizmo_target_set_handler_doc, | 
					
						
							|  |  |  |     ".. method:: target_set_handler(target, get, set, range=None):\n" | 
					
						
							|  |  |  |     "\n" | 
					
						
							|  |  |  |     "   Assigns callbacks to a gizmos property.\n" | 
					
						
							|  |  |  |     "\n" | 
					
						
							|  |  |  |     "   :arg get: Function that returns the value for this property (single value or sequence).\n" | 
					
						
							|  |  |  |     "   :type get: callable\n" | 
					
						
							|  |  |  |     "   :arg set: Function that takes a single value argument and applies it.\n" | 
					
						
							|  |  |  |     "   :type set: callable\n" | 
					
						
							|  |  |  |     "   :arg range: Function that returns a (min, max) tuple for gizmos that use a range.\n" | 
					
						
							|  |  |  |     "   :type range: callable\n"); | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | static PyObject *bpy_gizmo_target_set_handler(PyObject *UNUSED(self), PyObject *args, PyObject *kw) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |   const PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   struct { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |     struct BPyGizmoWithTargetType gz_with_target_type; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *py_fn_slots[BPY_GIZMO_FN_SLOT_LEN]; | 
					
						
							|  |  |  |   } params = { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |       .gz_with_target_type = {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       .py_fn_slots = {NULL}, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |   /* NOTE: this is a counter-part to functions:
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    * 'Gizmo.target_set_prop & target_set_operator' | 
					
						
							|  |  |  |    * (see: rna_wm_gizmo_api.c). conventions should match. */ | 
					
						
							|  |  |  |   static const char *const _keywords[] = {"self", "target", "get", "set", "range", NULL}; | 
					
						
							| 
									
										
										
										
											2022-04-08 09:41:28 +10:00
										 |  |  |   static _PyArg_Parser _parser = { | 
					
						
							|  |  |  |       "O&" /* `self` */ | 
					
						
							|  |  |  |       "O&" /* `target` */ | 
					
						
							|  |  |  |       "|$" /* Optional keyword only arguments. */ | 
					
						
							|  |  |  |       "O"  /* `get` */ | 
					
						
							|  |  |  |       "O"  /* `set` */ | 
					
						
							|  |  |  |       "O"  /* `range` */ | 
					
						
							|  |  |  |       ":target_set_handler", | 
					
						
							|  |  |  |       _keywords, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (!_PyArg_ParseTupleAndKeywordsFast(args, | 
					
						
							|  |  |  |                                         kw, | 
					
						
							|  |  |  |                                         &_parser, | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |                                         /* `self` */ | 
					
						
							|  |  |  |                                         py_rna_gizmo_parse, | 
					
						
							|  |  |  |                                         ¶ms.gz_with_target_type.gz, | 
					
						
							|  |  |  |                                         /* `target` */ | 
					
						
							|  |  |  |                                         py_rna_gizmo_target_type_id_parse, | 
					
						
							|  |  |  |                                         ¶ms.gz_with_target_type, | 
					
						
							|  |  |  |                                         /* `get/set/range` */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                                         ¶ms.py_fn_slots[BPY_GIZMO_FN_SLOT_GET], | 
					
						
							|  |  |  |                                         ¶ms.py_fn_slots[BPY_GIZMO_FN_SLOT_SET], | 
					
						
							|  |  |  |                                         ¶ms.py_fn_slots[BPY_GIZMO_FN_SLOT_RANGE_GET])) { | 
					
						
							|  |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   wmGizmo *gz = params.gz_with_target_type.gz; | 
					
						
							|  |  |  |   const wmGizmoPropertyType *gz_prop_type = params.gz_with_target_type.gz_prop_type; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const int slots_required = 2; | 
					
						
							|  |  |  |     const int slots_start = 2; | 
					
						
							|  |  |  |     for (int i = 0; i < BPY_GIZMO_FN_SLOT_LEN; i++) { | 
					
						
							|  |  |  |       if (params.py_fn_slots[i] == NULL) { | 
					
						
							|  |  |  |         if (i < slots_required) { | 
					
						
							|  |  |  |           PyErr_Format(PyExc_ValueError, "Argument '%s' not given", _keywords[slots_start + i]); | 
					
						
							|  |  |  |           goto fail; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (!PyCallable_Check(params.py_fn_slots[i])) { | 
					
						
							|  |  |  |         PyErr_Format(PyExc_ValueError, "Argument '%s' not callable", _keywords[slots_start + i]); | 
					
						
							|  |  |  |         goto fail; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct BPyGizmoHandlerUserData *data = MEM_callocN(sizeof(*data), __func__); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int i = 0; i < BPY_GIZMO_FN_SLOT_LEN; i++) { | 
					
						
							|  |  |  |     data->fn_slots[i] = params.py_fn_slots[i]; | 
					
						
							|  |  |  |     Py_XINCREF(params.py_fn_slots[i]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   WM_gizmo_target_property_def_func_ptr(gz, | 
					
						
							|  |  |  |                                         gz_prop_type, | 
					
						
							|  |  |  |                                         &(const struct wmGizmoPropertyFnParams){ | 
					
						
							|  |  |  |                                             .value_get_fn = py_rna_gizmo_handler_get_cb, | 
					
						
							|  |  |  |                                             .value_set_fn = py_rna_gizmo_handler_set_cb, | 
					
						
							|  |  |  |                                             .range_get_fn = py_rna_gizmo_handler_range_get_cb, | 
					
						
							|  |  |  |                                             .free_fn = py_rna_gizmo_handler_free_cb, | 
					
						
							|  |  |  |                                             .user_data = data, | 
					
						
							|  |  |  |                                         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   PyGILState_Release(gilstate); | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | /** \name Gizmo Target Property Access API
 | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | PyDoc_STRVAR(bpy_gizmo_target_get_value_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: target_get_value(target):\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Get the value of this target property.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg target: Target property name.\n" | 
					
						
							|  |  |  |              "   :type target: string\n" | 
					
						
							|  |  |  |              "   :return: The value of the target property.\n" | 
					
						
							|  |  |  |              "   :rtype: Single value or array based on the target type\n"); | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | static PyObject *bpy_gizmo_target_get_value(PyObject *UNUSED(self), PyObject *args, PyObject *kw) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |     struct BPyGizmoWithTarget gz_with_target; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } params = { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |       .gz_with_target = {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static const char *const _keywords[] = {"self", "target", NULL}; | 
					
						
							| 
									
										
										
										
											2022-04-08 09:41:28 +10:00
										 |  |  |   static _PyArg_Parser _parser = { | 
					
						
							|  |  |  |       "O&" /* `self` */ | 
					
						
							|  |  |  |       "O&" /* `target` */ | 
					
						
							|  |  |  |       ":target_get_value", | 
					
						
							|  |  |  |       _keywords, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   if (!_PyArg_ParseTupleAndKeywordsFast(args, | 
					
						
							|  |  |  |                                         kw, | 
					
						
							|  |  |  |                                         &_parser, | 
					
						
							|  |  |  |                                         /* `self` */ | 
					
						
							|  |  |  |                                         py_rna_gizmo_parse, | 
					
						
							|  |  |  |                                         ¶ms.gz_with_target.gz, | 
					
						
							|  |  |  |                                         /* `target` */ | 
					
						
							| 
									
										
										
										
											2021-10-11 20:06:09 +11:00
										 |  |  |                                         py_rna_gizmo_target_id_parse_and_ensure_is_valid, | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |                                         ¶ms.gz_with_target)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   wmGizmo *gz = params.gz_with_target.gz; | 
					
						
							|  |  |  |   wmGizmoProperty *gz_prop = params.gz_with_target.gz_prop; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const int array_len = WM_gizmo_target_property_array_length(gz, gz_prop); | 
					
						
							|  |  |  |   switch (gz_prop->type->data_type) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       if (array_len != 0) { | 
					
						
							|  |  |  |         float *value = BLI_array_alloca(value, array_len); | 
					
						
							|  |  |  |         WM_gizmo_target_property_float_get_array(gz, gz_prop, value); | 
					
						
							|  |  |  |         return PyC_Tuple_PackArray_F32(value, array_len); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 16:10:13 +10:00
										 |  |  |       const float value = WM_gizmo_target_property_float_get(gz, gz_prop); | 
					
						
							| 
									
										
										
										
											2020-08-07 12:41:06 +02:00
										 |  |  |       return PyFloat_FromDouble(value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_RuntimeError, "Not yet supported type"); | 
					
						
							|  |  |  |       goto fail; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | PyDoc_STRVAR(bpy_gizmo_target_set_value_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: target_set_value(target):\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Set the value of this target property.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg target: Target property name.\n" | 
					
						
							|  |  |  |              "   :type target: string\n"); | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | static PyObject *bpy_gizmo_target_set_value(PyObject *UNUSED(self), PyObject *args, PyObject *kw) | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |     struct BPyGizmoWithTarget gz_with_target; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyObject *value; | 
					
						
							|  |  |  |   } params = { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |       .gz_with_target = {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       .value = NULL, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static const char *const _keywords[] = {"self", "target", "value", NULL}; | 
					
						
							| 
									
										
										
										
											2022-04-08 09:41:28 +10:00
										 |  |  |   static _PyArg_Parser _parser = { | 
					
						
							|  |  |  |       "O&" /* `self` */ | 
					
						
							|  |  |  |       "O&" /* `target` */ | 
					
						
							|  |  |  |       "O"  /* `value` */ | 
					
						
							|  |  |  |       ":target_set_value", | 
					
						
							|  |  |  |       _keywords, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   if (!_PyArg_ParseTupleAndKeywordsFast(args, | 
					
						
							|  |  |  |                                         kw, | 
					
						
							|  |  |  |                                         &_parser, | 
					
						
							|  |  |  |                                         /* `self` */ | 
					
						
							|  |  |  |                                         py_rna_gizmo_parse, | 
					
						
							|  |  |  |                                         ¶ms.gz_with_target.gz, | 
					
						
							|  |  |  |                                         /* `target` */ | 
					
						
							| 
									
										
										
										
											2021-10-11 20:06:09 +11:00
										 |  |  |                                         py_rna_gizmo_target_id_parse_and_ensure_is_valid, | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |                                         ¶ms.gz_with_target, | 
					
						
							|  |  |  |                                         /* `value` */ | 
					
						
							|  |  |  |                                         ¶ms.value)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   wmGizmo *gz = params.gz_with_target.gz; | 
					
						
							|  |  |  |   wmGizmoProperty *gz_prop = params.gz_with_target.gz_prop; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const int array_len = WM_gizmo_target_property_array_length(gz, gz_prop); | 
					
						
							|  |  |  |   switch (gz_prop->type->data_type) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       if (array_len != 0) { | 
					
						
							|  |  |  |         float *value = BLI_array_alloca(value, array_len); | 
					
						
							|  |  |  |         if (PyC_AsArray(value, | 
					
						
							| 
									
										
										
										
											2021-07-27 22:26:33 +10:00
										 |  |  |                         sizeof(*value), | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |                         params.value, | 
					
						
							|  |  |  |                         gz_prop->type->array_length, | 
					
						
							|  |  |  |                         &PyFloat_Type, | 
					
						
							| 
									
										
										
										
											2021-07-27 22:26:33 +10:00
										 |  |  |                         "Gizmo target property array: ") == -1) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |           goto fail; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |         WM_gizmo_target_property_float_set_array(BPY_context_get(), gz, gz_prop, value); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         float value; | 
					
						
							|  |  |  |         if ((value = PyFloat_AsDouble(params.value)) == -1.0f && PyErr_Occurred()) { | 
					
						
							|  |  |  |           goto fail; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-15 18:20:15 +11:00
										 |  |  |         WM_gizmo_target_property_float_set(BPY_context_get(), gz, gz_prop, value); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       Py_RETURN_NONE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_RuntimeError, "Not yet supported type"); | 
					
						
							|  |  |  |       goto fail; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | PyDoc_STRVAR(bpy_gizmo_target_get_range_doc, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |              ".. method:: target_get_range(target):\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   Get the range for this target property.\n" | 
					
						
							|  |  |  |              "\n" | 
					
						
							|  |  |  |              "   :arg target: Target property name.\n" | 
					
						
							|  |  |  |              "   :return: The range of this property (min, max).\n" | 
					
						
							|  |  |  |              "   :rtype: tuple pair.\n"); | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | static PyObject *bpy_gizmo_target_get_range(PyObject *UNUSED(self), PyObject *args, PyObject *kw) | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |     struct BPyGizmoWithTarget gz_with_target; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } params = { | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |       .gz_with_target = {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static const char *const _keywords[] = {"self", "target", NULL}; | 
					
						
							| 
									
										
										
										
											2022-04-08 09:41:28 +10:00
										 |  |  |   static _PyArg_Parser _parser = { | 
					
						
							|  |  |  |       "O&" /* `self` */ | 
					
						
							|  |  |  |       "O&" /* `target` */ | 
					
						
							|  |  |  |       ":target_get_range", | 
					
						
							|  |  |  |       _keywords, | 
					
						
							|  |  |  |       0, | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   if (!_PyArg_ParseTupleAndKeywordsFast(args, | 
					
						
							|  |  |  |                                         kw, | 
					
						
							|  |  |  |                                         &_parser, | 
					
						
							|  |  |  |                                         /* `self` */ | 
					
						
							|  |  |  |                                         py_rna_gizmo_parse, | 
					
						
							|  |  |  |                                         ¶ms.gz_with_target.gz, | 
					
						
							|  |  |  |                                         /* `target` */ | 
					
						
							| 
									
										
										
										
											2021-10-11 20:06:09 +11:00
										 |  |  |                                         py_rna_gizmo_target_id_parse_and_ensure_is_valid, | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |                                         ¶ms.gz_with_target)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     goto fail; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  |   wmGizmo *gz = params.gz_with_target.gz; | 
					
						
							|  |  |  |   wmGizmoProperty *gz_prop = params.gz_with_target.gz_prop; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   switch (gz_prop->type->data_type) { | 
					
						
							|  |  |  |     case PROP_FLOAT: { | 
					
						
							|  |  |  |       float range[2]; | 
					
						
							|  |  |  |       WM_gizmo_target_property_float_range_get(gz, gz_prop, range); | 
					
						
							|  |  |  |       return PyC_Tuple_PackArray_F32(range, 2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: { | 
					
						
							|  |  |  |       PyErr_SetString(PyExc_RuntimeError, "Not yet supported type"); | 
					
						
							|  |  |  |       goto fail; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Gizmo Module
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 11:10:38 +02:00
										 |  |  | bool BPY_rna_gizmo_module(PyObject *mod_par) | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   static PyMethodDef method_def_array[] = { | 
					
						
							|  |  |  |       /* Gizmo Target Property Define API */ | 
					
						
							|  |  |  |       {"target_set_handler", | 
					
						
							|  |  |  |        (PyCFunction)bpy_gizmo_target_set_handler, | 
					
						
							|  |  |  |        METH_VARARGS | METH_KEYWORDS, | 
					
						
							|  |  |  |        bpy_gizmo_target_set_handler_doc}, | 
					
						
							|  |  |  |       /* Gizmo Target Property Access API */ | 
					
						
							|  |  |  |       {"target_get_value", | 
					
						
							|  |  |  |        (PyCFunction)bpy_gizmo_target_get_value, | 
					
						
							|  |  |  |        METH_VARARGS | METH_KEYWORDS, | 
					
						
							|  |  |  |        bpy_gizmo_target_get_value_doc}, | 
					
						
							|  |  |  |       {"target_set_value", | 
					
						
							|  |  |  |        (PyCFunction)bpy_gizmo_target_set_value, | 
					
						
							|  |  |  |        METH_VARARGS | METH_KEYWORDS, | 
					
						
							|  |  |  |        bpy_gizmo_target_set_value_doc}, | 
					
						
							|  |  |  |       {"target_get_range", | 
					
						
							|  |  |  |        (PyCFunction)bpy_gizmo_target_get_range, | 
					
						
							|  |  |  |        METH_VARARGS | METH_KEYWORDS, | 
					
						
							|  |  |  |        bpy_gizmo_target_get_range_doc}, | 
					
						
							|  |  |  |       /* no sentinel needed. */ | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int i = 0; i < ARRAY_SIZE(method_def_array); i++) { | 
					
						
							|  |  |  |     PyMethodDef *m = &method_def_array[i]; | 
					
						
							|  |  |  |     PyObject *func = PyCFunction_New(m, NULL); | 
					
						
							|  |  |  |     PyObject *func_inst = PyInstanceMethod_New(func); | 
					
						
							|  |  |  |     char name_prefix[128]; | 
					
						
							|  |  |  |     PyOS_snprintf(name_prefix, sizeof(name_prefix), "_rna_gizmo_%s", m->ml_name); | 
					
						
							| 
									
										
										
										
											2021-07-03 23:08:40 +10:00
										 |  |  |     /* TODO: return a type that binds nearly to a method. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     PyModule_AddObject(mod_par, name_prefix, func_inst); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 11:10:38 +02:00
										 |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2017-08-22 18:55:19 +10:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-11 19:59:06 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |