| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup pythonintern | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This file is so Python can define widget-group's that C can call into. | 
					
						
							|  |  |  |  * The generic callback functions for Python widget-group are defines in | 
					
						
							|  |  |  |  * 'rna_wm.c', some calling into functions here to do python specific | 
					
						
							|  |  |  |  * functionality. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \note This follows 'bpy_operator_wrap.c' very closely. | 
					
						
							|  |  |  |  * Keep in sync unless there is good reason not to! | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Python.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | #include "RNA_define.h"
 | 
					
						
							|  |  |  | #include "RNA_enum_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bpy_rna.h"
 | 
					
						
							|  |  |  | #include "bpy_intern_string.h"
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:16:34 +02:00
										 |  |  | #include "bpy_gizmo_wrap.h"  /* own include */
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* we may want to add, but not now */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | /** \name Gizmo
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | static bool bpy_gizmotype_target_property_def( | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  |         wmGizmoType *gzt, PyObject *item) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Note: names based on 'rna_rna.c' */ | 
					
						
							|  |  |  | 	PyObject *empty_tuple = PyTuple_New(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct { | 
					
						
							|  |  |  | 		char *id; | 
					
						
							|  |  |  | 		char *type_id; int type; | 
					
						
							|  |  |  | 		int array_length; | 
					
						
							|  |  |  | 	} params = { | 
					
						
							|  |  |  | 		.id = NULL, /* not optional */ | 
					
						
							|  |  |  | 		.type = PROP_FLOAT, | 
					
						
							|  |  |  | 		.type_id = NULL, | 
					
						
							|  |  |  | 		.array_length = 1, | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 19:57:48 +10:00
										 |  |  | 	static const char * const _keywords[] = {"id", "type", "array_length", NULL}; | 
					
						
							| 
									
										
										
										
											2017-10-07 15:14:36 +11:00
										 |  |  | 	static _PyArg_Parser _parser = {"|$ssi:register_class", _keywords, 0}; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 	if (!_PyArg_ParseTupleAndKeywordsFast( | 
					
						
							|  |  |  | 	        empty_tuple, item, | 
					
						
							|  |  |  | 	        &_parser, | 
					
						
							|  |  |  | 	        ¶ms.id, | 
					
						
							|  |  |  | 	        ¶ms.type_id, | 
					
						
							|  |  |  | 	        ¶ms.array_length)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (params.id == NULL) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ValueError, "'id' argument not given"); | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((params.type_id != NULL) && | 
					
						
							|  |  |  | 	    pyrna_enum_value_from_id( | 
					
						
							|  |  |  | 	        rna_enum_property_type_items, params.type_id, ¶ms.type, "'type' enum value") == -1) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		params.type = rna_enum_property_type_items[params.type].value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((params.array_length < 1 || params.array_length > RNA_MAX_ARRAY_LENGTH)) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_ValueError, "'array_length' out of range"); | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	WM_gizmotype_target_property_def(gzt, params.id, params.type, params.array_length); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 	Py_DECREF(empty_tuple); | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							|  |  |  | 	Py_DECREF(empty_tuple); | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | static void gizmo_properties_init(wmGizmoType *gzt) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	PyTypeObject *py_class = gzt->ext.data; | 
					
						
							|  |  |  | 	RNA_struct_blender_type_set(gzt->ext.srna, gzt); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* only call this so pyrna_deferred_register_class gives a useful error
 | 
					
						
							|  |  |  | 	 * WM_operatortype_append_ptr will call RNA_def_struct_identifier | 
					
						
							|  |  |  | 	 * later */ | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	RNA_def_struct_identifier_no_struct_map(gzt->srna, gzt->idname); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	if (pyrna_deferred_register_class(gzt->srna, py_class) != 0) { | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 		PyErr_Print(); /* failed to register operator props */ | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Extract target property definitions from 'bl_target_properties' */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* picky developers will notice that 'bl_targets' won't work with inheritance
 | 
					
						
							|  |  |  | 		 * get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */ | 
					
						
							|  |  |  | 		PyObject *py_class_dict = py_class->tp_dict; | 
					
						
							|  |  |  | 		PyObject *bl_target_properties = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_target_properties); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-17 12:29:37 +10:00
										 |  |  | 		/* Some widgets may only exist to activate operators. */ | 
					
						
							|  |  |  | 		if (bl_target_properties != NULL) { | 
					
						
							|  |  |  | 			PyObject *bl_target_properties_fast; | 
					
						
							|  |  |  | 			if (!(bl_target_properties_fast = PySequence_Fast( | 
					
						
							|  |  |  | 			          bl_target_properties, "bl_target_properties sequence"))) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* PySequence_Fast sets the error */ | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 				PyErr_Print(); | 
					
						
							|  |  |  | 				PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2017-07-17 12:29:37 +10:00
										 |  |  | 				return; | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-17 12:29:37 +10:00
										 |  |  | 			const uint items_len = PySequence_Fast_GET_SIZE(bl_target_properties_fast); | 
					
						
							|  |  |  | 			PyObject **items = PySequence_Fast_ITEMS(bl_target_properties_fast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (uint i = 0; i < items_len; i++) { | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 				if (!bpy_gizmotype_target_property_def(gzt, items[i])) { | 
					
						
							| 
									
										
										
										
											2017-07-17 12:29:37 +10:00
										 |  |  | 					PyErr_Print(); | 
					
						
							|  |  |  | 					PyErr_Clear(); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Py_DECREF(bl_target_properties_fast); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | void BPY_RNA_gizmo_wrapper(wmGizmoType *gzt, void *userdata) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* take care not to overwrite anything set in
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | 	 * WM_gizmomaptype_group_link_ptr before opfunc() is called */ | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	StructRNA *srna = gzt->srna; | 
					
						
							|  |  |  | 	*gzt = *((wmGizmoType *)userdata); | 
					
						
							|  |  |  | 	gzt->srna = srna; /* restore */ | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* don't do translations here yet */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | 	/* Use i18n context from ext.srna if possible (py gizmogroups). */ | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	if (gt->ext.srna) { | 
					
						
							|  |  |  | 		RNA_def_struct_translation_context(gt->srna, RNA_struct_translation_context(gt->ext.srna)); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	gzt->struct_size = sizeof(wmGizmo); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	gizmo_properties_init(gzt); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | /** \name Gizmo Group
 | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | static void gizmogroup_properties_init(wmGizmoGroupType *gzgt) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	PyTypeObject *py_class = gzgt->ext.data; | 
					
						
							|  |  |  | 	RNA_struct_blender_type_set(gzgt->ext.srna, gzgt); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* only call this so pyrna_deferred_register_class gives a useful error
 | 
					
						
							|  |  |  | 	 * WM_operatortype_append_ptr will call RNA_def_struct_identifier | 
					
						
							|  |  |  | 	 * later */ | 
					
						
							| 
									
										
										
										
											2018-10-02 16:59:54 +10:00
										 |  |  | 	RNA_def_struct_identifier_no_struct_map(gzgt->srna, gzgt->idname); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	if (pyrna_deferred_register_class(gzgt->srna, py_class) != 0) { | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 		PyErr_Print(); /* failed to register operator props */ | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | void BPY_RNA_gizmogroup_wrapper(wmGizmoGroupType *gzgt, void *userdata) | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* take care not to overwrite anything set in
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | 	 * WM_gizmomaptype_group_link_ptr before opfunc() is called */ | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	StructRNA *srna = gzgt->srna; | 
					
						
							|  |  |  | 	*gzgt = *((wmGizmoGroupType *)userdata); | 
					
						
							|  |  |  | 	gzgt->srna = srna; /* restore */ | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-02 16:59:54 +10:00
										 |  |  | 	/* don't do translations here yet */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2018-07-14 23:49:00 +02:00
										 |  |  | 	/* Use i18n context from ext.srna if possible (py gizmogroups). */ | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	if (gzgt->ext.srna) { | 
					
						
							|  |  |  | 		RNA_def_struct_translation_context(gzgt->srna, RNA_struct_translation_context(gzgt->ext.srna)); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-15 14:24:10 +02:00
										 |  |  | 	gizmogroup_properties_init(gzgt); | 
					
						
							| 
									
										
										
										
											2017-06-26 15:57:14 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |