Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Campbell Barton 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00032 #include <Python.h> 00033 00034 #include "RNA_types.h" 00035 00036 #include "bpy_props.h" 00037 #include "bpy_rna.h" 00038 #include "bpy_util.h" 00039 00040 #include "BLI_utildefines.h" 00041 00042 #include "BKE_idprop.h" 00043 00044 #include "RNA_access.h" 00045 #include "RNA_define.h" /* for defining our own rna */ 00046 #include "RNA_enum_types.h" 00047 00048 #include "MEM_guardedalloc.h" 00049 00050 #include "../generic/py_capi_utils.h" 00051 00052 /* initial definition of callback slots we'll probably have more then 1 */ 00053 #define BPY_DATA_CB_SLOT_SIZE 1 00054 00055 #define BPY_DATA_CB_SLOT_UPDATE 0 00056 00057 extern BPy_StructRNA *bpy_context_module; 00058 00059 static EnumPropertyItem property_flag_items[] = { 00060 {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, 00061 {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""}, 00062 {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""}, 00063 {0, NULL, 0, NULL, NULL}}; 00064 00065 static EnumPropertyItem property_flag_enum_items[] = { 00066 {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""}, 00067 {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""}, 00068 {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""}, 00069 {PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""}, 00070 {0, NULL, 0, NULL, NULL}}; 00071 00072 /* subtypes */ 00073 static EnumPropertyItem property_subtype_string_items[] = { 00074 {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, 00075 {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""}, 00076 {PROP_FILENAME, "FILENAME", 0, "Filename", ""}, 00077 {PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""}, 00078 {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""}, 00079 00080 {PROP_NONE, "NONE", 0, "None", ""}, 00081 {0, NULL, 0, NULL, NULL}}; 00082 00083 static EnumPropertyItem property_subtype_number_items[] = { 00084 {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""}, 00085 {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""}, 00086 {PROP_FACTOR, "FACTOR", 0, "Factor", ""}, 00087 {PROP_ANGLE, "ANGLE", 0, "Angle", ""}, 00088 {PROP_TIME, "TIME", 0, "Time", ""}, 00089 {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""}, 00090 00091 {PROP_NONE, "NONE", 0, "None", ""}, 00092 {0, NULL, 0, NULL, NULL}}; 00093 00094 static EnumPropertyItem property_subtype_array_items[] = { 00095 {PROP_COLOR, "COLOR", 0, "Color", ""}, 00096 {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""}, 00097 {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""}, 00098 {PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""}, 00099 {PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""}, 00100 {PROP_MATRIX, "MATRIX", 0, "Matrix", ""}, 00101 {PROP_EULER, "EULER", 0, "Euler", ""}, 00102 {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""}, 00103 {PROP_AXISANGLE, "AXISANGLE", 0, "Axis Angle", ""}, 00104 {PROP_XYZ, "XYZ", 0, "XYZ", ""}, 00105 {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Color Gamma", ""}, 00106 {PROP_LAYER, "LAYER", 0, "Layer", ""}, 00107 00108 {PROP_NONE, "NONE", 0, "None", ""}, 00109 {0, NULL, 0, NULL, NULL}}; 00110 00111 /* PyObject's */ 00112 static PyObject *pymeth_BoolProperty = NULL; 00113 static PyObject *pymeth_BoolVectorProperty = NULL; 00114 static PyObject *pymeth_IntProperty = NULL; 00115 static PyObject *pymeth_IntVectorProperty = NULL; 00116 static PyObject *pymeth_FloatProperty = NULL; 00117 static PyObject *pymeth_FloatVectorProperty = NULL; 00118 static PyObject *pymeth_StringProperty = NULL; 00119 static PyObject *pymeth_EnumProperty = NULL; 00120 static PyObject *pymeth_PointerProperty = NULL; 00121 static PyObject *pymeth_CollectionProperty = NULL; 00122 static PyObject *pymeth_RemoveProperty = NULL; 00123 00124 static PyObject *pyrna_struct_as_instance(PointerRNA *ptr) 00125 { 00126 PyObject *self = NULL; 00127 /* first get self */ 00128 /* operators can store their own instance for later use */ 00129 if (ptr->data) { 00130 void **instance = RNA_struct_instance(ptr); 00131 00132 if (instance) { 00133 if (*instance) { 00134 self = *instance; 00135 Py_INCREF(self); 00136 } 00137 } 00138 } 00139 00140 /* in most cases this will run */ 00141 if (self == NULL) { 00142 self = pyrna_struct_CreatePyObject(ptr); 00143 } 00144 00145 return self; 00146 } 00147 00148 /* could be moved into bpy_utils */ 00149 static void printf_func_error(PyObject *py_func) 00150 { 00151 /* since we return to C code we can't leave the error */ 00152 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); 00153 PyErr_Print(); 00154 PyErr_Clear(); 00155 00156 /* use py style error */ 00157 fprintf(stderr, "File \"%s\", line %d, in %s\n", 00158 _PyUnicode_AsString(f_code->co_filename), 00159 f_code->co_firstlineno, 00160 _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name) 00161 ); 00162 } 00163 00164 /* operators and classes use this so it can store the args given but defer 00165 * running it until the operator runs where these values are used to setup 00166 * the default args for that operator instance */ 00167 static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw) 00168 { 00169 PyObject *ret = PyTuple_New(2); 00170 PyTuple_SET_ITEM(ret, 0, func); 00171 Py_INCREF(func); 00172 00173 if (kw == NULL) 00174 kw = PyDict_New(); 00175 else 00176 Py_INCREF(kw); 00177 00178 PyTuple_SET_ITEM(ret, 1, kw); 00179 00180 return ret; 00181 } 00182 00183 /* callbacks */ 00184 static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop) 00185 { 00186 PyGILState_STATE gilstate; 00187 PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); 00188 PyObject *py_func; 00189 PyObject *args; 00190 PyObject *self; 00191 PyObject *ret; 00192 const int is_write_ok = pyrna_write_check(); 00193 00194 BLI_assert(py_data != NULL); 00195 00196 if (!is_write_ok) { 00197 pyrna_write_set(TRUE); 00198 } 00199 00200 bpy_context_set(C, &gilstate); 00201 00202 py_func = py_data[BPY_DATA_CB_SLOT_UPDATE]; 00203 00204 args = PyTuple_New(2); 00205 self = pyrna_struct_as_instance(ptr); 00206 PyTuple_SET_ITEM(args, 0, self); 00207 00208 PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); 00209 Py_INCREF(bpy_context_module); 00210 00211 ret = PyObject_CallObject(py_func, args); 00212 00213 Py_DECREF(args); 00214 00215 if (ret == NULL) { 00216 printf_func_error(py_func); 00217 } 00218 else { 00219 if (ret != Py_None) { 00220 PyErr_SetString(PyExc_ValueError, "the return value must be None"); 00221 printf_func_error(py_func); 00222 } 00223 00224 Py_DECREF(ret); 00225 } 00226 00227 bpy_context_clear(C, &gilstate); 00228 00229 if (!is_write_ok) { 00230 pyrna_write_set(FALSE); 00231 } 00232 } 00233 00234 static int bpy_prop_callback_check(PyObject *py_func, int argcount) 00235 { 00236 if (py_func && py_func != Py_None) { 00237 if (!PyFunction_Check(py_func)) { 00238 PyErr_Format(PyExc_TypeError, 00239 "update keyword: expected a function type, not a %.200s", 00240 Py_TYPE(py_func)->tp_name); 00241 return -1; 00242 } 00243 else { 00244 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); 00245 if (f_code->co_argcount != argcount) { 00246 PyErr_Format(PyExc_TypeError, 00247 "update keyword: expected a function taking %d arguments, not %d", 00248 argcount, f_code->co_argcount); 00249 return -1; 00250 } 00251 } 00252 } 00253 00254 return 0; 00255 } 00256 00257 00258 static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb) 00259 { 00260 /* assume this is already checked for type and arg length */ 00261 if (update_cb) { 00262 PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); 00263 RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); 00264 py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb; 00265 RNA_def_py_data(prop, py_data); 00266 00267 RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE); 00268 } 00269 00270 return 0; 00271 } 00272 00273 /* utility function we need for parsing int's in an if statement */ 00274 static int py_long_as_int(PyObject *py_long, int *r_int) 00275 { 00276 if (PyLong_CheckExact(py_long)) { 00277 *r_int = (int)PyLong_AS_LONG(py_long); 00278 return 0; 00279 } 00280 else { 00281 return -1; 00282 } 00283 } 00284 00285 /* this define runs at the start of each function and deals with 00286 * returning a deferred property (to be registered later) */ 00287 #define BPY_PROPDEF_HEAD(_func) \ 00288 if (PyTuple_GET_SIZE(args) == 1) { \ 00289 PyObject *ret; \ 00290 self = PyTuple_GET_ITEM(args, 0); \ 00291 args = PyTuple_New(0); \ 00292 ret = BPy_##_func(self, args, kw); \ 00293 Py_DECREF(args); \ 00294 return ret; \ 00295 } \ 00296 else if (PyTuple_GET_SIZE(args) > 1) { \ 00297 PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ 00298 return NULL; \ 00299 } \ 00300 srna = srna_from_self(self, #_func"(...):"); \ 00301 if (srna == NULL) { \ 00302 if (PyErr_Occurred()) \ 00303 return NULL; \ 00304 return bpy_prop_deferred_return(pymeth_##_func, kw); \ 00305 } \ 00306 00307 /* terse macros for error checks shared between all funcs cant use function 00308 * calls because of static strins passed to pyrna_set_to_enum_bitfield */ 00309 #define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ 00310 if (id_len >= MAX_IDPROP_NAME) { \ 00311 PyErr_Format(PyExc_TypeError, \ 00312 #_func"(): '%.200s' too long, max length is %d", \ 00313 id, MAX_IDPROP_NAME - 1); \ 00314 return NULL; \ 00315 } \ 00316 if (RNA_def_property_free_identifier(srna, id) == -1) { \ 00317 PyErr_Format(PyExc_TypeError, \ 00318 #_func"(): '%s' is defined as a non-dynamic type", \ 00319 id); \ 00320 return NULL; \ 00321 } \ 00322 if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ 00323 pyopts, \ 00324 &opts, \ 00325 #_func"(options={ ...}):")) \ 00326 { \ 00327 return NULL; \ 00328 } \ 00329 00330 #define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ 00331 BPY_PROPDEF_CHECK(_func, _property_flag_items) \ 00332 if (pysubtype && RNA_enum_value_from_id(_subtype, \ 00333 pysubtype, \ 00334 &subtype) == 0) \ 00335 { \ 00336 PyErr_Format(PyExc_TypeError, \ 00337 #_func"(subtype='%s'): invalid subtype", \ 00338 pysubtype); \ 00339 return NULL; \ 00340 } \ 00341 00342 00343 #define BPY_PROPDEF_NAME_DOC \ 00344 " :arg name: Name used in the user interface.\n" \ 00345 " :type name: string\n" \ 00346 00347 00348 #define BPY_PROPDEF_DESC_DOC \ 00349 " :arg description: Text used for the tooltip and api documentation.\n" \ 00350 " :type description: string\n" \ 00351 00352 00353 #define BPY_PROPDEF_UNIT_DOC \ 00354 " :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \ 00355 " :type unit: string\n" \ 00356 00357 00358 #define BPY_PROPDEF_UPDATE_DOC \ 00359 " :arg update: function to be called when this value is modified,\n" \ 00360 " This function must take 2 values (self, context) and return None.\n" \ 00361 " :type update: function\n" \ 00362 00363 #if 0 00364 static int bpy_struct_id_used(StructRNA *srna, char *identifier) 00365 { 00366 PointerRNA ptr; 00367 RNA_pointer_create(NULL, srna, NULL, &ptr); 00368 return (RNA_struct_find_property(&ptr, identifier) != NULL); 00369 } 00370 #endif 00371 00372 00373 /* Function that sets RNA, NOTE - self is NULL when called from python, 00374 * but being abused from C so we can pass the srna along. 00375 * This isnt incorrect since its a python object - but be careful */ 00376 PyDoc_STRVAR(BPy_BoolProperty_doc, 00377 ".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE', update=None)\n" 00378 "\n" 00379 " Returns a new boolean property definition.\n" 00380 "\n" 00381 BPY_PROPDEF_NAME_DOC 00382 BPY_PROPDEF_DESC_DOC 00383 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00384 " :type options: set\n" 00385 " :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" 00386 " :type subtype: string\n" 00387 BPY_PROPDEF_UPDATE_DOC 00388 ); 00389 static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) 00390 { 00391 StructRNA *srna; 00392 00393 BPY_PROPDEF_HEAD(BoolProperty) 00394 00395 if (srna) { 00396 static const char *kwlist[] = {"attr", "name", "description", "default", 00397 "options", "subtype", "update", NULL}; 00398 const char *id = NULL, *name = NULL, *description = ""; 00399 int id_len; 00400 int def = 0; 00401 PropertyRNA *prop; 00402 PyObject *pyopts = NULL; 00403 int opts = 0; 00404 char *pysubtype = NULL; 00405 int subtype = PROP_NONE; 00406 PyObject *update_cb = NULL; 00407 00408 if (!PyArg_ParseTupleAndKeywords(args, kw, 00409 "s#|ssiO!sO:BoolProperty", 00410 (char **)kwlist, &id, &id_len, 00411 &name, &description, &def, 00412 &PySet_Type, &pyopts, &pysubtype, 00413 &update_cb)) 00414 { 00415 return NULL; 00416 } 00417 00418 BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items) 00419 00420 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00421 return NULL; 00422 } 00423 00424 prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); 00425 RNA_def_property_boolean_default(prop, def); 00426 RNA_def_property_ui_text(prop, name ? name : id, description); 00427 00428 if (pyopts) { 00429 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00430 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00431 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00432 } 00433 bpy_prop_callback_assign(prop, update_cb); 00434 RNA_def_property_duplicate_pointers(srna, prop); 00435 } 00436 00437 Py_RETURN_NONE; 00438 } 00439 00440 PyDoc_STRVAR(BPy_BoolVectorProperty_doc, 00441 ".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n" 00442 "\n" 00443 " Returns a new vector boolean property definition.\n" 00444 "\n" 00445 BPY_PROPDEF_NAME_DOC 00446 BPY_PROPDEF_DESC_DOC 00447 " :arg default: sequence of booleans the length of *size*.\n" 00448 " :type default: sequence\n" 00449 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00450 " :type options: set\n" 00451 " :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" 00452 " :type subtype: string\n" 00453 " :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" 00454 " :type size: int\n" 00455 BPY_PROPDEF_UPDATE_DOC 00456 ); 00457 static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw) 00458 { 00459 StructRNA *srna; 00460 00461 BPY_PROPDEF_HEAD(BoolVectorProperty) 00462 00463 if (srna) { 00464 static const char *kwlist[] = {"attr", "name", "description", "default", 00465 "options", "subtype", "size", "update", NULL}; 00466 const char *id = NULL, *name = NULL, *description = ""; 00467 int id_len; 00468 int def[PYRNA_STACK_ARRAY] = {0}; 00469 int size = 3; 00470 PropertyRNA *prop; 00471 PyObject *pydef = NULL; 00472 PyObject *pyopts = NULL; 00473 int opts = 0; 00474 char *pysubtype = NULL; 00475 int subtype = PROP_NONE; 00476 PyObject *update_cb = NULL; 00477 00478 if (!PyArg_ParseTupleAndKeywords(args, kw, 00479 "s#|ssOO!siO:BoolVectorProperty", 00480 (char **)kwlist, &id, &id_len, 00481 &name, &description, &pydef, 00482 &PySet_Type, &pyopts, &pysubtype, &size, 00483 &update_cb)) 00484 { 00485 return NULL; 00486 } 00487 00488 BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items) 00489 00490 if (size < 1 || size > PYRNA_STACK_ARRAY) { 00491 PyErr_Format(PyExc_TypeError, 00492 "BoolVectorProperty(size=%d): size must be between 0 and " 00493 STRINGIFY(PYRNA_STACK_ARRAY), size); 00494 return NULL; 00495 } 00496 00497 if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0) 00498 return NULL; 00499 00500 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00501 return NULL; 00502 } 00503 00504 // prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description); 00505 prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype); 00506 RNA_def_property_array(prop, size); 00507 if (pydef) RNA_def_property_boolean_array_default(prop, def); 00508 RNA_def_property_ui_text(prop, name ? name : id, description); 00509 00510 if (pyopts) { 00511 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00512 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00513 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00514 } 00515 bpy_prop_callback_assign(prop, update_cb); 00516 RNA_def_property_duplicate_pointers(srna, prop); 00517 } 00518 00519 Py_RETURN_NONE; 00520 } 00521 00522 PyDoc_STRVAR(BPy_IntProperty_doc, 00523 ".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE', update=None)\n" 00524 "\n" 00525 " Returns a new int property definition.\n" 00526 "\n" 00527 BPY_PROPDEF_NAME_DOC 00528 BPY_PROPDEF_DESC_DOC 00529 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00530 " :type options: set\n" 00531 " :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" 00532 " :type subtype: string\n" 00533 BPY_PROPDEF_UPDATE_DOC 00534 ); 00535 static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) 00536 { 00537 StructRNA *srna; 00538 00539 BPY_PROPDEF_HEAD(IntProperty) 00540 00541 if (srna) { 00542 static const char *kwlist[] = {"attr", "name", "description", "default", 00543 "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "update", NULL}; 00544 const char *id = NULL, *name = NULL, *description = ""; 00545 int id_len; 00546 int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; 00547 PropertyRNA *prop; 00548 PyObject *pyopts = NULL; 00549 int opts = 0; 00550 char *pysubtype = NULL; 00551 int subtype = PROP_NONE; 00552 PyObject *update_cb = NULL; 00553 00554 if (!PyArg_ParseTupleAndKeywords(args, kw, 00555 "s#|ssiiiiiiO!sO:IntProperty", 00556 (char **)kwlist, &id, &id_len, 00557 &name, &description, &def, 00558 &min, &max, &soft_min, &soft_max, 00559 &step, &PySet_Type, &pyopts, &pysubtype, 00560 &update_cb)) 00561 { 00562 return NULL; 00563 } 00564 00565 BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items) 00566 00567 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00568 return NULL; 00569 } 00570 00571 prop = RNA_def_property(srna, id, PROP_INT, subtype); 00572 RNA_def_property_int_default(prop, def); 00573 RNA_def_property_ui_text(prop, name ? name : id, description); 00574 RNA_def_property_range(prop, min, max); 00575 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); 00576 00577 if (pyopts) { 00578 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00579 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00580 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00581 } 00582 bpy_prop_callback_assign(prop, update_cb); 00583 RNA_def_property_duplicate_pointers(srna, prop); 00584 } 00585 Py_RETURN_NONE; 00586 } 00587 00588 PyDoc_STRVAR(BPy_IntVectorProperty_doc, 00589 ".. function:: IntVectorProperty(name=\"\", description=\"\", default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n" 00590 "\n" 00591 " Returns a new vector int property definition.\n" 00592 "\n" 00593 BPY_PROPDEF_NAME_DOC 00594 BPY_PROPDEF_DESC_DOC 00595 " :arg default: sequence of ints the length of *size*.\n" 00596 " :type default: sequence\n" 00597 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00598 " :type options: set\n" 00599 " :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" 00600 " :type subtype: string\n" 00601 " :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" 00602 " :type size: int\n" 00603 BPY_PROPDEF_UPDATE_DOC 00604 ); 00605 static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw) 00606 { 00607 StructRNA *srna; 00608 00609 BPY_PROPDEF_HEAD(IntVectorProperty) 00610 00611 if (srna) { 00612 static const char *kwlist[] = {"attr", "name", "description", "default", 00613 "min", "max", "soft_min", "soft_max", 00614 "step", "options", "subtype", "size", "update", NULL}; 00615 const char *id = NULL, *name = NULL, *description = ""; 00616 int id_len; 00617 int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; 00618 int def[PYRNA_STACK_ARRAY] = {0}; 00619 int size = 3; 00620 PropertyRNA *prop; 00621 PyObject *pydef = NULL; 00622 PyObject *pyopts = NULL; 00623 int opts = 0; 00624 char *pysubtype = NULL; 00625 int subtype = PROP_NONE; 00626 PyObject *update_cb = NULL; 00627 00628 if (!PyArg_ParseTupleAndKeywords(args, kw, 00629 "s#|ssOiiiiiO!siO:IntVectorProperty", 00630 (char **)kwlist, &id, &id_len, 00631 &name, &description, &pydef, 00632 &min, &max, &soft_min, &soft_max, 00633 &step, &PySet_Type, &pyopts, 00634 &pysubtype, &size, 00635 &update_cb)) 00636 { 00637 return NULL; 00638 } 00639 00640 BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items) 00641 00642 if (size < 1 || size > PYRNA_STACK_ARRAY) { 00643 PyErr_Format(PyExc_TypeError, 00644 "IntVectorProperty(size=%d): size must be between 0 and " 00645 STRINGIFY(PYRNA_STACK_ARRAY), size); 00646 return NULL; 00647 } 00648 00649 if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0) 00650 return NULL; 00651 00652 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00653 return NULL; 00654 } 00655 00656 prop = RNA_def_property(srna, id, PROP_INT, subtype); 00657 RNA_def_property_array(prop, size); 00658 if (pydef) RNA_def_property_int_array_default(prop, def); 00659 RNA_def_property_range(prop, min, max); 00660 RNA_def_property_ui_text(prop, name ? name : id, description); 00661 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); 00662 00663 if (pyopts) { 00664 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00665 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00666 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00667 } 00668 bpy_prop_callback_assign(prop, update_cb); 00669 RNA_def_property_duplicate_pointers(srna, prop); 00670 } 00671 Py_RETURN_NONE; 00672 } 00673 00674 00675 PyDoc_STRVAR(BPy_FloatProperty_doc, 00676 ".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', unit='NONE', update=None)\n" 00677 "\n" 00678 " Returns a new float property definition.\n" 00679 "\n" 00680 BPY_PROPDEF_NAME_DOC 00681 BPY_PROPDEF_DESC_DOC 00682 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00683 " :type options: set\n" 00684 " :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n" 00685 " :type subtype: string\n" 00686 BPY_PROPDEF_UNIT_DOC 00687 BPY_PROPDEF_UPDATE_DOC 00688 ); 00689 static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) 00690 { 00691 StructRNA *srna; 00692 00693 BPY_PROPDEF_HEAD(FloatProperty) 00694 00695 if (srna) { 00696 static const char *kwlist[] = {"attr", "name", "description", "default", 00697 "min", "max", "soft_min", "soft_max", 00698 "step", "precision", "options", "subtype", "unit", "update", NULL}; 00699 const char *id = NULL, *name = NULL, *description = ""; 00700 int id_len; 00701 float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; 00702 int precision = 2; 00703 PropertyRNA *prop; 00704 PyObject *pyopts = NULL; 00705 int opts = 0; 00706 char *pysubtype = NULL; 00707 int subtype = PROP_NONE; 00708 char *pyunit = NULL; 00709 int unit = PROP_UNIT_NONE; 00710 PyObject *update_cb = NULL; 00711 00712 if (!PyArg_ParseTupleAndKeywords(args, kw, 00713 "s#|ssffffffiO!ssO:FloatProperty", 00714 (char **)kwlist, &id, &id_len, 00715 &name, &description, &def, 00716 &min, &max, &soft_min, &soft_max, 00717 &step, &precision, &PySet_Type, 00718 &pyopts, &pysubtype, &pyunit, 00719 &update_cb)) 00720 { 00721 return NULL; 00722 } 00723 00724 BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items) 00725 00726 if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { 00727 PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit); 00728 return NULL; 00729 } 00730 00731 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00732 return NULL; 00733 } 00734 00735 prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); 00736 RNA_def_property_float_default(prop, def); 00737 RNA_def_property_range(prop, min, max); 00738 RNA_def_property_ui_text(prop, name ? name : id, description); 00739 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); 00740 00741 if (pyopts) { 00742 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00743 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00744 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00745 } 00746 bpy_prop_callback_assign(prop, update_cb); 00747 RNA_def_property_duplicate_pointers(srna, prop); 00748 } 00749 Py_RETURN_NONE; 00750 } 00751 00752 PyDoc_STRVAR(BPy_FloatVectorProperty_doc, 00753 ".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n" 00754 "\n" 00755 " Returns a new vector float property definition.\n" 00756 "\n" 00757 BPY_PROPDEF_NAME_DOC 00758 BPY_PROPDEF_DESC_DOC 00759 " :arg default: sequence of floats the length of *size*.\n" 00760 " :type default: sequence\n" 00761 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00762 " :type options: set\n" 00763 " :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n" 00764 " :type subtype: string\n" 00765 BPY_PROPDEF_UNIT_DOC 00766 " :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n" 00767 " :type size: int\n" 00768 BPY_PROPDEF_UPDATE_DOC 00769 ); 00770 static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw) 00771 { 00772 StructRNA *srna; 00773 00774 BPY_PROPDEF_HEAD(FloatVectorProperty) 00775 00776 if (srna) { 00777 static const char *kwlist[] = {"attr", "name", "description", "default", 00778 "min", "max", "soft_min", "soft_max", 00779 "step", "precision", "options", "subtype", "unit", "size", "update", NULL}; 00780 const char *id = NULL, *name = NULL, *description = ""; 00781 int id_len; 00782 float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def[PYRNA_STACK_ARRAY] = {0.0f}; 00783 int precision = 2, size = 3; 00784 PropertyRNA *prop; 00785 PyObject *pydef = NULL; 00786 PyObject *pyopts = NULL; 00787 int opts = 0; 00788 char *pysubtype = NULL; 00789 int subtype = PROP_NONE; 00790 char *pyunit = NULL; 00791 int unit = PROP_UNIT_NONE; 00792 PyObject *update_cb = NULL; 00793 00794 if (!PyArg_ParseTupleAndKeywords(args, kw, 00795 "s#|ssOfffffiO!ssiO:FloatVectorProperty", 00796 (char **)kwlist, &id, &id_len, 00797 &name, &description, &pydef, 00798 &min, &max, &soft_min, &soft_max, 00799 &step, &precision, &PySet_Type, 00800 &pyopts, &pysubtype, &pyunit, &size, 00801 &update_cb)) 00802 { 00803 return NULL; 00804 } 00805 00806 BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items) 00807 00808 if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) { 00809 PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit); 00810 return NULL; 00811 } 00812 00813 if (size < 1 || size > PYRNA_STACK_ARRAY) { 00814 PyErr_Format(PyExc_TypeError, 00815 "FloatVectorProperty(size=%d): size must be between 0 and " 00816 STRINGIFY(PYRNA_STACK_ARRAY), size); 00817 return NULL; 00818 } 00819 00820 if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0) 00821 return NULL; 00822 00823 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00824 return NULL; 00825 } 00826 00827 prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit); 00828 RNA_def_property_array(prop, size); 00829 if (pydef) RNA_def_property_float_array_default(prop, def); 00830 RNA_def_property_range(prop, min, max); 00831 RNA_def_property_ui_text(prop, name ? name : id, description); 00832 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision); 00833 00834 if (pyopts) { 00835 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00836 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00837 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00838 } 00839 bpy_prop_callback_assign(prop, update_cb); 00840 RNA_def_property_duplicate_pointers(srna, prop); 00841 } 00842 Py_RETURN_NONE; 00843 } 00844 00845 PyDoc_STRVAR(BPy_StringProperty_doc, 00846 ".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE', update=None)\n" 00847 "\n" 00848 " Returns a new string property definition.\n" 00849 "\n" 00850 BPY_PROPDEF_NAME_DOC 00851 BPY_PROPDEF_DESC_DOC 00852 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 00853 " :type options: set\n" 00854 " :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILENAME', 'NONE'].\n" 00855 " :type subtype: string\n" 00856 BPY_PROPDEF_UPDATE_DOC 00857 ); 00858 static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw) 00859 { 00860 StructRNA *srna; 00861 00862 BPY_PROPDEF_HEAD(StringProperty) 00863 00864 if (srna) { 00865 static const char *kwlist[] = {"attr", "name", "description", "default", 00866 "maxlen", "options", "subtype", "update", NULL}; 00867 const char *id = NULL, *name = NULL, *description = "", *def = ""; 00868 int id_len; 00869 int maxlen = 0; 00870 PropertyRNA *prop; 00871 PyObject *pyopts = NULL; 00872 int opts = 0; 00873 char *pysubtype = NULL; 00874 int subtype = PROP_NONE; 00875 PyObject *update_cb = NULL; 00876 00877 if (!PyArg_ParseTupleAndKeywords(args, kw, 00878 "s#|sssiO!sO:StringProperty", 00879 (char **)kwlist, &id, &id_len, 00880 &name, &description, &def, 00881 &maxlen, &PySet_Type, &pyopts, &pysubtype, 00882 &update_cb)) 00883 { 00884 return NULL; 00885 } 00886 00887 BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items) 00888 00889 if (bpy_prop_callback_check(update_cb, 2) == -1) { 00890 return NULL; 00891 } 00892 00893 prop = RNA_def_property(srna, id, PROP_STRING, subtype); 00894 if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */ 00895 if (def) RNA_def_property_string_default(prop, def); 00896 RNA_def_property_ui_text(prop, name ? name : id, description); 00897 00898 if (pyopts) { 00899 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 00900 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 00901 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 00902 } 00903 bpy_prop_callback_assign(prop, update_cb); 00904 RNA_def_property_duplicate_pointers(srna, prop); 00905 } 00906 Py_RETURN_NONE; 00907 } 00908 00909 #if 0 00910 /* copies orig to buf, then sets orig to buf, returns copy length */ 00911 static size_t strswapbufcpy(char *buf, const char **orig) 00912 { 00913 const char *src = *orig; 00914 char *dst = buf; 00915 size_t i = 0; 00916 *orig = buf; 00917 while ((*dst = *src)) { dst++; src++; i++; } 00918 return i + 1; /* include '\0' */ 00919 } 00920 #endif 00921 00922 static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) 00923 { 00924 EnumPropertyItem *items; 00925 PyObject *item; 00926 const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); 00927 Py_ssize_t totbuf = 0; 00928 int i; 00929 short def_used = 0; 00930 const char *def_cmp = NULL; 00931 00932 if (is_enum_flag) { 00933 if (seq_len > RNA_ENUM_BITFLAG_SIZE) { 00934 PyErr_SetString(PyExc_TypeError, 00935 "EnumProperty(...): maximum " 00936 STRINGIFY(RNA_ENUM_BITFLAG_SIZE) 00937 " members for a ENUM_FLAG type property"); 00938 return NULL; 00939 } 00940 if (def && !PySet_Check(def)) { 00941 PyErr_Format(PyExc_TypeError, 00942 "EnumProperty(...): default option must be a 'set' " 00943 "type when ENUM_FLAG is enabled, not a '%.200s'", 00944 Py_TYPE(def)->tp_name); 00945 return NULL; 00946 } 00947 } 00948 else { 00949 if (def) { 00950 def_cmp = _PyUnicode_AsString(def); 00951 if (def_cmp == NULL) { 00952 PyErr_Format(PyExc_TypeError, 00953 "EnumProperty(...): default option must be a 'str' " 00954 "type when ENUM_FLAG is disabled, not a '%.200s'", 00955 Py_TYPE(def)->tp_name); 00956 return NULL; 00957 } 00958 } 00959 } 00960 00961 /* blank value */ 00962 *defvalue = 0; 00963 00964 items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); 00965 00966 for (i = 0; i < seq_len; i++) { 00967 EnumPropertyItem tmp = {0, "", 0, "", ""}; 00968 Py_ssize_t item_size; 00969 Py_ssize_t id_str_size; 00970 Py_ssize_t name_str_size; 00971 Py_ssize_t desc_str_size; 00972 00973 item = PySequence_Fast_GET_ITEM(seq_fast, i); 00974 00975 if ( (PyTuple_CheckExact(item)) && 00976 (item_size = PyTuple_GET_SIZE(item)) && 00977 (item_size == 3 || item_size == 4) && 00978 (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && 00979 (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && 00980 (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && 00981 (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) /* TODO, number isnt ensured to be unique from the script author */ 00982 { 00983 if (is_enum_flag) { 00984 if (item_size < 4) { 00985 tmp.value = 1 << i; 00986 } 00987 00988 if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { 00989 *defvalue |= tmp.value; 00990 def_used++; 00991 } 00992 } 00993 else { 00994 if (item_size < 4) { 00995 tmp.value = i; 00996 } 00997 00998 if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) { 00999 *defvalue = tmp.value; 01000 def_used++; /* only ever 1 */ 01001 } 01002 } 01003 01004 items[i] = tmp; 01005 01006 /* calculate combine string length */ 01007 totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */ 01008 } 01009 else { 01010 MEM_freeN(items); 01011 PyErr_SetString(PyExc_TypeError, 01012 "EnumProperty(...): expected an tuple containing " 01013 "(identifier, name description) and optionally a " 01014 "unique number"); 01015 return NULL; 01016 } 01017 01018 } 01019 01020 if (is_enum_flag) { 01021 /* strict check that all set members were used */ 01022 if (def && def_used != PySet_GET_SIZE(def)) { 01023 MEM_freeN(items); 01024 01025 PyErr_Format(PyExc_TypeError, 01026 "EnumProperty(..., default={...}): set has %d unused member(s)", 01027 PySet_GET_SIZE(def) - def_used); 01028 return NULL; 01029 } 01030 } 01031 else { 01032 if (def && def_used == 0) { 01033 MEM_freeN(items); 01034 01035 PyErr_Format(PyExc_TypeError, 01036 "EnumProperty(..., default=\'%s\'): not found in enum members", 01037 def_cmp); 01038 return NULL; 01039 } 01040 } 01041 01042 /* disabled duplicating strings because the array can still be freed and 01043 * the strings from it referenced, for now we can't support dynamically 01044 * created strings from python. */ 01045 #if 0 01046 /* this would all work perfectly _but_ the python strings may be freed 01047 * immediately after use, so we need to duplicate them, ugh. 01048 * annoying because it works most of the time without this. */ 01049 { 01050 EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), 01051 "enum_items_from_py2"); 01052 EnumPropertyItem *items_ptr = items_dup; 01053 char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1)); 01054 memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1)); 01055 for (i = 0; i < seq_len; i++, items_ptr++) { 01056 buf += strswapbufcpy(buf, &items_ptr->identifier); 01057 buf += strswapbufcpy(buf, &items_ptr->name); 01058 buf += strswapbufcpy(buf, &items_ptr->description); 01059 } 01060 MEM_freeN(items); 01061 items = items_dup; 01062 } 01063 /* end string duplication */ 01064 #endif 01065 01066 return items; 01067 } 01068 01069 static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) 01070 { 01071 PyGILState_STATE gilstate; 01072 01073 PyObject *py_func = RNA_property_enum_py_data_get(prop); 01074 PyObject *self = NULL; 01075 PyObject *args; 01076 PyObject *items; /* returned from the function call */ 01077 01078 EnumPropertyItem *eitems = NULL; 01079 int err = 0; 01080 01081 bpy_context_set(C, &gilstate); 01082 01083 args = PyTuple_New(2); 01084 self = pyrna_struct_as_instance(ptr); 01085 PyTuple_SET_ITEM(args, 0, self); 01086 01087 /* now get the context */ 01088 PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); 01089 Py_INCREF(bpy_context_module); 01090 01091 items = PyObject_CallObject(py_func, args); 01092 01093 Py_DECREF(args); 01094 01095 if (items == NULL) { 01096 err = -1; 01097 } 01098 else { 01099 PyObject *items_fast; 01100 int defvalue_dummy = 0; 01101 01102 if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " 01103 "return value from the callback was not a sequence"))) 01104 { 01105 err = -1; 01106 } 01107 else { 01108 eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0); 01109 01110 Py_DECREF(items_fast); 01111 01112 if (!eitems) { 01113 err = -1; 01114 } 01115 } 01116 01117 Py_DECREF(items); 01118 } 01119 01120 if (err != -1) { /* worked */ 01121 *free = 1; 01122 } 01123 else { 01124 printf_func_error(py_func); 01125 01126 eitems = DummyRNA_NULL_items; 01127 } 01128 01129 01130 bpy_context_clear(C, &gilstate); 01131 return eitems; 01132 } 01133 01134 PyDoc_STRVAR(BPy_EnumProperty_doc, 01135 ".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'}, update=None)\n" 01136 "\n" 01137 " Returns a new enumerator property definition.\n" 01138 "\n" 01139 BPY_PROPDEF_NAME_DOC 01140 BPY_PROPDEF_DESC_DOC 01141 " :arg default: The default value for this enum, A string when *ENUM_FLAG*\n" 01142 " is disabled otherwise a set which may only contain string identifiers\n" 01143 " used in *items*.\n" 01144 " :type default: string or set\n" 01145 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG'].\n" 01146 " :type options: set\n" 01147 " :arg items: sequence of enum items formatted:\n" 01148 " [(identifier, name, description, number), ...] where the identifier is used\n" 01149 " for python access and other values are used for the interface.\n" 01150 " Note the item is optional.\n" 01151 " For dynamic values a callback can be passed which returns a list in\n" 01152 " the same format as the static list.\n" 01153 " This function must take 2 arguments (self, context)\n" 01154 " :type items: sequence of string triplets or a function\n" 01155 BPY_PROPDEF_UPDATE_DOC 01156 ); 01157 static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) 01158 { 01159 StructRNA *srna; 01160 01161 BPY_PROPDEF_HEAD(EnumProperty) 01162 01163 if (srna) { 01164 static const char *kwlist[] = {"attr", "items", "name", "description", "default", 01165 "options", "update", NULL}; 01166 const char *id = NULL, *name = NULL, *description = ""; 01167 PyObject *def = NULL; 01168 int id_len; 01169 int defvalue = 0; 01170 PyObject *items, *items_fast; 01171 EnumPropertyItem *eitems; 01172 PropertyRNA *prop; 01173 PyObject *pyopts = NULL; 01174 int opts = 0; 01175 short is_itemf = FALSE; 01176 PyObject *update_cb = NULL; 01177 01178 if (!PyArg_ParseTupleAndKeywords(args, kw, 01179 "s#O|ssOO!O:EnumProperty", 01180 (char **)kwlist, &id, &id_len, 01181 &items, &name, &description, 01182 &def, &PySet_Type, &pyopts, 01183 &update_cb)) 01184 { 01185 return NULL; 01186 } 01187 01188 BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items) 01189 01190 if (bpy_prop_callback_check(update_cb, 2) == -1) { 01191 return NULL; 01192 } 01193 01194 /* items can be a list or a callable */ 01195 if (PyFunction_Check(items)) { /* dont use PyCallable_Check because we need the function code for errors */ 01196 PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items); 01197 if (f_code->co_argcount != 2) { 01198 PyErr_Format(PyExc_ValueError, 01199 "EnumProperty(...): expected 'items' function to take 2 arguments, not %d", 01200 f_code->co_argcount); 01201 return NULL; 01202 } 01203 01204 if (def) { 01205 /* note, using type error here is odd but python does this for invalid arguments */ 01206 PyErr_SetString(PyExc_TypeError, 01207 "EnumProperty(...): 'default' can't be set when 'items' is a function"); 01208 return NULL; 01209 } 01210 01211 is_itemf = TRUE; 01212 eitems = DummyRNA_NULL_items; 01213 } 01214 else { 01215 if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " 01216 "expected a sequence of tuples for the enum items or a function"))) 01217 { 01218 return NULL; 01219 } 01220 01221 eitems = enum_items_from_py(items_fast, def, &defvalue, (opts & PROP_ENUM_FLAG) != 0); 01222 01223 Py_DECREF(items_fast); 01224 01225 if (!eitems) { 01226 return NULL; 01227 } 01228 } 01229 01230 if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description); 01231 else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); 01232 01233 if (is_itemf) { 01234 RNA_def_enum_funcs(prop, bpy_props_enum_itemf); 01235 RNA_def_enum_py_data(prop, (void *)items); 01236 01237 /* watch out!, if a user is tricky they can probably crash blender 01238 * if they manage to free the callback, take care! */ 01239 /* Py_INCREF(items); */ 01240 } 01241 01242 if (pyopts) { 01243 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 01244 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 01245 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 01246 } 01247 bpy_prop_callback_assign(prop, update_cb); 01248 RNA_def_property_duplicate_pointers(srna, prop); 01249 01250 if (is_itemf == FALSE) { 01251 MEM_freeN(eitems); 01252 } 01253 } 01254 Py_RETURN_NONE; 01255 } 01256 01257 static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix) 01258 { 01259 StructRNA *srna; 01260 01261 srna = srna_from_self(value, ""); 01262 if (!srna) { 01263 if (PyErr_Occurred()) { 01264 PyObject *msg = PyC_ExceptionBuffer(); 01265 const char *msg_char = _PyUnicode_AsString(msg); 01266 PyErr_Format(PyExc_TypeError, 01267 "%.200s expected an RNA type derived from PropertyGroup, failed with: %s", 01268 error_prefix, msg_char); 01269 Py_DECREF(msg); 01270 } 01271 else { 01272 PyErr_Format(PyExc_TypeError, 01273 "%.200s expected an RNA type derived from PropertyGroup, failed with type '%s'", 01274 error_prefix, Py_TYPE(value)->tp_name); 01275 } 01276 return NULL; 01277 } 01278 01279 if (!RNA_struct_is_a(srna, &RNA_PropertyGroup)) { 01280 PyErr_Format(PyExc_TypeError, 01281 "%.200s expected an RNA type derived from PropertyGroup", 01282 error_prefix); 01283 return NULL; 01284 } 01285 01286 return srna; 01287 } 01288 01289 PyDoc_STRVAR(BPy_PointerProperty_doc, 01290 ".. function:: PointerProperty(type=\"\", description=\"\", options={'ANIMATABLE'}, update=None)\n" 01291 "\n" 01292 " Returns a new pointer property definition.\n" 01293 "\n" 01294 " :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n" 01295 " :type type: class\n" 01296 BPY_PROPDEF_NAME_DOC 01297 BPY_PROPDEF_DESC_DOC 01298 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 01299 " :type options: set\n" 01300 BPY_PROPDEF_UPDATE_DOC 01301 ); 01302 static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) 01303 { 01304 StructRNA *srna; 01305 01306 BPY_PROPDEF_HEAD(PointerProperty) 01307 01308 if (srna) { 01309 static const char *kwlist[] = {"attr", "type", "name", "description", "options", "update", NULL}; 01310 const char *id = NULL, *name = NULL, *description = ""; 01311 int id_len; 01312 PropertyRNA *prop; 01313 StructRNA *ptype; 01314 PyObject *type = Py_None; 01315 PyObject *pyopts = NULL; 01316 int opts = 0; 01317 PyObject *update_cb = NULL; 01318 01319 if (!PyArg_ParseTupleAndKeywords(args, kw, 01320 "s#O|ssO!O:PointerProperty", 01321 (char **)kwlist, &id, &id_len, 01322 &type, &name, &description, 01323 &PySet_Type, &pyopts, 01324 &update_cb)) 01325 { 01326 return NULL; 01327 } 01328 01329 BPY_PROPDEF_CHECK(PointerProperty, property_flag_items) 01330 01331 ptype = pointer_type_from_py(type, "PointerProperty(...):"); 01332 if (!ptype) 01333 return NULL; 01334 01335 if (bpy_prop_callback_check(update_cb, 2) == -1) { 01336 return NULL; 01337 } 01338 01339 prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description); 01340 if (pyopts) { 01341 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 01342 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 01343 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 01344 } 01345 bpy_prop_callback_assign(prop, update_cb); 01346 RNA_def_property_duplicate_pointers(srna, prop); 01347 } 01348 Py_RETURN_NONE; 01349 } 01350 01351 PyDoc_STRVAR(BPy_CollectionProperty_doc, 01352 ".. function:: CollectionProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n" 01353 "\n" 01354 " Returns a new collection property definition.\n" 01355 "\n" 01356 " :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n" 01357 " :type type: class\n" 01358 BPY_PROPDEF_NAME_DOC 01359 BPY_PROPDEF_DESC_DOC 01360 " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n" 01361 " :type options: set\n" 01362 ); 01363 static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) 01364 { 01365 StructRNA *srna; 01366 01367 BPY_PROPDEF_HEAD(CollectionProperty) 01368 01369 if (srna) { 01370 static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL}; 01371 const char *id = NULL, *name = NULL, *description = ""; 01372 int id_len; 01373 PropertyRNA *prop; 01374 StructRNA *ptype; 01375 PyObject *type = Py_None; 01376 PyObject *pyopts = NULL; 01377 int opts = 0; 01378 01379 if (!PyArg_ParseTupleAndKeywords(args, kw, 01380 "s#O|ssO!:CollectionProperty", 01381 (char **)kwlist, &id, &id_len, 01382 &type, &name, &description, 01383 &PySet_Type, &pyopts)) 01384 { 01385 return NULL; 01386 } 01387 01388 BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items) 01389 01390 ptype = pointer_type_from_py(type, "CollectionProperty(...):"); 01391 if (!ptype) 01392 return NULL; 01393 01394 prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description); 01395 if (pyopts) { 01396 if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); 01397 if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); 01398 if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); 01399 } 01400 RNA_def_property_duplicate_pointers(srna, prop); 01401 } 01402 Py_RETURN_NONE; 01403 } 01404 01405 PyDoc_STRVAR(BPy_RemoveProperty_doc, 01406 ".. function:: RemoveProperty(attr)\n" 01407 "\n" 01408 " Removes a dynamically defined property.\n" 01409 "\n" 01410 " :arg attr: Property name.\n" 01411 " :type attr: string\n" 01412 ); 01413 static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw) 01414 { 01415 StructRNA *srna; 01416 01417 if (PyTuple_GET_SIZE(args) == 1) { 01418 PyObject *ret; 01419 self = PyTuple_GET_ITEM(args, 0); 01420 args = PyTuple_New(0); 01421 ret = BPy_RemoveProperty(self, args, kw); 01422 Py_DECREF(args); 01423 return ret; 01424 } 01425 else if (PyTuple_GET_SIZE(args) > 1) { 01426 PyErr_SetString(PyExc_ValueError, "all args must be keywords"); 01427 return NULL; 01428 } 01429 01430 srna = srna_from_self(self, "RemoveProperty(...):"); 01431 if (srna == NULL && PyErr_Occurred()) { 01432 return NULL; /* self's type was compatible but error getting the srna */ 01433 } 01434 else if (srna == NULL) { 01435 PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type"); 01436 return NULL; 01437 } 01438 else { 01439 static const char *kwlist[] = {"attr", NULL}; 01440 01441 char *id = NULL; 01442 01443 if (!PyArg_ParseTupleAndKeywords(args, kw, 01444 "s:RemoveProperty", 01445 (char **)kwlist, &id)) 01446 { 01447 return NULL; 01448 } 01449 01450 if (RNA_def_property_free_identifier(srna, id) != 1) { 01451 PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id); 01452 return NULL; 01453 } 01454 } 01455 Py_RETURN_NONE; 01456 } 01457 01458 static struct PyMethodDef props_methods[] = { 01459 {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc}, 01460 {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc}, 01461 {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc}, 01462 {"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntVectorProperty_doc}, 01463 {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatProperty_doc}, 01464 {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatVectorProperty_doc}, 01465 {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, BPy_StringProperty_doc}, 01466 {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc}, 01467 {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc}, 01468 {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc}, 01469 01470 {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc}, 01471 {NULL, NULL, 0, NULL} 01472 }; 01473 01474 static struct PyModuleDef props_module = { 01475 PyModuleDef_HEAD_INIT, 01476 "bpy.props", 01477 "This module defines properties to extend blenders internal data, the result of these functions" 01478 " is used to assign properties to classes registered with blender and can't be used directly.", 01479 -1,/* multiple "initialization" just copies the module dict. */ 01480 props_methods, 01481 NULL, NULL, NULL, NULL 01482 }; 01483 01484 PyObject *BPY_rna_props(void) 01485 { 01486 PyObject *submodule; 01487 PyObject *submodule_dict; 01488 01489 submodule = PyModule_Create(&props_module); 01490 PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule); 01491 01492 /* INCREF since its its assumed that all these functions return the 01493 * module with a new ref like PyDict_New, since they are passed to 01494 * PyModule_AddObject which steals a ref */ 01495 Py_INCREF(submodule); 01496 01497 /* api needs the PyObjects internally */ 01498 submodule_dict = PyModule_GetDict(submodule); 01499 01500 #define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name) 01501 01502 ASSIGN_STATIC(BoolProperty); 01503 ASSIGN_STATIC(BoolVectorProperty); 01504 ASSIGN_STATIC(IntProperty); 01505 ASSIGN_STATIC(IntVectorProperty); 01506 ASSIGN_STATIC(FloatProperty); 01507 ASSIGN_STATIC(FloatVectorProperty); 01508 ASSIGN_STATIC(StringProperty); 01509 ASSIGN_STATIC(EnumProperty); 01510 ASSIGN_STATIC(PointerProperty); 01511 ASSIGN_STATIC(CollectionProperty); 01512 ASSIGN_STATIC(RemoveProperty); 01513 01514 return submodule; 01515 }