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