2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2010-01-19 00:59:36 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2010-01-19 00:59:36 +00:00
|
|
|
*
|
|
|
|
* Contributor(s): Campbell Barton
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-27 20:10:08 +00:00
|
|
|
/** \file blender/python/intern/bpy_props.c
|
|
|
|
* \ingroup pythonintern
|
2011-11-05 08:21:12 +00:00
|
|
|
*
|
|
|
|
* This file defines 'bpy.props' module used so scripts can define their own
|
|
|
|
* rna properties for use with python operators or adding new properties to
|
|
|
|
* existing blender types.
|
2011-02-27 20:10:08 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2011-02-14 04:15:25 +00:00
|
|
|
#include <Python.h>
|
|
|
|
|
2011-03-02 04:51:43 +00:00
|
|
|
#include "RNA_types.h"
|
|
|
|
|
2010-01-19 00:59:36 +00:00
|
|
|
#include "bpy_props.h"
|
|
|
|
#include "bpy_rna.h"
|
2010-02-01 10:51:34 +00:00
|
|
|
#include "bpy_util.h"
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
2011-03-02 04:51:43 +00:00
|
|
|
#include "BKE_idprop.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
2010-01-19 00:59:36 +00:00
|
|
|
#include "RNA_define.h" /* for defining our own rna */
|
2010-02-02 23:03:56 +00:00
|
|
|
#include "RNA_enum_types.h"
|
2010-01-19 00:59:36 +00:00
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2010-09-01 14:13:48 +00:00
|
|
|
#include "../generic/py_capi_utils.h"
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
/* initial definition of callback slots we'll probably have more then 1 */
|
|
|
|
#define BPY_DATA_CB_SLOT_SIZE 1
|
|
|
|
|
|
|
|
#define BPY_DATA_CB_SLOT_UPDATE 0
|
|
|
|
|
2011-05-26 16:07:28 +00:00
|
|
|
extern BPy_StructRNA *bpy_context_module;
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
static EnumPropertyItem property_flag_items[] = {
|
2010-02-01 22:04:33 +00:00
|
|
|
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
|
2011-10-06 22:04:01 +00:00
|
|
|
{PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
|
2012-03-03 11:45:08 +00:00
|
|
|
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", ""},
|
2012-05-19 21:22:01 +00:00
|
|
|
{PROP_LIB_EXCEPTION, "LIBRARY_EDITABLE", 0, "Library Editable", ""},
|
2010-02-01 22:04:33 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
static EnumPropertyItem property_flag_enum_items[] = {
|
2010-12-13 09:10:16 +00:00
|
|
|
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
|
2011-10-06 22:04:01 +00:00
|
|
|
{PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
|
2012-03-03 11:45:08 +00:00
|
|
|
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", ""},
|
2010-12-13 09:10:16 +00:00
|
|
|
{PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""},
|
2012-05-19 21:22:01 +00:00
|
|
|
{PROP_LIB_EXCEPTION, "LIBRARY_EDITABLE", 0, "Library Editable", ""},
|
2010-12-13 09:10:16 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
2010-02-01 22:04:33 +00:00
|
|
|
/* subtypes */
|
2011-12-26 12:26:11 +00:00
|
|
|
static EnumPropertyItem property_subtype_string_items[] = {
|
2010-02-01 22:04:33 +00:00
|
|
|
{PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
|
|
|
|
{PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
|
2012-10-30 12:36:54 +00:00
|
|
|
{PROP_FILENAME, "FILE_NAME", 0, "Filename", ""},
|
2011-11-15 07:09:41 +00:00
|
|
|
{PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""},
|
2011-10-06 22:04:01 +00:00
|
|
|
{PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
|
* New string property subtype: PASSWORD
When this new subtypes is used, then string of property is hidden using
asterisks, e.g.: mysecretpassword -> ****************
This code was reviewed and modified by Brecht. Thanks very much:
- https://codereview.appspot.com/6713044/
This new subtype of string property is intended mostly for Add-on developers
writing Add-on which communicates with some server (http, sql, ftp, verse,
etc.). When this server requires user authentication and user has to type
username and password, then current API didn't allow to type 'hidden' password,
e.g. when you want to demonstrate this script, then everybody can see this
security password. Some examples of Add-on which could use this new subtype:
- On-line database of textures
- Integration of render farm
- Integration of Verse
Security Notes:
- You can copy paste hiddent string of property from text input using (Ctrl-C, Ctrl-V),
but you can do this in other GUI toolkits too (this behavior it is widely used).
- Text of string property is stored in plain text, but it is widely used in other
GUI toolkits (Qt, Gtk, etc.).
Simple examples:
- https://dl.dropbox.com/u/369894/draw_op_passwd.py
- https://dl.dropbox.com/u/369894/blender-password.png
2012-10-26 12:58:54 +00:00
|
|
|
{PROP_PASSWORD, "PASSWORD", 0, "Password", 0},
|
2010-02-01 22:04:33 +00:00
|
|
|
|
|
|
|
{PROP_NONE, "NONE", 0, "None", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
static EnumPropertyItem property_subtype_number_items[] = {
|
2010-02-01 22:04:33 +00:00
|
|
|
{PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""},
|
|
|
|
{PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
|
|
|
|
{PROP_FACTOR, "FACTOR", 0, "Factor", ""},
|
|
|
|
{PROP_ANGLE, "ANGLE", 0, "Angle", ""},
|
|
|
|
{PROP_TIME, "TIME", 0, "Time", ""},
|
|
|
|
{PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
|
|
|
|
|
|
|
|
{PROP_NONE, "NONE", 0, "None", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
static EnumPropertyItem property_subtype_array_items[] = {
|
2010-02-01 22:04:33 +00:00
|
|
|
{PROP_COLOR, "COLOR", 0, "Color", ""},
|
|
|
|
{PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
|
|
|
|
{PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
|
|
|
|
{PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""},
|
|
|
|
{PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
|
|
|
|
{PROP_MATRIX, "MATRIX", 0, "Matrix", ""},
|
|
|
|
{PROP_EULER, "EULER", 0, "Euler", ""},
|
|
|
|
{PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
|
|
|
|
{PROP_AXISANGLE, "AXISANGLE", 0, "Axis Angle", ""},
|
|
|
|
{PROP_XYZ, "XYZ", 0, "XYZ", ""},
|
|
|
|
{PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Color Gamma", ""},
|
2010-03-10 20:33:57 +00:00
|
|
|
{PROP_LAYER, "LAYER", 0, "Layer", ""},
|
2010-02-01 22:04:33 +00:00
|
|
|
|
|
|
|
{PROP_NONE, "NONE", 0, "None", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
2010-09-08 10:43:36 +00:00
|
|
|
/* PyObject's */
|
2011-12-26 12:26:11 +00:00
|
|
|
static PyObject *pymeth_BoolProperty = NULL;
|
|
|
|
static PyObject *pymeth_BoolVectorProperty = NULL;
|
|
|
|
static PyObject *pymeth_IntProperty = NULL;
|
|
|
|
static PyObject *pymeth_IntVectorProperty = NULL;
|
|
|
|
static PyObject *pymeth_FloatProperty = NULL;
|
|
|
|
static PyObject *pymeth_FloatVectorProperty = NULL;
|
|
|
|
static PyObject *pymeth_StringProperty = NULL;
|
|
|
|
static PyObject *pymeth_EnumProperty = NULL;
|
|
|
|
static PyObject *pymeth_PointerProperty = NULL;
|
|
|
|
static PyObject *pymeth_CollectionProperty = NULL;
|
|
|
|
static PyObject *pymeth_RemoveProperty = NULL;
|
2010-09-08 10:43:36 +00:00
|
|
|
|
2011-08-28 05:06:30 +00:00
|
|
|
static PyObject *pyrna_struct_as_instance(PointerRNA *ptr)
|
2011-06-06 17:50:20 +00:00
|
|
|
{
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *self = NULL;
|
2011-06-06 17:50:20 +00:00
|
|
|
/* first get self */
|
|
|
|
/* operators can store their own instance for later use */
|
2011-10-13 01:29:08 +00:00
|
|
|
if (ptr->data) {
|
2011-12-26 12:26:11 +00:00
|
|
|
void **instance = RNA_struct_instance(ptr);
|
2011-06-06 17:50:20 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (instance) {
|
|
|
|
if (*instance) {
|
2011-12-26 12:26:11 +00:00
|
|
|
self = *instance;
|
2011-06-06 17:50:20 +00:00
|
|
|
Py_INCREF(self);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* in most cases this will run */
|
2011-10-13 01:29:08 +00:00
|
|
|
if (self == NULL) {
|
2011-12-26 12:26:11 +00:00
|
|
|
self = pyrna_struct_CreatePyObject(ptr);
|
2011-06-06 17:50:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* could be moved into bpy_utils */
|
|
|
|
static void printf_func_error(PyObject *py_func)
|
|
|
|
{
|
|
|
|
/* since we return to C code we can't leave the error */
|
2011-12-26 12:26:11 +00:00
|
|
|
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
|
2011-06-06 17:50:20 +00:00
|
|
|
PyErr_Print();
|
|
|
|
PyErr_Clear();
|
|
|
|
|
|
|
|
/* use py style error */
|
|
|
|
fprintf(stderr, "File \"%s\", line %d, in %s\n",
|
2012-03-16 21:39:56 +00:00
|
|
|
_PyUnicode_AsString(f_code->co_filename),
|
|
|
|
f_code->co_firstlineno,
|
|
|
|
_PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)
|
|
|
|
);
|
2011-06-06 17:50:20 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
|
2010-09-10 02:46:29 +00:00
|
|
|
/* operators and classes use this so it can store the args given but defer
|
|
|
|
* running it until the operator runs where these values are used to setup
|
|
|
|
* the default args for that operator instance */
|
2010-09-08 10:43:36 +00:00
|
|
|
static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *ret = PyTuple_New(2);
|
2010-09-08 10:43:36 +00:00
|
|
|
PyTuple_SET_ITEM(ret, 0, func);
|
|
|
|
Py_INCREF(func);
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
if (kw == NULL)
|
|
|
|
kw = PyDict_New();
|
2010-09-08 10:43:36 +00:00
|
|
|
else
|
|
|
|
Py_INCREF(kw);
|
|
|
|
|
2010-01-19 00:59:36 +00:00
|
|
|
PyTuple_SET_ITEM(ret, 1, kw);
|
2010-09-08 10:43:36 +00:00
|
|
|
|
2010-01-19 00:59:36 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
/* callbacks */
|
2011-08-28 05:06:30 +00:00
|
|
|
static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop)
|
2011-06-06 17:50:20 +00:00
|
|
|
{
|
|
|
|
PyGILState_STATE gilstate;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
2011-06-06 17:50:20 +00:00
|
|
|
PyObject *py_func;
|
|
|
|
PyObject *args;
|
|
|
|
PyObject *self;
|
|
|
|
PyObject *ret;
|
2011-12-26 12:26:11 +00:00
|
|
|
const int is_write_ok = pyrna_write_check();
|
2011-06-06 17:50:20 +00:00
|
|
|
|
|
|
|
BLI_assert(py_data != NULL);
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!is_write_ok) {
|
2011-06-07 16:08:49 +00:00
|
|
|
pyrna_write_set(TRUE);
|
|
|
|
}
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_context_set(C, &gilstate);
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
py_func = py_data[BPY_DATA_CB_SLOT_UPDATE];
|
2011-06-06 17:50:20 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
args = PyTuple_New(2);
|
|
|
|
self = pyrna_struct_as_instance(ptr);
|
2011-06-06 17:50:20 +00:00
|
|
|
PyTuple_SET_ITEM(args, 0, self);
|
|
|
|
|
|
|
|
PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
|
|
|
|
Py_INCREF(bpy_context_module);
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
ret = PyObject_CallObject(py_func, args);
|
2011-06-06 17:50:20 +00:00
|
|
|
|
|
|
|
Py_DECREF(args);
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (ret == NULL) {
|
2011-06-06 17:50:20 +00:00
|
|
|
printf_func_error(py_func);
|
|
|
|
}
|
|
|
|
else {
|
2011-10-13 01:29:08 +00:00
|
|
|
if (ret != Py_None) {
|
2011-06-06 17:50:20 +00:00
|
|
|
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
|
|
|
printf_func_error(py_func);
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_DECREF(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
bpy_context_clear(C, &gilstate);
|
2011-06-07 16:08:49 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!is_write_ok) {
|
2011-06-07 16:08:49 +00:00
|
|
|
pyrna_write_set(FALSE);
|
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int bpy_prop_callback_check(PyObject *py_func, int argcount)
|
|
|
|
{
|
2011-11-29 22:57:35 +00:00
|
|
|
if (py_func && py_func != Py_None) {
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!PyFunction_Check(py_func)) {
|
2011-06-06 17:50:20 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"update keyword: expected a function type, not a %.200s",
|
|
|
|
Py_TYPE(py_func)->tp_name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else {
|
2011-12-26 12:26:11 +00:00
|
|
|
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
|
2011-06-06 17:50:20 +00:00
|
|
|
if (f_code->co_argcount != argcount) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"update keyword: expected a function taking %d arguments, not %d",
|
|
|
|
argcount, f_code->co_argcount);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
|
|
|
|
{
|
|
|
|
/* assume this is already checked for type and arg length */
|
2012-10-25 22:37:05 +00:00
|
|
|
if (update_cb && update_cb != Py_None) {
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
|
2011-06-06 17:50:20 +00:00
|
|
|
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
|
2011-12-26 12:26:11 +00:00
|
|
|
py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
|
2011-06-06 17:50:20 +00:00
|
|
|
RNA_def_py_data(prop, py_data);
|
|
|
|
|
|
|
|
RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-28 09:18:20 +00:00
|
|
|
/* utility function we need for parsing int's in an if statement */
|
|
|
|
static int py_long_as_int(PyObject *py_long, int *r_int)
|
|
|
|
{
|
2011-10-13 01:29:08 +00:00
|
|
|
if (PyLong_CheckExact(py_long)) {
|
2011-12-26 12:26:11 +00:00
|
|
|
*r_int = (int)PyLong_AS_LONG(py_long);
|
2011-09-28 09:18:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-10 02:46:29 +00:00
|
|
|
/* this define runs at the start of each function and deals with
|
2011-04-21 05:49:47 +00:00
|
|
|
* returning a deferred property (to be registered later) */
|
2011-11-05 05:44:52 +00:00
|
|
|
#define BPY_PROPDEF_HEAD(_func) \
|
|
|
|
if (PyTuple_GET_SIZE(args) == 1) { \
|
|
|
|
PyObject *ret; \
|
2011-12-26 12:26:11 +00:00
|
|
|
self = PyTuple_GET_ITEM(args, 0); \
|
|
|
|
args = PyTuple_New(0); \
|
|
|
|
ret = BPy_##_func(self, args, kw); \
|
2011-11-05 05:44:52 +00:00
|
|
|
Py_DECREF(args); \
|
|
|
|
return ret; \
|
|
|
|
} \
|
|
|
|
else if (PyTuple_GET_SIZE(args) > 1) { \
|
|
|
|
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
|
|
|
return NULL; \
|
|
|
|
} \
|
2011-12-26 12:26:11 +00:00
|
|
|
srna = srna_from_self(self, #_func"(...):"); \
|
|
|
|
if (srna == NULL) { \
|
2011-11-05 05:44:52 +00:00
|
|
|
if (PyErr_Occurred()) \
|
|
|
|
return NULL; \
|
2011-11-26 15:18:30 +00:00
|
|
|
return bpy_prop_deferred_return(pymeth_##_func, kw); \
|
2012-05-27 20:13:59 +00:00
|
|
|
} (void)0
|
2010-09-08 08:48:40 +00:00
|
|
|
|
2010-10-22 13:02:41 +00:00
|
|
|
/* terse macros for error checks shared between all funcs cant use function
|
2012-07-16 23:23:33 +00:00
|
|
|
* calls because of static strings passed to pyrna_set_to_enum_bitfield */
|
2011-11-05 05:44:52 +00:00
|
|
|
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
2012-10-30 12:45:42 +00:00
|
|
|
if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \
|
2011-11-05 05:44:52 +00:00
|
|
|
PyErr_Format(PyExc_TypeError, \
|
|
|
|
#_func"(): '%.200s' too long, max length is %d", \
|
2011-12-26 12:26:11 +00:00
|
|
|
id, MAX_IDPROP_NAME - 1); \
|
2011-11-05 05:44:52 +00:00
|
|
|
return NULL; \
|
|
|
|
} \
|
2012-10-30 12:45:42 +00:00
|
|
|
if (UNLIKELY(RNA_def_property_free_identifier(srna, id) == -1)) { \
|
2011-11-05 05:44:52 +00:00
|
|
|
PyErr_Format(PyExc_TypeError, \
|
|
|
|
#_func"(): '%s' is defined as a non-dynamic type", \
|
|
|
|
id); \
|
|
|
|
return NULL; \
|
|
|
|
} \
|
2012-10-30 12:45:42 +00:00
|
|
|
if (UNLIKELY(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \
|
2011-11-05 05:44:52 +00:00
|
|
|
pyopts, \
|
|
|
|
&opts, \
|
2012-10-30 12:45:42 +00:00
|
|
|
#_func"(options={ ...}):"))) \
|
2011-11-05 05:44:52 +00:00
|
|
|
{ \
|
|
|
|
return NULL; \
|
2012-05-27 20:13:59 +00:00
|
|
|
} (void)0
|
2011-11-05 05:44:52 +00:00
|
|
|
|
|
|
|
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_CHECK(_func, _property_flag_items); \
|
2012-10-30 12:45:42 +00:00
|
|
|
if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, \
|
2011-11-05 05:44:52 +00:00
|
|
|
pysubtype, \
|
2012-10-30 12:45:42 +00:00
|
|
|
&subtype) == 0)) \
|
2011-11-05 05:44:52 +00:00
|
|
|
{ \
|
2012-10-30 12:45:42 +00:00
|
|
|
const char *enum_str = BPy_enum_as_string(_subtype); \
|
2011-11-05 05:44:52 +00:00
|
|
|
PyErr_Format(PyExc_TypeError, \
|
2012-10-30 12:45:42 +00:00
|
|
|
#_func"(subtype='%s'): " \
|
|
|
|
"subtype not found in (%s)", \
|
|
|
|
pysubtype, enum_str); \
|
|
|
|
MEM_freeN((void *)enum_str); \
|
2011-11-05 05:44:52 +00:00
|
|
|
return NULL; \
|
2012-05-27 20:13:59 +00:00
|
|
|
} (void)0
|
2010-10-22 13:02:41 +00:00
|
|
|
|
2010-09-08 08:48:40 +00:00
|
|
|
|
2011-02-15 11:43:35 +00:00
|
|
|
#define BPY_PROPDEF_NAME_DOC \
|
|
|
|
" :arg name: Name used in the user interface.\n" \
|
|
|
|
" :type name: string\n" \
|
|
|
|
|
|
|
|
|
|
|
|
#define BPY_PROPDEF_DESC_DOC \
|
|
|
|
" :arg description: Text used for the tooltip and api documentation.\n" \
|
|
|
|
" :type description: string\n" \
|
|
|
|
|
|
|
|
|
2011-08-02 10:56:09 +00:00
|
|
|
#define BPY_PROPDEF_UNIT_DOC \
|
|
|
|
" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \
|
|
|
|
" :type unit: string\n" \
|
|
|
|
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
#define BPY_PROPDEF_UPDATE_DOC \
|
|
|
|
" :arg update: function to be called when this value is modified,\n" \
|
|
|
|
" This function must take 2 values (self, context) and return None.\n" \
|
2012-09-28 09:35:32 +00:00
|
|
|
" *Warning* there are no safety checks to avoid infinite recursion.\n" \
|
2011-06-06 17:50:20 +00:00
|
|
|
" :type update: function\n" \
|
|
|
|
|
2010-06-05 15:31:55 +00:00
|
|
|
#if 0
|
2010-02-17 21:58:08 +00:00
|
|
|
static int bpy_struct_id_used(StructRNA *srna, char *identifier)
|
|
|
|
{
|
|
|
|
PointerRNA ptr;
|
|
|
|
RNA_pointer_create(NULL, srna, NULL, &ptr);
|
|
|
|
return (RNA_struct_find_property(&ptr, identifier) != NULL);
|
|
|
|
}
|
2010-06-05 15:31:55 +00:00
|
|
|
#endif
|
2010-02-17 21:58:08 +00:00
|
|
|
|
|
|
|
|
2011-11-26 15:18:30 +00:00
|
|
|
/* Function that sets RNA, NOTE - self is NULL when called from python,
|
|
|
|
* but being abused from C so we can pass the srna along.
|
2012-03-18 07:38:51 +00:00
|
|
|
* This isn't incorrect since its a python object - but be careful */
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_BoolProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. function:: BoolProperty(name=\"\", "
|
|
|
|
"description=\"\", "
|
|
|
|
"default=False, "
|
|
|
|
"options={'ANIMATABLE'}, "
|
|
|
|
"subtype='NONE', "
|
|
|
|
"update=None)\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
"\n"
|
|
|
|
" Returns a new boolean property definition.\n"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
|
|
|
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type subtype: string\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(BoolProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"options", "subtype", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
int def = 0;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#|ssiO!sO:BoolProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &def,
|
2011-06-06 17:50:20 +00:00
|
|
|
&PySet_Type, &pyopts, &pysubtype,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
|
2010-10-19 07:23:34 +00:00
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_boolean_default(prop, def);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. function:: BoolVectorProperty(name=\"\", "
|
|
|
|
"description=\"\", "
|
|
|
|
"default=(False, False, False), "
|
|
|
|
"options={'ANIMATABLE'}, "
|
|
|
|
"subtype='NONE', "
|
|
|
|
"size=3, "
|
|
|
|
"update=None)\n"
|
2010-02-01 10:51:34 +00:00
|
|
|
"\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" Returns a new vector boolean property definition.\n"
|
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
|
|
|
" :arg default: sequence of booleans the length of *size*.\n"
|
|
|
|
" :type default: sequence\n"
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2012-01-21 10:27:24 +00:00
|
|
|
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
|
|
|
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', "
|
|
|
|
"'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type subtype: string\n"
|
2011-03-19 11:12:48 +00:00
|
|
|
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type size: int\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-02-01 10:51:34 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(BoolVectorProperty);
|
2010-02-01 10:51:34 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"options", "subtype", "size", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
int def[PYRNA_STACK_ARRAY] = {0};
|
|
|
|
int size = 3;
|
2010-02-01 10:51:34 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pydef = NULL;
|
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#|ssOO!siO:BoolVectorProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &pydef,
|
2011-06-06 17:50:20 +00:00
|
|
|
&PySet_Type, &pyopts, &pysubtype, &size,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2012-05-27 21:56:19 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items);
|
2010-02-01 10:51:34 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
2011-11-26 15:18:30 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"BoolVectorProperty(size=%d): size must be between 0 and "
|
|
|
|
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
2010-02-01 10:51:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
|
2010-02-01 10:51:34 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-28 04:25:46 +00:00
|
|
|
// prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description);
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_array(prop, size);
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pydef) RNA_def_property_boolean_array_default(prop, def);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-02-01 10:51:34 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
|
|
|
|
Py_RETURN_NONE;
|
2010-02-01 10:51:34 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_IntProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. 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"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" Returns a new int property definition.\n"
|
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
|
|
|
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type subtype: string\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(IntProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"min", "max", "soft_min", "soft_max",
|
2012-01-21 10:27:24 +00:00
|
|
|
"step", "options", "subtype", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#|ssiiiiiiO!sO:IntProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &def,
|
|
|
|
&min, &max, &soft_min, &soft_max,
|
2011-06-06 17:50:20 +00:00
|
|
|
&step, &PySet_Type, &pyopts, &pysubtype,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2012-05-27 21:56:19 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_INT, subtype);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_int_default(prop, def);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_range(prop, min, max);
|
2010-09-02 14:43:22 +00:00
|
|
|
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_IntVectorProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. 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"
|
2010-02-01 10:51:34 +00:00
|
|
|
"\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" Returns a new vector int property definition.\n"
|
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
|
|
|
" :arg default: sequence of ints the length of *size*.\n"
|
|
|
|
" :type default: sequence\n"
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2012-01-21 10:27:24 +00:00
|
|
|
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
|
|
|
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', "
|
|
|
|
"'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type subtype: string\n"
|
2011-03-19 11:12:48 +00:00
|
|
|
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type size: int\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-02-01 10:51:34 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(IntVectorProperty);
|
2010-02-01 10:51:34 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"min", "max", "soft_min", "soft_max",
|
|
|
|
"step", "options", "subtype", "size", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1;
|
|
|
|
int def[PYRNA_STACK_ARRAY] = {0};
|
|
|
|
int size = 3;
|
2010-02-01 10:51:34 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pydef = NULL;
|
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#|ssOiiiiiO!siO:IntVectorProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &pydef,
|
|
|
|
&min, &max, &soft_min, &soft_max,
|
|
|
|
&step, &PySet_Type, &pyopts,
|
2011-06-06 17:50:20 +00:00
|
|
|
&pysubtype, &size,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2012-05-27 21:56:19 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items);
|
2010-02-01 10:51:34 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
2011-11-26 15:18:30 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"IntVectorProperty(size=%d): size must be between 0 and "
|
|
|
|
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
2010-02-01 10:51:34 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
|
2010-02-01 10:51:34 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_INT, subtype);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_array(prop, size);
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pydef) RNA_def_property_int_array_default(prop, def);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_range(prop, min, max);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-09-02 14:43:22 +00:00
|
|
|
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-02-01 10:51:34 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-02-01 10:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_FloatProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. 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"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" Returns a new float property definition.\n"
|
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
|
|
|
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
2010-02-02 23:03:56 +00:00
|
|
|
" :type subtype: string\n"
|
2011-08-02 10:56:09 +00:00
|
|
|
BPY_PROPDEF_UNIT_DOC
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(FloatProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"min", "max", "soft_min", "soft_max",
|
|
|
|
"step", "precision", "options", "subtype", "unit", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
|
|
|
|
int precision = 2;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
char *pyunit = NULL;
|
|
|
|
int unit = PROP_UNIT_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#|ssffffffiO!ssO:FloatProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &def,
|
|
|
|
&min, &max, &soft_min, &soft_max,
|
|
|
|
&step, &precision, &PySet_Type,
|
2011-06-06 17:50:20 +00:00
|
|
|
&pyopts, &pysubtype, &pyunit,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 21:56:19 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
|
2011-08-02 10:56:09 +00:00
|
|
|
PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit);
|
2010-02-02 23:03:56 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_float_default(prop, def);
|
|
|
|
RNA_def_property_range(prop, min, max);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-09-02 14:43:22 +00:00
|
|
|
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. 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"
|
2010-02-01 22:04:33 +00:00
|
|
|
"\n"
|
|
|
|
" Returns a new vector float property definition.\n"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
|
|
|
" :arg default: sequence of floats the length of *size*.\n"
|
|
|
|
" :type default: sequence\n"
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2012-01-21 10:27:24 +00:00
|
|
|
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
|
|
|
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', "
|
|
|
|
"'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type subtype: string\n"
|
2011-08-02 10:56:09 +00:00
|
|
|
BPY_PROPDEF_UNIT_DOC
|
2011-03-19 11:12:48 +00:00
|
|
|
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type size: int\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(FloatVectorProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"min", "max", "soft_min", "soft_max",
|
|
|
|
"step", "precision", "options", "subtype", "unit", "size", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2012-01-21 10:27:24 +00:00
|
|
|
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3;
|
|
|
|
float def[PYRNA_STACK_ARRAY] = {0.0f};
|
2011-12-26 12:26:11 +00:00
|
|
|
int precision = 2, size = 3;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pydef = NULL;
|
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
char *pyunit = NULL;
|
|
|
|
int unit = PROP_UNIT_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-08-02 10:56:09 +00:00
|
|
|
"s#|ssOfffffiO!ssiO:FloatVectorProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &pydef,
|
|
|
|
&min, &max, &soft_min, &soft_max,
|
|
|
|
&step, &precision, &PySet_Type,
|
2011-08-02 10:56:09 +00:00
|
|
|
&pyopts, &pysubtype, &pyunit, &size,
|
2011-06-06 17:50:20 +00:00
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 21:56:19 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
|
2011-08-02 10:56:09 +00:00
|
|
|
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
2011-11-26 15:18:30 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"FloatVectorProperty(size=%d): size must be between 0 and "
|
|
|
|
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
|
2010-02-01 10:51:34 +00:00
|
|
|
return NULL;
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_array(prop, size);
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pydef) RNA_def_property_float_array_default(prop, def);
|
2010-02-01 22:04:33 +00:00
|
|
|
RNA_def_property_range(prop, min, max);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-09-02 14:43:22 +00:00
|
|
|
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_StringProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. function:: StringProperty(name=\"\", "
|
|
|
|
"description=\"\", "
|
|
|
|
"default=\"\", "
|
|
|
|
"maxlen=0, "
|
|
|
|
"options={'ANIMATABLE'}, "
|
|
|
|
"subtype='NONE', "
|
|
|
|
"update=None)\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
"\n"
|
|
|
|
" Returns a new string property definition.\n"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2012-10-30 12:36:54 +00:00
|
|
|
" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'NONE'].\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type subtype: string\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(StringProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"maxlen", "options", "subtype", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "", *def = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
int maxlen = 0;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
char *pysubtype = NULL;
|
|
|
|
int subtype = PROP_NONE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#|sssiO!sO:StringProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&name, &description, &def,
|
2011-06-06 17:50:20 +00:00
|
|
|
&maxlen, &PySet_Type, &pyopts, &pysubtype,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 21:56:19 +00:00
|
|
|
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
prop = RNA_def_property(srna, id, PROP_STRING, subtype);
|
2012-03-26 20:41:54 +00:00
|
|
|
if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def) RNA_def_property_string_default(prop, def);
|
2011-12-28 04:25:46 +00:00
|
|
|
RNA_def_property_ui_text(prop, name ? name : id, description);
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-06-03 04:39:18 +00:00
|
|
|
#if 0
|
2011-06-03 04:21:41 +00:00
|
|
|
/* copies orig to buf, then sets orig to buf, returns copy length */
|
|
|
|
static size_t strswapbufcpy(char *buf, const char **orig)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
2011-12-26 12:26:11 +00:00
|
|
|
const char *src = *orig;
|
|
|
|
char *dst = buf;
|
|
|
|
size_t i = 0;
|
|
|
|
*orig = buf;
|
|
|
|
while ((*dst = *src)) { dst++; src++; i++; }
|
2011-06-03 04:21:41 +00:00
|
|
|
return i + 1; /* include '\0' */
|
|
|
|
}
|
2011-06-03 04:39:18 +00:00
|
|
|
#endif
|
2011-06-03 03:19:22 +00:00
|
|
|
|
2011-06-03 04:21:41 +00:00
|
|
|
static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
|
|
|
|
{
|
2011-06-03 03:19:22 +00:00
|
|
|
EnumPropertyItem *items;
|
2010-01-19 00:59:36 +00:00
|
|
|
PyObject *item;
|
2011-12-26 12:26:11 +00:00
|
|
|
const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
|
|
|
|
Py_ssize_t totbuf = 0;
|
2011-06-03 04:21:41 +00:00
|
|
|
int i;
|
2011-12-26 12:26:11 +00:00
|
|
|
short def_used = 0;
|
|
|
|
const char *def_cmp = NULL;
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (is_enum_flag) {
|
|
|
|
if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
|
2011-11-26 15:18:30 +00:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"EnumProperty(...): maximum "
|
|
|
|
STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
|
|
|
|
" members for a ENUM_FLAG type property");
|
2010-12-13 09:10:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def && !PySet_Check(def)) {
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"EnumProperty(...): default option must be a 'set' "
|
|
|
|
"type when ENUM_FLAG is enabled, not a '%.200s'",
|
|
|
|
Py_TYPE(def)->tp_name);
|
2010-12-13 09:10:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def) {
|
2011-12-26 12:26:11 +00:00
|
|
|
def_cmp = _PyUnicode_AsString(def);
|
|
|
|
if (def_cmp == NULL) {
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"EnumProperty(...): default option must be a 'str' "
|
|
|
|
"type when ENUM_FLAG is disabled, not a '%.200s'",
|
|
|
|
Py_TYPE(def)->tp_name);
|
2010-12-13 09:10:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* blank value */
|
2011-12-26 12:26:11 +00:00
|
|
|
*defvalue = 0;
|
2010-12-13 09:10:16 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
|
2011-06-03 03:19:22 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
for (i = 0; i < seq_len; i++) {
|
|
|
|
EnumPropertyItem tmp = {0, "", 0, "", ""};
|
2011-09-28 09:18:20 +00:00
|
|
|
Py_ssize_t item_size;
|
2011-06-03 04:21:41 +00:00
|
|
|
Py_ssize_t id_str_size;
|
|
|
|
Py_ssize_t name_str_size;
|
|
|
|
Py_ssize_t desc_str_size;
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
item = PySequence_Fast_GET_ITEM(seq_fast, i);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-03-16 21:39:56 +00:00
|
|
|
if ((PyTuple_CheckExact(item)) &&
|
|
|
|
(item_size = PyTuple_GET_SIZE(item)) &&
|
|
|
|
(item_size == 3 || item_size == 4) &&
|
|
|
|
(tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
|
|
|
|
(tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
|
|
|
|
(tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
|
2012-03-18 07:38:51 +00:00
|
|
|
/* TODO, number isn't ensured to be unique from the script author */
|
2012-03-16 21:39:56 +00:00
|
|
|
(item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1))
|
2011-12-18 08:50:06 +00:00
|
|
|
{
|
2011-10-13 01:29:08 +00:00
|
|
|
if (is_enum_flag) {
|
|
|
|
if (item_size < 4) {
|
2011-12-26 12:26:11 +00:00
|
|
|
tmp.value = 1 << i;
|
2011-09-28 09:18:20 +00:00
|
|
|
}
|
2011-06-03 04:21:41 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
|
2011-06-03 04:21:41 +00:00
|
|
|
*defvalue |= tmp.value;
|
|
|
|
def_used++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2011-10-13 01:29:08 +00:00
|
|
|
if (item_size < 4) {
|
2011-12-26 12:26:11 +00:00
|
|
|
tmp.value = i;
|
2011-09-28 09:18:20 +00:00
|
|
|
}
|
2010-12-13 09:10:16 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
|
|
|
|
*defvalue = tmp.value;
|
2011-06-03 04:21:41 +00:00
|
|
|
def_used++; /* only ever 1 */
|
|
|
|
}
|
2010-12-13 09:10:16 +00:00
|
|
|
}
|
2011-06-03 04:21:41 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
items[i] = tmp;
|
2011-06-03 04:21:41 +00:00
|
|
|
|
|
|
|
/* calculate combine string length */
|
|
|
|
totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
|
2010-12-13 09:10:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-06-03 04:21:41 +00:00
|
|
|
MEM_freeN(items);
|
2011-09-28 09:18:20 +00:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
2012-05-04 14:34:10 +00:00
|
|
|
"EnumProperty(...): expected a tuple containing "
|
|
|
|
"(identifier, name, description) and optionally a "
|
2011-09-28 09:18:20 +00:00
|
|
|
"unique number");
|
2011-06-03 04:21:41 +00:00
|
|
|
return NULL;
|
2010-12-13 09:10:16 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-06-03 04:21:41 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (is_enum_flag) {
|
2010-12-13 09:10:16 +00:00
|
|
|
/* strict check that all set members were used */
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def && def_used != PySet_GET_SIZE(def)) {
|
2010-12-13 09:10:16 +00:00
|
|
|
MEM_freeN(items);
|
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"EnumProperty(..., default={...}): set has %d unused member(s)",
|
|
|
|
PySet_GET_SIZE(def) - def_used);
|
2010-12-13 09:10:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def && def_used == 0) {
|
2010-12-13 09:10:16 +00:00
|
|
|
MEM_freeN(items);
|
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"EnumProperty(..., default=\'%s\'): not found in enum members",
|
2011-09-27 16:23:40 +00:00
|
|
|
def_cmp);
|
2010-12-13 09:10:16 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2011-01-16 10:36:27 +00:00
|
|
|
|
2011-06-03 04:39:18 +00:00
|
|
|
/* disabled duplicating strings because the array can still be freed and
|
|
|
|
* the strings from it referenced, for now we can't support dynamically
|
|
|
|
* created strings from python. */
|
|
|
|
#if 0
|
2011-06-03 04:21:41 +00:00
|
|
|
/* this would all work perfectly _but_ the python strings may be freed
|
|
|
|
* immediately after use, so we need to duplicate them, ugh.
|
|
|
|
* annoying because it works most of the time without this. */
|
|
|
|
{
|
2011-12-26 12:26:11 +00:00
|
|
|
EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
|
2012-03-26 20:41:54 +00:00
|
|
|
"enum_items_from_py2");
|
2011-12-26 12:26:11 +00:00
|
|
|
EnumPropertyItem *items_ptr = items_dup;
|
|
|
|
char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
|
2011-06-03 04:21:41 +00:00
|
|
|
memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
|
2011-12-26 12:26:11 +00:00
|
|
|
for (i = 0; i < seq_len; i++, items_ptr++) {
|
2011-06-03 04:21:41 +00:00
|
|
|
buf += strswapbufcpy(buf, &items_ptr->identifier);
|
|
|
|
buf += strswapbufcpy(buf, &items_ptr->name);
|
|
|
|
buf += strswapbufcpy(buf, &items_ptr->description);
|
|
|
|
}
|
|
|
|
MEM_freeN(items);
|
2011-12-26 12:26:11 +00:00
|
|
|
items = items_dup;
|
2011-06-03 04:21:41 +00:00
|
|
|
}
|
|
|
|
/* end string duplication */
|
2011-06-03 04:39:18 +00:00
|
|
|
#endif
|
2011-06-03 03:19:22 +00:00
|
|
|
|
2011-06-03 04:21:41 +00:00
|
|
|
return items;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 16:07:28 +00:00
|
|
|
static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
|
|
|
|
{
|
|
|
|
PyGILState_STATE gilstate;
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *py_func = RNA_property_enum_py_data_get(prop);
|
|
|
|
PyObject *self = NULL;
|
2011-05-26 16:07:28 +00:00
|
|
|
PyObject *args;
|
|
|
|
PyObject *items; /* returned from the function call */
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
EnumPropertyItem *eitems = NULL;
|
|
|
|
int err = 0;
|
2011-05-26 16:07:28 +00:00
|
|
|
|
|
|
|
bpy_context_set(C, &gilstate);
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
args = PyTuple_New(2);
|
|
|
|
self = pyrna_struct_as_instance(ptr);
|
2011-05-26 16:07:28 +00:00
|
|
|
PyTuple_SET_ITEM(args, 0, self);
|
|
|
|
|
|
|
|
/* now get the context */
|
|
|
|
PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
|
|
|
|
Py_INCREF(bpy_context_module);
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
items = PyObject_CallObject(py_func, args);
|
2011-05-26 16:07:28 +00:00
|
|
|
|
|
|
|
Py_DECREF(args);
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
if (items == NULL) {
|
|
|
|
err = -1;
|
2011-05-26 16:07:28 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
PyObject *items_fast;
|
2011-12-26 12:26:11 +00:00
|
|
|
int defvalue_dummy = 0;
|
2011-05-26 16:07:28 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
|
2012-03-26 20:41:54 +00:00
|
|
|
"return value from the callback was not a sequence")))
|
2011-11-26 15:18:30 +00:00
|
|
|
{
|
2011-12-26 12:26:11 +00:00
|
|
|
err = -1;
|
2011-05-26 16:07:28 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-01-21 10:27:24 +00:00
|
|
|
eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy,
|
|
|
|
(RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
|
2011-05-26 16:07:28 +00:00
|
|
|
|
|
|
|
Py_DECREF(items_fast);
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!eitems) {
|
2011-12-26 12:26:11 +00:00
|
|
|
err = -1;
|
2011-05-26 16:07:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_DECREF(items);
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (err != -1) { /* worked */
|
2011-12-26 12:26:11 +00:00
|
|
|
*free = 1;
|
2011-05-26 16:07:28 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-06-06 17:50:20 +00:00
|
|
|
printf_func_error(py_func);
|
2011-05-26 16:07:28 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
eitems = DummyRNA_NULL_items;
|
2011-05-26 16:07:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bpy_context_clear(C, &gilstate);
|
|
|
|
return eitems;
|
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_EnumProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. function:: EnumProperty(items, "
|
|
|
|
"name=\"\", "
|
|
|
|
"description=\"\", "
|
|
|
|
"default=\"\", "
|
|
|
|
"options={'ANIMATABLE'}, "
|
|
|
|
"update=None)\n"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
|
|
|
" Returns a new enumerator property definition.\n"
|
|
|
|
"\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2011-05-26 19:13:01 +00:00
|
|
|
" :arg default: The default value for this enum, A string when *ENUM_FLAG*\n"
|
|
|
|
" is disabled otherwise a set which may only contain string identifiers\n"
|
|
|
|
" used in *items*.\n"
|
2010-12-13 09:10:16 +00:00
|
|
|
" :type default: string or set\n"
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2011-05-26 19:13:01 +00:00
|
|
|
" :arg items: sequence of enum items formatted:\n"
|
2011-09-28 09:18:20 +00:00
|
|
|
" [(identifier, name, description, number), ...] where the identifier is used\n"
|
2011-05-26 19:13:01 +00:00
|
|
|
" for python access and other values are used for the interface.\n"
|
2011-09-28 09:18:20 +00:00
|
|
|
" Note the item is optional.\n"
|
2011-05-26 19:13:01 +00:00
|
|
|
" For dynamic values a callback can be passed which returns a list in\n"
|
|
|
|
" the same format as the static list.\n"
|
|
|
|
" This function must take 2 arguments (self, context)\n"
|
2011-05-26 16:07:28 +00:00
|
|
|
" :type items: sequence of string triplets or a function\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(EnumProperty);
|
2010-09-08 10:43:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "items", "name", "description", "default",
|
2012-03-26 20:41:54 +00:00
|
|
|
"options", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *def = NULL;
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2011-12-26 12:26:11 +00:00
|
|
|
int defvalue = 0;
|
2011-01-16 10:36:27 +00:00
|
|
|
PyObject *items, *items_fast;
|
2010-01-19 00:59:36 +00:00
|
|
|
EnumPropertyItem *eitems;
|
|
|
|
PropertyRNA *prop;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
short is_itemf = FALSE;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#O|ssOO!O:EnumProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&items, &name, &description,
|
2011-06-06 17:50:20 +00:00
|
|
|
&def, &PySet_Type, &pyopts,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-05-26 16:07:28 +00:00
|
|
|
/* items can be a list or a callable */
|
2012-03-18 07:38:51 +00:00
|
|
|
if (PyFunction_Check(items)) { /* don't use PyCallable_Check because we need the function code for errors */
|
2011-12-26 12:26:11 +00:00
|
|
|
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items);
|
2011-10-13 01:29:08 +00:00
|
|
|
if (f_code->co_argcount != 2) {
|
2011-05-26 16:07:28 +00:00
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
"EnumProperty(...): expected 'items' function to take 2 arguments, not %d",
|
|
|
|
f_code->co_argcount);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (def) {
|
2011-05-26 16:07:28 +00:00
|
|
|
/* note, using type error here is odd but python does this for invalid arguments */
|
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"EnumProperty(...): 'default' can't be set when 'items' is a function");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
is_itemf = TRUE;
|
|
|
|
eitems = DummyRNA_NULL_items;
|
2011-01-16 10:36:27 +00:00
|
|
|
}
|
2011-05-26 16:07:28 +00:00
|
|
|
else {
|
2011-12-26 12:26:11 +00:00
|
|
|
if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
|
2012-03-26 20:41:54 +00:00
|
|
|
"expected a sequence of tuples for the enum items or a function")))
|
2011-11-26 15:18:30 +00:00
|
|
|
{
|
2011-05-26 16:07:28 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2011-01-16 10:36:27 +00:00
|
|
|
|
2012-01-21 10:27:24 +00:00
|
|
|
eitems = enum_items_from_py(items_fast, def, &defvalue,
|
|
|
|
(opts & PROP_ENUM_FLAG) != 0);
|
2011-01-16 10:36:27 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!eitems) {
|
2012-08-07 10:03:14 +00:00
|
|
|
Py_DECREF(items_fast);
|
2011-05-26 16:07:28 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-12-28 04:25:46 +00:00
|
|
|
if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description);
|
|
|
|
else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description);
|
2011-01-16 10:08:20 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (is_itemf) {
|
2011-05-26 16:07:28 +00:00
|
|
|
RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
|
|
|
|
RNA_def_enum_py_data(prop, (void *)items);
|
2011-11-26 15:18:30 +00:00
|
|
|
|
|
|
|
/* watch out!, if a user is tricky they can probably crash blender
|
|
|
|
* if they manage to free the callback, take care! */
|
|
|
|
/* Py_INCREF(items); */
|
2011-05-26 16:07:28 +00:00
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2011-05-26 16:07:28 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (is_itemf == FALSE) {
|
2012-08-07 10:03:14 +00:00
|
|
|
/* note: this must be postponed until after #RNA_def_property_duplicate_pointers
|
2012-08-07 13:37:16 +00:00
|
|
|
* otherwise if this is a generator it may free the strings before we copy them */
|
2012-08-07 10:03:14 +00:00
|
|
|
Py_DECREF(items_fast);
|
|
|
|
|
2011-05-26 16:07:28 +00:00
|
|
|
MEM_freeN(eitems);
|
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2010-03-16 17:20:15 +00:00
|
|
|
static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
srna = srna_from_self(value, "");
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!srna) {
|
|
|
|
if (PyErr_Occurred()) {
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *msg = PyC_ExceptionBuffer();
|
|
|
|
const char *msg_char = _PyUnicode_AsString(msg);
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"%.200s expected an RNA type derived from PropertyGroup, failed with: %s",
|
|
|
|
error_prefix, msg_char);
|
2011-01-26 12:44:09 +00:00
|
|
|
Py_DECREF(msg);
|
|
|
|
}
|
|
|
|
else {
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"%.200s expected an RNA type derived from PropertyGroup, failed with type '%s'",
|
|
|
|
error_prefix, Py_TYPE(value)->tp_name);
|
2011-01-26 12:44:09 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
|
2011-04-30 13:58:31 +00:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"%.200s expected an RNA type derived from PropertyGroup",
|
|
|
|
error_prefix);
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srna;
|
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_PointerProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. function:: PointerProperty(type=\"\", "
|
|
|
|
"description=\"\", "
|
|
|
|
"options={'ANIMATABLE'}, "
|
|
|
|
"update=None)\n"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
|
|
|
" Returns a new pointer property definition.\n"
|
|
|
|
"\n"
|
2011-02-16 02:51:56 +00:00
|
|
|
" :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type type: class\n"
|
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2011-06-06 17:50:20 +00:00
|
|
|
BPY_PROPDEF_UPDATE_DOC
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(PointerProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "type", "name", "description", "options", "update", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
StructRNA *ptype;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *type = Py_None;
|
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
|
|
|
PyObject *update_cb = NULL;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
2011-06-06 17:50:20 +00:00
|
|
|
"s#O|ssO!O:PointerProperty",
|
2011-04-30 13:58:31 +00:00
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&type, &name, &description,
|
2011-06-06 17:50:20 +00:00
|
|
|
&PySet_Type, &pyopts,
|
|
|
|
&update_cb))
|
2011-04-30 13:58:31 +00:00
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_CHECK(PointerProperty, property_flag_items);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
ptype = pointer_type_from_py(type, "PointerProperty(...):");
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!ptype)
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-06-06 17:50:20 +00:00
|
|
|
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-28 04:25:46 +00:00
|
|
|
prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description);
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2011-06-06 17:50:20 +00:00
|
|
|
bpy_prop_callback_assign(prop, update_cb);
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_CollectionProperty_doc,
|
2012-01-21 10:27:24 +00:00
|
|
|
".. function:: CollectionProperty(items, "
|
|
|
|
"type=\"\", "
|
|
|
|
"description=\"\", "
|
|
|
|
"options={'ANIMATABLE'})\n"
|
2010-01-22 02:04:25 +00:00
|
|
|
"\n"
|
|
|
|
" Returns a new collection property definition.\n"
|
|
|
|
"\n"
|
2011-02-16 02:51:56 +00:00
|
|
|
" :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type type: class\n"
|
|
|
|
BPY_PROPDEF_NAME_DOC
|
|
|
|
BPY_PROPDEF_DESC_DOC
|
2012-05-19 21:22:01 +00:00
|
|
|
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
2010-02-01 22:04:33 +00:00
|
|
|
" :type options: set\n"
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_HEAD(CollectionProperty);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (srna) {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
|
2011-12-28 04:25:46 +00:00
|
|
|
const char *id = NULL, *name = NULL, *description = "";
|
2010-10-19 07:23:34 +00:00
|
|
|
int id_len;
|
2010-01-19 00:59:36 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
StructRNA *ptype;
|
2011-12-26 12:26:11 +00:00
|
|
|
PyObject *type = Py_None;
|
|
|
|
PyObject *pyopts = NULL;
|
|
|
|
int opts = 0;
|
2010-02-01 22:04:33 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
|
|
|
"s#O|ssO!:CollectionProperty",
|
|
|
|
(char **)kwlist, &id, &id_len,
|
|
|
|
&type, &name, &description,
|
|
|
|
&PySet_Type, &pyopts))
|
|
|
|
{
|
2010-02-01 22:04:33 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2012-05-27 20:13:59 +00:00
|
|
|
BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
ptype = pointer_type_from_py(type, "CollectionProperty(...):");
|
2011-10-13 01:29:08 +00:00
|
|
|
if (!ptype)
|
2010-01-19 00:59:36 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-12-28 04:25:46 +00:00
|
|
|
prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description);
|
2011-10-13 01:29:08 +00:00
|
|
|
if (pyopts) {
|
|
|
|
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
2011-12-26 12:26:11 +00:00
|
|
|
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
2011-11-14 15:05:41 +00:00
|
|
|
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-05-19 21:22:01 +00:00
|
|
|
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
2010-02-01 22:04:33 +00:00
|
|
|
}
|
2010-09-06 15:54:08 +00:00
|
|
|
RNA_def_property_duplicate_pointers(srna, prop);
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-01-19 00:59:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:05:51 +00:00
|
|
|
PyDoc_STRVAR(BPy_RemoveProperty_doc,
|
2010-05-08 23:34:54 +00:00
|
|
|
".. function:: RemoveProperty(attr)\n"
|
|
|
|
"\n"
|
|
|
|
" Removes a dynamically defined property.\n"
|
|
|
|
"\n"
|
|
|
|
" :arg attr: Property name.\n"
|
2011-02-15 11:43:35 +00:00
|
|
|
" :type attr: string\n"
|
2011-05-24 16:05:51 +00:00
|
|
|
);
|
2010-09-09 06:29:44 +00:00
|
|
|
static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
|
2010-05-08 23:34:54 +00:00
|
|
|
{
|
|
|
|
StructRNA *srna;
|
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (PyTuple_GET_SIZE(args) == 1) {
|
2010-09-08 10:43:36 +00:00
|
|
|
PyObject *ret;
|
2011-12-26 12:26:11 +00:00
|
|
|
self = PyTuple_GET_ITEM(args, 0);
|
|
|
|
args = PyTuple_New(0);
|
|
|
|
ret = BPy_RemoveProperty(self, args, kw);
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_DECREF(args);
|
2012-10-21 05:46:41 +00:00
|
|
|
return ret;
|
2010-09-08 10:43:36 +00:00
|
|
|
}
|
|
|
|
else if (PyTuple_GET_SIZE(args) > 1) {
|
2012-01-12 06:11:08 +00:00
|
|
|
PyErr_SetString(PyExc_ValueError, "all args must be keywords");
|
2010-09-08 10:43:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
srna = srna_from_self(self, "RemoveProperty(...):");
|
|
|
|
if (srna == NULL && PyErr_Occurred()) {
|
2010-05-08 23:34:54 +00:00
|
|
|
return NULL; /* self's type was compatible but error getting the srna */
|
|
|
|
}
|
2011-12-26 12:26:11 +00:00
|
|
|
else if (srna == NULL) {
|
2010-11-23 16:45:17 +00:00
|
|
|
PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type");
|
2010-05-08 23:34:54 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else {
|
2011-12-26 12:26:11 +00:00
|
|
|
static const char *kwlist[] = {"attr", NULL};
|
2010-05-08 23:34:54 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
char *id = NULL;
|
2010-05-08 23:34:54 +00:00
|
|
|
|
2011-04-30 13:58:31 +00:00
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
|
|
|
"s:RemoveProperty",
|
|
|
|
(char **)kwlist, &id))
|
|
|
|
{
|
2010-05-08 23:34:54 +00:00
|
|
|
return NULL;
|
2011-04-30 13:58:31 +00:00
|
|
|
}
|
2010-05-08 23:34:54 +00:00
|
|
|
|
2011-10-13 01:29:08 +00:00
|
|
|
if (RNA_def_property_free_identifier(srna, id) != 1) {
|
2010-11-23 16:45:17 +00:00
|
|
|
PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id);
|
2010-05-08 23:34:54 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
2010-09-08 10:43:36 +00:00
|
|
|
Py_RETURN_NONE;
|
2010-05-08 23:34:54 +00:00
|
|
|
}
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
static struct PyMethodDef props_methods[] = {
|
2012-03-26 20:41:54 +00:00
|
|
|
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS | METH_KEYWORDS, BPy_BoolProperty_doc},
|
|
|
|
{"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS | METH_KEYWORDS, BPy_BoolVectorProperty_doc},
|
|
|
|
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS | METH_KEYWORDS, BPy_IntProperty_doc},
|
|
|
|
{"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS | METH_KEYWORDS, BPy_IntVectorProperty_doc},
|
|
|
|
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS | METH_KEYWORDS, BPy_FloatProperty_doc},
|
|
|
|
{"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS | METH_KEYWORDS, BPy_FloatVectorProperty_doc},
|
|
|
|
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS | METH_KEYWORDS, BPy_StringProperty_doc},
|
|
|
|
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS | METH_KEYWORDS, BPy_EnumProperty_doc},
|
|
|
|
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS | METH_KEYWORDS, BPy_PointerProperty_doc},
|
|
|
|
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS | METH_KEYWORDS, BPy_CollectionProperty_doc},
|
|
|
|
|
|
|
|
{"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS | METH_KEYWORDS, BPy_RemoveProperty_doc},
|
2010-01-19 00:59:36 +00:00
|
|
|
{NULL, NULL, 0, NULL}
|
|
|
|
};
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
static struct PyModuleDef props_module = {
|
2010-01-19 00:59:36 +00:00
|
|
|
PyModuleDef_HEAD_INIT,
|
|
|
|
"bpy.props",
|
2010-01-22 02:04:25 +00:00
|
|
|
"This module defines properties to extend blenders internal data, the result of these functions"
|
|
|
|
" is used to assign properties to classes registered with blender and can't be used directly.",
|
2012-03-26 20:41:54 +00:00
|
|
|
-1, /* multiple "initialization" just copies the module dict. */
|
2010-01-19 00:59:36 +00:00
|
|
|
props_methods,
|
|
|
|
NULL, NULL, NULL, NULL
|
|
|
|
};
|
|
|
|
|
2011-06-02 08:29:16 +00:00
|
|
|
PyObject *BPY_rna_props(void)
|
2010-01-19 00:59:36 +00:00
|
|
|
{
|
|
|
|
PyObject *submodule;
|
2010-09-08 10:43:36 +00:00
|
|
|
PyObject *submodule_dict;
|
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
submodule = PyModule_Create(&props_module);
|
2010-08-14 05:33:20 +00:00
|
|
|
PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
|
2010-01-19 00:59:36 +00:00
|
|
|
|
|
|
|
/* INCREF since its its assumed that all these functions return the
|
|
|
|
* module with a new ref like PyDict_New, since they are passed to
|
2011-04-21 05:49:47 +00:00
|
|
|
* PyModule_AddObject which steals a ref */
|
2010-01-19 00:59:36 +00:00
|
|
|
Py_INCREF(submodule);
|
2010-09-08 10:43:36 +00:00
|
|
|
|
|
|
|
/* api needs the PyObjects internally */
|
2011-12-26 12:26:11 +00:00
|
|
|
submodule_dict = PyModule_GetDict(submodule);
|
2010-09-08 10:43:36 +00:00
|
|
|
|
2011-12-26 12:26:11 +00:00
|
|
|
#define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name)
|
2010-09-08 10:43:36 +00:00
|
|
|
|
|
|
|
ASSIGN_STATIC(BoolProperty);
|
|
|
|
ASSIGN_STATIC(BoolVectorProperty);
|
|
|
|
ASSIGN_STATIC(IntProperty);
|
|
|
|
ASSIGN_STATIC(IntVectorProperty);
|
|
|
|
ASSIGN_STATIC(FloatProperty);
|
|
|
|
ASSIGN_STATIC(FloatVectorProperty);
|
|
|
|
ASSIGN_STATIC(StringProperty);
|
|
|
|
ASSIGN_STATIC(EnumProperty);
|
|
|
|
ASSIGN_STATIC(PointerProperty);
|
|
|
|
ASSIGN_STATIC(CollectionProperty);
|
|
|
|
ASSIGN_STATIC(RemoveProperty);
|
|
|
|
|
2010-01-19 00:59:36 +00:00
|
|
|
return submodule;
|
|
|
|
}
|