9ae7507a72a066909e39ae1c149c9b4aec6eb089
[blender.git] / source / blender / python / intern / bpy_props.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include "bpy_props.h"
26 #include "bpy_rna.h"
27 #include "bpy_util.h"
28
29 #include "BKE_utildefines.h"
30
31 #include "RNA_define.h" /* for defining our own rna */
32 #include "RNA_enum_types.h"
33
34 #include "MEM_guardedalloc.h"
35
36 #include "../generic/py_capi_utils.h"
37
38 EnumPropertyItem property_flag_items[] = {
39         {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
40         {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
41         {0, NULL, 0, NULL, NULL}};
42
43 /* subtypes */
44 EnumPropertyItem property_subtype_string_items[] = {
45         {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
46         {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
47         {PROP_FILENAME, "FILENAME", 0, "Filename", ""},
48
49         {PROP_NONE, "NONE", 0, "None", ""},
50         {0, NULL, 0, NULL, NULL}};
51
52 EnumPropertyItem property_subtype_number_items[] = {
53         {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""},
54         {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
55         {PROP_FACTOR, "FACTOR", 0, "Factor", ""},
56         {PROP_ANGLE, "ANGLE", 0, "Angle", ""},
57         {PROP_TIME, "TIME", 0, "Time", ""},
58         {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
59
60         {PROP_NONE, "NONE", 0, "None", ""},
61         {0, NULL, 0, NULL, NULL}};
62
63 EnumPropertyItem property_subtype_array_items[] = {
64         {PROP_COLOR, "COLOR", 0, "Color", ""},
65         {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
66         {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
67         {PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""},
68         {PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
69         {PROP_MATRIX, "MATRIX", 0, "Matrix", ""},
70         {PROP_EULER, "EULER", 0, "Euler", ""},
71         {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
72         {PROP_AXISANGLE, "AXISANGLE", 0, "Axis Angle", ""},
73         {PROP_XYZ, "XYZ", 0, "XYZ", ""},
74         {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Color Gamma", ""},
75         {PROP_LAYER, "LAYER", 0, "Layer", ""},
76
77         {PROP_NONE, "NONE", 0, "None", ""},
78         {0, NULL, 0, NULL, NULL}};
79
80 /* operators use this so it can store the args given but defer running
81  * it until the operator runs where these values are used to setup the
82  * default args for that operator instance */
83 static PyObject *bpy_prop_deferred_return(void *func, PyObject *kw)
84 {
85         PyObject *ret = PyTuple_New(2);
86         PyTuple_SET_ITEM(ret, 0, PyCapsule_New(func, NULL, NULL));
87         if(kw==NULL)    kw= PyDict_New();
88         else                    Py_INCREF(kw);
89         PyTuple_SET_ITEM(ret, 1, kw);
90         return ret;
91 }
92
93 #if 0
94 static int bpy_struct_id_used(StructRNA *srna, char *identifier)
95 {
96         PointerRNA ptr;
97         RNA_pointer_create(NULL, srna, NULL, &ptr);
98         return (RNA_struct_find_property(&ptr, identifier) != NULL);
99 }
100 #endif
101
102
103 /* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
104  * This isnt incorrect since its a python object - but be careful */
105 char BPy_BoolProperty_doc[] =
106 ".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE')\n"
107 "\n"
108 "   Returns a new boolean property definition.\n"
109 "\n"
110 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
111 "   :type options: set\n"
112 "   :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
113 "   :type subtype: string";
114
115 PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
116 {
117         StructRNA *srna;
118
119         if (PyTuple_GET_SIZE(args) > 0) {
120                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
121                 return NULL;
122         }
123
124         srna= srna_from_self(self, "BoolProperty(...):");
125         if(srna==NULL && PyErr_Occurred()) {
126                 return NULL; /* self's type was compatible but error getting the srna */
127         }
128         else if(srna) {
129                 static char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", NULL};
130                 char *id=NULL, *name="", *description="";
131                 int def=0;
132                 PropertyRNA *prop;
133                 PyObject *pyopts= NULL;
134                 int opts=0;
135                 char *pysubtype= NULL;
136                 int subtype= PROP_NONE;
137
138                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiO!s:BoolProperty", (char **)kwlist, &id, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype))
139                         return NULL;
140
141                 if(RNA_def_property_free_identifier(srna, id) == -1) {
142                         PyErr_Format(PyExc_TypeError, "BoolProperty(): '%s' is defined as a non-dynamic type.", id);
143                         return NULL;
144                 }
145
146                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "BoolProperty(options={...}):"))
147                         return NULL;
148
149                 if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) {
150                         PyErr_Format(PyExc_TypeError, "BoolProperty(subtype='%s'): invalid subtype.", pysubtype);
151                         return NULL;
152                 }
153
154                 // prop= RNA_def_boolean(srna, id, def, name, description);
155                 prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
156                 RNA_def_property_boolean_default(prop, def);
157                 RNA_def_property_ui_text(prop, name, description);
158
159                 if(pyopts) {
160                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
161                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
162                 }
163                 RNA_def_property_duplicate_pointers(prop);
164                 Py_RETURN_NONE;
165         }
166         else { /* operators defer running this function */
167                 return bpy_prop_deferred_return((void *)BPy_BoolProperty, kw);
168         }
169 }
170
171 char BPy_BoolVectorProperty_doc[] =
172 ".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
173 "\n"
174 "   Returns a new vector boolean property definition.\n"
175 "\n"
176 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
177 "   :type options: set\n"
178 "   :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
179 "   :type subtype: string";
180 PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
181 {
182         StructRNA *srna;
183
184         if (PyTuple_GET_SIZE(args) > 0) {
185                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
186                 return NULL;
187         }
188
189         srna= srna_from_self(self, "BoolVectorProperty(...):");
190         if(srna==NULL && PyErr_Occurred()) {
191                 return NULL; /* self's type was compatible but error getting the srna */
192         }
193         else if(srna) {
194                 static const char *kwlist[] = {"attr", "name", "description", "default", "options", "subtype", "size", NULL};
195                 char *id=NULL, *name="", *description="";
196                 int def[PYRNA_STACK_ARRAY]={0};
197                 int size=3;
198                 PropertyRNA *prop;
199                 PyObject *pydef= NULL;
200                 PyObject *pyopts= NULL;
201                 int opts=0;
202                 char *pysubtype= NULL;
203                 int subtype= PROP_NONE;
204
205                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOO!si:BoolVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size))
206                         return NULL;
207
208                 if(RNA_def_property_free_identifier(srna, id) == -1) {
209                         PyErr_Format(PyExc_TypeError, "BoolVectorProperty(): '%s' is defined as a non-dynamic type.", id);
210                         return NULL;
211                 }
212
213                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "BoolVectorProperty(options={...}):"))
214                         return NULL;
215
216                 if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) {
217                         PyErr_Format(PyExc_TypeError, "BoolVectorProperty(subtype='%s'): invalid subtype.", pysubtype);
218                         return NULL;
219                 }
220
221                 if(size < 1 || size > PYRNA_STACK_ARRAY) {
222                         PyErr_Format(PyExc_TypeError, "BoolVectorProperty(size=%d): size must be between 0 and %d.", size, PYRNA_STACK_ARRAY);
223                         return NULL;
224                 }
225
226                 if(pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, "BoolVectorProperty(default=sequence)") < 0)
227                         return NULL;
228
229                 // prop= RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name, description);
230                 prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
231                 RNA_def_property_array(prop, size);
232                 if(pydef) RNA_def_property_boolean_array_default(prop, def);
233                 RNA_def_property_ui_text(prop, name, description);
234
235                 if(pyopts) {
236                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
237                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
238                 }
239                 RNA_def_property_duplicate_pointers(prop);
240                 Py_RETURN_NONE;
241         }
242         else { /* operators defer running this function */
243                 return bpy_prop_deferred_return((void *)BPy_BoolVectorProperty, kw);
244         }
245 }
246
247 char BPy_IntProperty_doc[] =
248 ".. 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')\n"
249 "\n"
250 "   Returns a new int property definition.\n"
251 "\n"
252 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
253 "   :type options: set\n"
254 "   :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
255 "   :type subtype: string";
256 PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
257 {
258         StructRNA *srna;
259
260         if (PyTuple_GET_SIZE(args) > 0) {
261                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
262                 return NULL;
263         }
264
265         srna= srna_from_self(self, "IntProperty(...):");
266         if(srna==NULL && PyErr_Occurred()) {
267                 return NULL; /* self's type was compatible but error getting the srna */
268         }
269         else if(srna) {
270                 static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", NULL};
271                 char *id=NULL, *name="", *description="";
272                 int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def=0;
273                 PropertyRNA *prop;
274                 PyObject *pyopts= NULL;
275                 int opts=0;
276                 char *pysubtype= NULL;
277                 int subtype= PROP_NONE;
278
279                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiiiiO!s:IntProperty", (char **)kwlist, &id, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype))
280                         return NULL;
281
282                 if(RNA_def_property_free_identifier(srna, id) == -1) {
283                         PyErr_Format(PyExc_TypeError, "IntProperty(): '%s' is defined as a non-dynamic type.", id);
284                         return NULL;
285                 }
286
287                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "IntProperty(options={...}):"))
288                         return NULL;
289
290                 if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) {
291                         PyErr_Format(PyExc_TypeError, "IntProperty(subtype='%s'): invalid subtype.", pysubtype);
292                         return NULL;
293                 }
294
295                 prop= RNA_def_property(srna, id, PROP_INT, subtype);
296                 RNA_def_property_int_default(prop, def);
297                 RNA_def_property_range(prop, min, max);
298                 RNA_def_property_ui_text(prop, name, description);
299                 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
300
301                 if(pyopts) {
302                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
303                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
304                 }
305                 RNA_def_property_duplicate_pointers(prop);
306                 Py_RETURN_NONE;
307         }
308         else { /* operators defer running this function */
309                 return bpy_prop_deferred_return((void *)BPy_IntProperty, kw);
310         }
311 }
312
313 char BPy_IntVectorProperty_doc[] =
314 ".. 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)\n"
315 "\n"
316 "   Returns a new vector int property definition.\n"
317 "\n"
318 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
319 "   :type options: set\n"
320 "   :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
321 "   :type subtype: string";
322 PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
323 {
324         StructRNA *srna;
325
326         if (PyTuple_GET_SIZE(args) > 0) {
327                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
328                 return NULL;
329         }
330
331         srna= srna_from_self(self, "IntVectorProperty(...):");
332         if(srna==NULL && PyErr_Occurred()) {
333                 return NULL; /* self's type was compatible but error getting the srna */
334         }
335         else if(srna) {
336                 static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", NULL};
337                 char *id=NULL, *name="", *description="";
338                 int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0};
339                 int size=3;
340                 PropertyRNA *prop;
341                 PyObject *pydef= NULL;
342                 PyObject *pyopts= NULL;
343                 int opts=0;
344                 char *pysubtype= NULL;
345                 int subtype= PROP_NONE;
346
347                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOiiiiO!si:IntVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &PySet_Type, &pyopts, &pysubtype, &size))
348                         return NULL;
349
350                 if(RNA_def_property_free_identifier(srna, id) == -1) {
351                         PyErr_Format(PyExc_TypeError, "IntVectorProperty(): '%s' is defined as a non-dynamic type.", id);
352                         return NULL;
353                 }
354
355                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "IntVectorProperty(options={...}):"))
356                         return NULL;
357
358                 if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) {
359                         PyErr_Format(PyExc_TypeError, "IntVectorProperty(subtype='%s'): invalid subtype.", pysubtype);
360                         return NULL;
361                 }
362
363                 if(size < 1 || size > PYRNA_STACK_ARRAY) {
364                         PyErr_Format(PyExc_TypeError, "IntVectorProperty(size=%d): size must be between 0 and %d.", size, PYRNA_STACK_ARRAY);
365                         return NULL;
366                 }
367
368                 if(pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, "IntVectorProperty(default=sequence)") < 0)
369                         return NULL;
370
371                 prop= RNA_def_property(srna, id, PROP_INT, subtype);
372                 RNA_def_property_array(prop, size);
373                 if(pydef) RNA_def_property_int_array_default(prop, def);
374                 RNA_def_property_range(prop, min, max);
375                 RNA_def_property_ui_text(prop, name, description);
376                 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
377
378                 if(pyopts) {
379                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
380                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
381                 }
382                 RNA_def_property_duplicate_pointers(prop);
383                 Py_RETURN_NONE;
384         }
385         else { /* operators defer running this function */
386                 return bpy_prop_deferred_return((void *)BPy_IntVectorProperty, kw);
387         }
388 }
389
390
391 char BPy_FloatProperty_doc[] =
392 ".. 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')\n"
393 "\n"
394 "   Returns a new float property definition.\n"
395 "\n"
396 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
397 "   :type options: set\n"
398 "   :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
399 "   :type subtype: string\n"
400 "   :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n"
401 "   :type unit: string\n";
402 PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
403 {
404         StructRNA *srna;
405
406         if (PyTuple_GET_SIZE(args) > 0) {
407                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
408                 return NULL;
409         }
410
411         srna= srna_from_self(self, "FloatProperty(...):");
412         if(srna==NULL && PyErr_Occurred()) {
413                 return NULL; /* self's type was compatible but error getting the srna */
414         }
415         else if(srna) {
416                 static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", NULL};
417                 char *id=NULL, *name="", *description="";
418                 float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f;
419                 int precision= 2;
420                 PropertyRNA *prop;
421                 PyObject *pyopts= NULL;
422                 int opts=0;
423                 char *pysubtype= NULL;
424                 int subtype= PROP_NONE;
425                 char *pyunit= NULL;
426                 int unit= PROP_UNIT_NONE;
427
428                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssffffffiO!ss:FloatProperty", (char **)kwlist, &id, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit))
429                         return NULL;
430
431                 if(RNA_def_property_free_identifier(srna, id) == -1) {
432                         PyErr_Format(PyExc_TypeError, "FloatProperty(): '%s' is defined as a non-dynamic type.", id);
433                         return NULL;
434                 }
435
436                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "FloatProperty(options={...}):"))
437                         return NULL;
438
439                 if(pysubtype && RNA_enum_value_from_id(property_subtype_number_items, pysubtype, &subtype)==0) {
440                         PyErr_Format(PyExc_TypeError, "FloatProperty(subtype='%s'): invalid subtype.", pysubtype);
441                         return NULL;
442                 }
443
444                 if(pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) {
445                         PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit.");
446                         return NULL;
447                 }
448
449                 prop= RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
450                 RNA_def_property_float_default(prop, def);
451                 RNA_def_property_range(prop, min, max);
452                 RNA_def_property_ui_text(prop, name, description);
453                 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
454
455                 if(pyopts) {
456                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
457                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
458                 }
459                 RNA_def_property_duplicate_pointers(prop);
460                 Py_RETURN_NONE;
461         }
462         else { /* operators defer running this function */
463                 return bpy_prop_deferred_return((void *)BPy_FloatProperty, kw);
464         }
465 }
466
467 char BPy_FloatVectorProperty_doc[] =
468 ".. 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)\n"
469 "\n"
470 "   Returns a new vector float property definition.\n"
471 "\n"
472 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
473 "   :type options: set\n"
474 "   :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
475 "   :type subtype: string";
476 PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
477 {
478         StructRNA *srna;
479
480         if (PyTuple_GET_SIZE(args) > 0) {
481                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
482                 return NULL;
483         }
484
485         srna= srna_from_self(self, "FloatVectorProperty(...):");
486         if(srna==NULL && PyErr_Occurred()) {
487                 return NULL; /* self's type was compatible but error getting the srna */
488         }
489         else if(srna) {
490                 static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", NULL};
491                 char *id=NULL, *name="", *description="";
492                 float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f};
493                 int precision= 2, size=3;
494                 PropertyRNA *prop;
495                 PyObject *pydef= NULL;
496                 PyObject *pyopts= NULL;
497                 int opts=0;
498                 char *pysubtype= NULL;
499                 int subtype= PROP_NONE;
500
501                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssOfffffiO!si:FloatVectorProperty", (char **)kwlist, &id, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &size))
502                         return NULL;
503
504                 if(RNA_def_property_free_identifier(srna, id) == -1) {
505                         PyErr_Format(PyExc_TypeError, "FloatVectorProperty(): '%s' is defined as a non-dynamic type.", id);
506                         return NULL;
507                 }
508
509                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "FloatVectorProperty(options={...}):"))
510                         return NULL;
511
512                 if(pysubtype && RNA_enum_value_from_id(property_subtype_array_items, pysubtype, &subtype)==0) {
513                         PyErr_Format(PyExc_TypeError, "FloatVectorProperty(subtype='%s'): invalid subtype.", pysubtype);
514                         return NULL;
515                 }
516
517                 if(size < 1 || size > PYRNA_STACK_ARRAY) {
518                         PyErr_Format(PyExc_TypeError, "FloatVectorProperty(size=%d): size must be between 0 and %d.", size, PYRNA_STACK_ARRAY);
519                         return NULL;
520                 }
521
522                 if(pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, "FloatVectorProperty(default=sequence)") < 0)
523                         return NULL;
524
525                 prop= RNA_def_property(srna, id, PROP_FLOAT, subtype);
526                 RNA_def_property_array(prop, size);
527                 if(pydef) RNA_def_property_float_array_default(prop, def);
528                 RNA_def_property_range(prop, min, max);
529                 RNA_def_property_ui_text(prop, name, description);
530                 RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
531
532                 if(pyopts) {
533                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
534                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
535                 }
536                 RNA_def_property_duplicate_pointers(prop);
537                 Py_RETURN_NONE;
538         }
539         else { /* operators defer running this function */
540                 return bpy_prop_deferred_return((void *)BPy_FloatVectorProperty, kw);
541         }
542 }
543
544 char BPy_StringProperty_doc[] =
545 ".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE')\n"
546 "\n"
547 "   Returns a new string property definition.\n"
548 "\n"
549 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
550 "   :type options: set\n"
551 "   :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILENAME', 'NONE'].\n"
552 "   :type subtype: string";
553 PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
554 {
555         StructRNA *srna;
556
557         if (PyTuple_GET_SIZE(args) > 0) {
558                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
559                 return NULL;
560         }
561
562         srna= srna_from_self(self, "StringProperty(...):");
563         if(srna==NULL && PyErr_Occurred()) {
564                 return NULL; /* self's type was compatible but error getting the srna */
565         }
566         else if(srna) {
567                 static const char *kwlist[] = {"attr", "name", "description", "default", "maxlen", "options", "subtype", NULL};
568                 char *id=NULL, *name="", *description="", *def="";
569                 int maxlen=0;
570                 PropertyRNA *prop;
571                 PyObject *pyopts= NULL;
572                 int opts=0;
573                 char *pysubtype= NULL;
574                 int subtype= PROP_NONE;
575
576                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s|sssiO!s:StringProperty", (char **)kwlist, &id, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype))
577                         return NULL;
578
579                 if(RNA_def_property_free_identifier(srna, id) == -1) {
580                         PyErr_Format(PyExc_TypeError, "StringProperty(): '%s' is defined as a non-dynamic type.", id);
581                         return NULL;
582                 }
583
584                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "StringProperty(options={...}):"))
585                         return NULL;
586
587                 if(pysubtype && RNA_enum_value_from_id(property_subtype_string_items, pysubtype, &subtype)==0) {
588                         PyErr_Format(PyExc_TypeError, "StringProperty(subtype='%s'): invalid subtype.", pysubtype);
589                         return NULL;
590                 }
591
592                 prop= RNA_def_property(srna, id, PROP_STRING, subtype);
593                 if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
594                 if(def) RNA_def_property_string_default(prop, def);
595                 RNA_def_property_ui_text(prop, name, description);
596
597                 if(pyopts) {
598                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
599                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
600                 }
601                 RNA_def_property_duplicate_pointers(prop);
602                 Py_RETURN_NONE;
603         }
604         else { /* operators defer running this function */
605                 return bpy_prop_deferred_return((void *)BPy_StringProperty, kw);
606         }
607 }
608
609 static EnumPropertyItem *enum_items_from_py(PyObject *value, const char *def, int *defvalue)
610 {
611         EnumPropertyItem *items= NULL;
612         PyObject *item;
613         int seq_len, i, totitem= 0;
614
615         if(!PySequence_Check(value)) {
616                 PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
617                 return NULL;
618         }
619
620         seq_len = PySequence_Length(value);
621         for(i=0; i<seq_len; i++) {
622                 EnumPropertyItem tmp= {0, "", 0, "", ""};
623
624                 item= PySequence_GetItem(value, i);
625                 if(item==NULL || PyTuple_Check(item)==0) {
626                         PyErr_SetString(PyExc_TypeError, "expected a sequence of tuples for the enum items");
627                         if(items) MEM_freeN(items);
628                         Py_XDECREF(item);
629                         return NULL;
630                 }
631
632                 if(!PyArg_ParseTuple(item, "sss", &tmp.identifier, &tmp.name, &tmp.description)) {
633                         PyErr_SetString(PyExc_TypeError, "expected an identifier, name and description in the tuple");
634                         Py_DECREF(item);
635                         return NULL;
636                 }
637
638                 tmp.value= i;
639                 RNA_enum_item_add(&items, &totitem, &tmp);
640
641                 if(def[0] && strcmp(def, tmp.identifier) == 0)
642                         *defvalue= tmp.value;
643
644                 Py_DECREF(item);
645         }
646
647         if(!def[0])
648                 *defvalue= 0;
649
650         RNA_enum_item_end(&items, &totitem);
651
652         return items;
653 }
654
655 char BPy_EnumProperty_doc[] =
656 ".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
657 "\n"
658 "   Returns a new enumerator property definition.\n"
659 "\n"
660 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
661 "   :type options: set\n"
662 "   :arg items: The items that make up this enumerator.\n"
663 "   :type items: sequence of string triplets";
664 PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
665 {
666         StructRNA *srna;
667
668         if (PyTuple_GET_SIZE(args) > 0) {
669                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
670                 return NULL;
671         }
672
673         srna= srna_from_self(self, "EnumProperty(...):");
674         if(srna==NULL && PyErr_Occurred()) {
675                 return NULL; /* self's type was compatible but error getting the srna */
676         }
677         else if(srna) {
678                 static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", NULL};
679                 char *id=NULL, *name="", *description="", *def="";
680                 int defvalue=0;
681                 PyObject *items= Py_None;
682                 EnumPropertyItem *eitems;
683                 PropertyRNA *prop;
684                 PyObject *pyopts= NULL;
685                 int opts=0;
686
687                 if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|sssO!:EnumProperty", (char **)kwlist, &id, &items, &name, &description, &def, &PySet_Type, &pyopts))
688                         return NULL;
689
690                 if(RNA_def_property_free_identifier(srna, id) == -1) {
691                         PyErr_Format(PyExc_TypeError, "EnumProperty(): '%s' is defined as a non-dynamic type.", id);
692                         return NULL;
693                 }
694
695                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "EnumProperty(options={...}):"))
696                         return NULL;
697
698                 eitems= enum_items_from_py(items, def, &defvalue);
699                 if(!eitems)
700                         return NULL;
701
702                 prop= RNA_def_enum(srna, id, eitems, defvalue, name, description);
703                 if(pyopts) {
704                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
705                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
706                 }
707                 RNA_def_property_duplicate_pointers(prop);
708                 MEM_freeN(eitems);
709
710                 Py_RETURN_NONE;
711         }
712         else { /* operators defer running this function */
713                 return bpy_prop_deferred_return((void *)BPy_EnumProperty, kw);
714         }
715 }
716
717 static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
718 {
719         StructRNA *srna;
720
721         srna= srna_from_self(value, "BoolProperty(...):");
722         if(!srna) {
723
724                 PyObject *msg= PyC_ExceptionBuffer();
725                 char *msg_char= _PyUnicode_AsString(msg);
726                 PyErr_Format(PyExc_TypeError, "%.200s expected an RNA type derived from IDPropertyGroup, failed with: %s", error_prefix, msg_char);
727                 Py_DECREF(msg);
728                 return NULL;
729         }
730
731         if(!RNA_struct_is_a(srna, &RNA_IDPropertyGroup)) {
732                  PyErr_Format(PyExc_SystemError, "%.200s expected an RNA type derived from IDPropertyGroup", error_prefix);
733                 return NULL;
734         }
735
736         return srna;
737 }
738
739 char BPy_PointerProperty_doc[] =
740 ".. function:: PointerProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
741 "\n"
742 "   Returns a new pointer property definition.\n"
743 "\n"
744 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
745 "   :type options: set\n"
746 "   :arg type: Dynamic type from :mod:`bpy.types`.\n"
747 "   :type type: class";
748 PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
749 {
750         StructRNA *srna;
751
752         if (PyTuple_GET_SIZE(args) > 0) {
753                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
754                 return NULL;
755         }
756
757         srna= srna_from_self(self, "PointerProperty(...):");
758         if(srna==NULL && PyErr_Occurred()) {
759                 return NULL; /* self's type was compatible but error getting the srna */
760         }
761         else if(srna) {
762                 static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
763                 char *id=NULL, *name="", *description="";
764                 PropertyRNA *prop;
765                 StructRNA *ptype;
766                 PyObject *type= Py_None;
767                 PyObject *pyopts= NULL;
768                 int opts=0;
769
770                 if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ssO!:PointerProperty", (char **)kwlist, &id, &type, &name, &description, &PySet_Type, &pyopts))
771                         return NULL;
772
773                 if(RNA_def_property_free_identifier(srna, id) == -1) {
774                         PyErr_Format(PyExc_TypeError, "PointerProperty(): '%s' is defined as a non-dynamic type.", id);
775                         return NULL;
776                 }
777
778                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "PointerProperty(options={...}):"))
779                         return NULL;
780
781                 ptype= pointer_type_from_py(type, "PointerProperty(...):");
782                 if(!ptype)
783                         return NULL;
784
785                 prop= RNA_def_pointer_runtime(srna, id, ptype, name, description);
786                 if(pyopts) {
787                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
788                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
789                 }
790                 RNA_def_property_duplicate_pointers(prop);
791                 Py_RETURN_NONE;
792         }
793         else { /* operators defer running this function */
794                 return bpy_prop_deferred_return((void *)BPy_PointerProperty, kw);
795         }
796         return NULL;
797 }
798
799 char BPy_CollectionProperty_doc[] =
800 ".. function:: CollectionProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
801 "\n"
802 "   Returns a new collection property definition.\n"
803 "\n"
804 "   :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
805 "   :type options: set\n"
806 "   :arg type: Dynamic type from :mod:`bpy.types`.\n"
807 "   :type type: class";
808 PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
809 {
810         StructRNA *srna;
811
812         if (PyTuple_GET_SIZE(args) > 0) {
813                  PyErr_SetString(PyExc_ValueError, "all args must be keywords");
814                 return NULL;
815         }
816
817         srna= srna_from_self(self, "CollectionProperty(...):");
818         if(srna==NULL && PyErr_Occurred()) {
819                 return NULL; /* self's type was compatible but error getting the srna */
820         }
821         else if(srna) {
822                 static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
823                 char *id=NULL, *name="", *description="";
824                 PropertyRNA *prop;
825                 StructRNA *ptype;
826                 PyObject *type= Py_None;
827                 PyObject *pyopts= NULL;
828                 int opts=0;
829
830                 if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|ssO!:CollectionProperty", (char **)kwlist, &id, &type, &name, &description, &PySet_Type, &pyopts))
831                         return NULL;
832
833                 if(RNA_def_property_free_identifier(srna, id) == -1) {
834                         PyErr_Format(PyExc_TypeError, "CollectionProperty(): '%s' is defined as a non-dynamic type.", id);
835                         return NULL;
836                 }
837
838                 if(pyopts && pyrna_set_to_enum_bitfield(property_flag_items, pyopts, &opts, "CollectionProperty(options={...}):"))
839                         return NULL;
840
841                 ptype= pointer_type_from_py(type, "CollectionProperty(...):");
842                 if(!ptype)
843                         return NULL;
844
845                 prop= RNA_def_collection_runtime(srna, id, ptype, name, description);
846                 if(pyopts) {
847                         if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
848                         if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
849                 }
850                 RNA_def_property_duplicate_pointers(prop);
851                 Py_RETURN_NONE;
852         }
853         else { /* operators defer running this function */
854                 return bpy_prop_deferred_return((void *)BPy_CollectionProperty, kw);
855         }
856         return NULL;
857 }
858
859 char BPy_RemoveProperty_doc[] =
860 ".. function:: RemoveProperty(attr)\n"
861 "\n"
862 "   Removes a dynamically defined property.\n"
863 "\n"
864 "   :arg attr: Property name.\n"
865 "   :type attr: string";
866 PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
867 {
868         StructRNA *srna;
869
870         srna= srna_from_self(self, "RemoveProperty(...):");
871         if(srna==NULL && PyErr_Occurred()) {
872                 return NULL; /* self's type was compatible but error getting the srna */
873         }
874         else if(srna==NULL) {
875                 PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type.");
876                 return NULL;
877         }
878         else {
879                 static const char *kwlist[] = {"attr", NULL};
880                 
881                 char *id=NULL;
882
883                 if (!PyArg_ParseTupleAndKeywords(args, kw, "s:RemoveProperty", (char **)kwlist, &id))
884                         return NULL;
885
886                 if(RNA_def_property_free_identifier(srna, id) != 1) {
887                         PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property.", id);
888                         return NULL;
889                 }
890                 
891                 Py_RETURN_NONE;
892         }
893 }
894
895 static struct PyMethodDef props_methods[] = {
896         {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc},
897         {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc},
898         {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc},
899         {"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntVectorProperty_doc},
900         {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatProperty_doc},
901         {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatVectorProperty_doc},
902         {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, BPy_StringProperty_doc},
903         {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc},
904         {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc},
905         {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc},
906
907         /* only useful as a bpy_struct method */
908         /* {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc}, */
909         {NULL, NULL, 0, NULL}
910 };
911
912 static struct PyModuleDef props_module = {
913         PyModuleDef_HEAD_INIT,
914         "bpy.props",
915         "This module defines properties to extend blenders internal data, the result of these functions"
916         " is used to assign properties to classes registered with blender and can't be used directly.",
917         -1,/* multiple "initialization" just copies the module dict. */
918         props_methods,
919         NULL, NULL, NULL, NULL
920 };
921
922 PyObject *BPY_rna_props( void )
923 {
924         PyObject *submodule;
925         submodule= PyModule_Create(&props_module);
926         PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
927
928         /* INCREF since its its assumed that all these functions return the
929          * module with a new ref like PyDict_New, since they are passed to
930           * PyModule_AddObject which steals a ref */
931         Py_INCREF(submodule);
932
933         return submodule;
934 }