This patch adds support in bpy.props for getter/setter callback functions. We already have update callbacks, but generic get/set functions can come in handy in some cases where the functionality is too complex to use a single value.
The current C callback functions are too simple allow a straightforward implementation, in particular they don't receive the PropertyRNA pointer itself as an argument, which means the callback cannot directly access the PropertyRNA's py_data pointers which store the python function objects. For this reason a second runtime variant of these callbacks has been added. It is only used for runtime callbacks and not in makesrna, but otherwise works the same way.
This commit is contained in:
@@ -112,6 +112,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* array utility function */
|
||||
PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type,
|
||||
const short is_double, const char *error_prefix)
|
||||
{
|
||||
PyObject *tuple;
|
||||
int i;
|
||||
|
||||
tuple = PyTuple_New(length);
|
||||
|
||||
/* for each type */
|
||||
if (type == &PyFloat_Type) {
|
||||
if (is_double) {
|
||||
const double *array_double = array;
|
||||
for (i = 0; i < length; ++i) {
|
||||
PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
const float *array_float = array;
|
||||
for (i = 0; i < length; ++i) {
|
||||
PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == &PyLong_Type) {
|
||||
/* could use is_double for 'long int' but no use now */
|
||||
const int *array_int = array;
|
||||
for (i = 0; i < length; ++i) {
|
||||
PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i]));
|
||||
}
|
||||
}
|
||||
else if (type == &PyBool_Type) {
|
||||
const int *array_bool = array;
|
||||
for (i = 0; i < length; ++i) {
|
||||
PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
Py_DECREF(tuple);
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s: internal error %s is invalid",
|
||||
error_prefix, type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tuple;
|
||||
}
|
||||
|
||||
|
||||
/* for debugging */
|
||||
void PyC_ObSpit(const char *name, PyObject *var)
|
||||
|
||||
@@ -39,6 +39,8 @@ void PyC_FileAndNum(const char **filename, int *lineno);
|
||||
void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */
|
||||
int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
|
||||
const PyTypeObject *type, const short is_double, const char *error_prefix);
|
||||
PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type,
|
||||
const short is_double, const char *error_prefix);
|
||||
|
||||
/* follow http://www.python.org/dev/peps/pep-0383/ */
|
||||
PyObject * PyC_UnicodeFromByte(const char *str);
|
||||
|
||||
@@ -50,9 +50,11 @@
|
||||
#include "../generic/py_capi_utils.h"
|
||||
|
||||
/* initial definition of callback slots we'll probably have more then 1 */
|
||||
#define BPY_DATA_CB_SLOT_SIZE 1
|
||||
#define BPY_DATA_CB_SLOT_SIZE 3
|
||||
|
||||
#define BPY_DATA_CB_SLOT_UPDATE 0
|
||||
#define BPY_DATA_CB_SLOT_GET 1
|
||||
#define BPY_DATA_CB_SLOT_SET 2
|
||||
|
||||
extern BPy_StructRNA *bpy_context_module;
|
||||
|
||||
@@ -234,43 +236,810 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc
|
||||
}
|
||||
}
|
||||
|
||||
static int bpy_prop_callback_check(PyObject *py_func, int argcount)
|
||||
static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
|
||||
{
|
||||
if (py_func && py_func != Py_None) {
|
||||
if (!PyFunction_Check(py_func)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"update keyword: expected a function type, not a %.200s",
|
||||
Py_TYPE(py_func)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
|
||||
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;
|
||||
}
|
||||
}
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int value;
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
value = FALSE;
|
||||
}
|
||||
else {
|
||||
value = PyLong_AsLong(ret);
|
||||
|
||||
if (value == -1 && PyErr_Occurred()) {
|
||||
printf_func_error(py_func);
|
||||
value = FALSE;
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
|
||||
static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
|
||||
{
|
||||
/* assume this is already checked for type and arg length */
|
||||
if (update_cb && update_cb != Py_None) {
|
||||
PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
|
||||
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
|
||||
py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
|
||||
RNA_def_py_data(prop, py_data);
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value));
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int i, len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
values[i] = FALSE;
|
||||
}
|
||||
else {
|
||||
if (ret && PyC_AsArray(values, ret, len, &PyBool_Type, FALSE, "BoolVectorProperty get") < 0) {
|
||||
printf_func_error(py_func);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
values[i] = FALSE;
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
PyObject *py_values;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
py_values = PyC_FromArray(values, len, &PyBool_Type, FALSE, "BoolVectorProperty set");
|
||||
if (!py_values) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else
|
||||
PyTuple_SET_ITEM(args, 1, py_values);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int value;
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
value = 0.0f;
|
||||
}
|
||||
else {
|
||||
value = PyLong_AsLong(ret);
|
||||
|
||||
if (value == -1 && PyErr_Occurred()) {
|
||||
printf_func_error(py_func);
|
||||
value = 0;
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int i, len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
values[i] = 0;
|
||||
}
|
||||
else {
|
||||
if (ret && PyC_AsArray(values, ret, len, &PyLong_Type, FALSE, "IntVectorProperty get") < 0) {
|
||||
printf_func_error(py_func);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
values[i] = 0;
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
PyObject *py_values;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
py_values = PyC_FromArray(values, len, &PyLong_Type, FALSE, "IntVectorProperty set");
|
||||
if (!py_values) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else
|
||||
PyTuple_SET_ITEM(args, 1, py_values);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
float value;
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
value = 0.0f;
|
||||
}
|
||||
else {
|
||||
value = PyFloat_AsDouble(ret);
|
||||
|
||||
if (value == -1.0f && PyErr_Occurred()) {
|
||||
printf_func_error(py_func);
|
||||
value = 0.0f;
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value));
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int i, len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
values[i] = 0.0f;
|
||||
}
|
||||
else {
|
||||
if (ret && PyC_AsArray(values, ret, len, &PyFloat_Type, FALSE, "FloatVectorProperty get") < 0) {
|
||||
printf_func_error(py_func);
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
values[i] = 0.0f;
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
PyObject *py_values;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
py_values = PyC_FromArray(values, len, &PyFloat_Type, FALSE, "FloatVectorProperty set");
|
||||
if (!py_values) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else
|
||||
PyTuple_SET_ITEM(args, 1, py_values);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
value[0] = '\0';
|
||||
}
|
||||
else {
|
||||
Py_ssize_t length;
|
||||
char *buffer = _PyUnicode_AsStringAndSize(ret, &length);
|
||||
|
||||
if (!buffer && PyErr_Occurred()) {
|
||||
printf_func_error(py_func);
|
||||
value[0] = '\0';
|
||||
}
|
||||
else {
|
||||
memcpy(value, buffer, length+1);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int length;
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
length = PyUnicode_GetLength(ret);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
PyObject *py_value;
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
py_value = PyUnicode_FromString(value);
|
||||
if (!py_value) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be a string");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else
|
||||
PyTuple_SET_ITEM(args, 1, py_value);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
int value;
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_GET];
|
||||
|
||||
args = PyTuple_New(1);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
value = RNA_property_enum_get_default(ptr, prop);
|
||||
}
|
||||
else {
|
||||
value = PyLong_AsLong(ret);
|
||||
|
||||
if (value == -1 && PyErr_Occurred()) {
|
||||
printf_func_error(py_func);
|
||||
value = RNA_property_enum_get_default(ptr, prop);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value)
|
||||
{
|
||||
PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
|
||||
PyObject *py_func;
|
||||
PyObject *args;
|
||||
PyObject *self;
|
||||
PyObject *ret;
|
||||
const int is_write_ok = pyrna_write_check();
|
||||
|
||||
BLI_assert(py_data != NULL);
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(TRUE);
|
||||
}
|
||||
|
||||
py_func = py_data[BPY_DATA_CB_SLOT_SET];
|
||||
|
||||
args = PyTuple_New(2);
|
||||
self = pyrna_struct_as_instance(ptr);
|
||||
PyTuple_SET_ITEM(args, 0, self);
|
||||
|
||||
PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value));
|
||||
|
||||
ret = PyObject_CallObject(py_func, args);
|
||||
|
||||
Py_DECREF(args);
|
||||
|
||||
if (ret == NULL) {
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
else {
|
||||
if (ret != Py_None) {
|
||||
PyErr_SetString(PyExc_ValueError, "the return value must be None");
|
||||
printf_func_error(py_func);
|
||||
}
|
||||
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
if (!is_write_ok) {
|
||||
pyrna_write_set(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* utility function we need for parsing int's in an if statement */
|
||||
@@ -285,702 +1054,6 @@ static int py_long_as_int(PyObject *py_long, int *r_int)
|
||||
}
|
||||
}
|
||||
|
||||
/* this define runs at the start of each function and deals with
|
||||
* returning a deferred property (to be registered later) */
|
||||
#define BPY_PROPDEF_HEAD(_func) \
|
||||
if (PyTuple_GET_SIZE(args) == 1) { \
|
||||
PyObject *ret; \
|
||||
self = PyTuple_GET_ITEM(args, 0); \
|
||||
args = PyTuple_New(0); \
|
||||
ret = BPy_##_func(self, args, kw); \
|
||||
Py_DECREF(args); \
|
||||
return ret; \
|
||||
} \
|
||||
else if (PyTuple_GET_SIZE(args) > 1) { \
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
||||
return NULL; \
|
||||
} \
|
||||
srna = srna_from_self(self, #_func"(...):"); \
|
||||
if (srna == NULL) { \
|
||||
if (PyErr_Occurred()) \
|
||||
return NULL; \
|
||||
return bpy_prop_deferred_return(pymeth_##_func, kw); \
|
||||
} (void)0
|
||||
|
||||
/* terse macros for error checks shared between all funcs cant use function
|
||||
* calls because of static strings passed to pyrna_set_to_enum_bitfield */
|
||||
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
||||
if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%.200s' too long, max length is %d", \
|
||||
id, MAX_IDPROP_NAME - 1); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (UNLIKELY(RNA_def_property_free_identifier(srna, id) == -1)) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%s' is defined as a non-dynamic type", \
|
||||
id); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (UNLIKELY(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \
|
||||
pyopts, \
|
||||
&opts, \
|
||||
#_func"(options={ ...}):"))) \
|
||||
{ \
|
||||
return NULL; \
|
||||
} (void)0
|
||||
|
||||
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
|
||||
BPY_PROPDEF_CHECK(_func, _property_flag_items); \
|
||||
if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, \
|
||||
pysubtype, \
|
||||
&subtype) == 0)) \
|
||||
{ \
|
||||
const char *enum_str = BPy_enum_as_string(_subtype); \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(subtype='%s'): " \
|
||||
"subtype not found in (%s)", \
|
||||
pysubtype, enum_str); \
|
||||
MEM_freeN((void *)enum_str); \
|
||||
return NULL; \
|
||||
} (void)0
|
||||
|
||||
|
||||
#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" \
|
||||
|
||||
|
||||
#define BPY_PROPDEF_UNIT_DOC \
|
||||
" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \
|
||||
" :type unit: string\n" \
|
||||
|
||||
|
||||
#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" \
|
||||
" *Warning* there are no safety checks to avoid infinite recursion.\n" \
|
||||
" :type update: function\n" \
|
||||
|
||||
#if 0
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Function that sets RNA, NOTE - self is NULL when called from python,
|
||||
* but being abused from C so we can pass the srna along.
|
||||
* This isn't incorrect since its a python object - but be careful */
|
||||
PyDoc_STRVAR(BPy_BoolProperty_doc,
|
||||
".. function:: BoolProperty(name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=False, "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"subtype='NONE', "
|
||||
"update=None)\n"
|
||||
"\n"
|
||||
" Returns a new boolean property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(BoolProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"options", "subtype", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
int def = 0;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssiO!sO:BoolProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&PySet_Type, &pyopts, &pysubtype,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
|
||||
RNA_def_property_boolean_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
|
||||
".. function:: BoolVectorProperty(name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=(False, False, False), "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"subtype='NONE', "
|
||||
"size=3, "
|
||||
"update=None)\n"
|
||||
"\n"
|
||||
" Returns a new vector boolean property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg default: sequence of booleans the length of *size*.\n"
|
||||
" :type default: sequence\n"
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
||||
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', "
|
||||
"'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
||||
" :type size: int\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(BoolVectorProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"options", "subtype", "size", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
int def[PYRNA_STACK_ARRAY] = {0};
|
||||
int size = 3;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pydef = NULL;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssOO!siO:BoolVectorProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &pydef,
|
||||
&PySet_Type, &pyopts, &pysubtype, &size,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items);
|
||||
|
||||
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"BoolVectorProperty(size=%d): size must be between 0 and "
|
||||
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description);
|
||||
prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
|
||||
RNA_def_property_array(prop, size);
|
||||
if (pydef) RNA_def_property_boolean_array_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_IntProperty_doc,
|
||||
".. 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"
|
||||
"\n"
|
||||
" Returns a new int property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(IntProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "options", "subtype", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssiiiiiiO!sO:IntProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &PySet_Type, &pyopts, &pysubtype,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_INT, subtype);
|
||||
RNA_def_property_int_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_IntVectorProperty_doc,
|
||||
".. 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"
|
||||
"\n"
|
||||
" Returns a new vector int property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg default: sequence of ints the length of *size*.\n"
|
||||
" :type default: sequence\n"
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
||||
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', "
|
||||
"'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
||||
" :type size: int\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(IntVectorProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "options", "subtype", "size", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
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;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pydef = NULL;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssOiiiiiO!siO:IntVectorProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &pydef,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &PySet_Type, &pyopts,
|
||||
&pysubtype, &size,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items);
|
||||
|
||||
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"IntVectorProperty(size=%d): size must be between 0 and "
|
||||
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_INT, subtype);
|
||||
RNA_def_property_array(prop, size);
|
||||
if (pydef) RNA_def_property_int_array_default(prop, def);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(BPy_FloatProperty_doc,
|
||||
".. 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"
|
||||
"\n"
|
||||
" Returns a new float property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UNIT_DOC
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(FloatProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "precision", "options", "subtype", "unit", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
|
||||
int precision = 2;
|
||||
PropertyRNA *prop;
|
||||
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;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssffffffiO!ssO:FloatProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &precision, &PySet_Type,
|
||||
&pyopts, &pysubtype, &pyunit,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items);
|
||||
|
||||
if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
|
||||
PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
|
||||
RNA_def_property_float_default(prop, def);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
|
||||
".. 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"
|
||||
"\n"
|
||||
" Returns a new vector float property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg default: sequence of floats the length of *size*.\n"
|
||||
" :type default: sequence\n"
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
||||
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', "
|
||||
"'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UNIT_DOC
|
||||
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
||||
" :type size: int\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(FloatVectorProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "precision", "options", "subtype", "unit", "size", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3;
|
||||
float def[PYRNA_STACK_ARRAY] = {0.0f};
|
||||
int precision = 2, size = 3;
|
||||
PropertyRNA *prop;
|
||||
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;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssOfffffiO!ssiO:FloatVectorProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &pydef,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &precision, &PySet_Type,
|
||||
&pyopts, &pysubtype, &pyunit, &size,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items);
|
||||
|
||||
if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
|
||||
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"FloatVectorProperty(size=%d): size must be between 0 and "
|
||||
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
|
||||
RNA_def_property_array(prop, size);
|
||||
if (pydef) RNA_def_property_float_array_default(prop, def);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_StringProperty_doc,
|
||||
".. function:: StringProperty(name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=\"\", "
|
||||
"maxlen=0, "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"subtype='NONE', "
|
||||
"update=None)\n"
|
||||
"\n"
|
||||
" Returns a new string property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(StringProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"maxlen", "options", "subtype", "update", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "", *def = "";
|
||||
int id_len;
|
||||
int maxlen = 0;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|sssiO!sO:StringProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&maxlen, &PySet_Type, &pyopts, &pysubtype,
|
||||
&update_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_STRING, subtype);
|
||||
if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
|
||||
if (def) RNA_def_property_string_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* copies orig to buf, then sets orig to buf, returns copy length */
|
||||
static size_t strswapbufcpy(char *buf, const char **orig)
|
||||
@@ -1142,7 +1215,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
|
||||
return items;
|
||||
}
|
||||
|
||||
static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
|
||||
static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
@@ -1208,13 +1281,1024 @@ static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *pt
|
||||
return eitems;
|
||||
}
|
||||
|
||||
static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount)
|
||||
{
|
||||
if (py_func && py_func != Py_None) {
|
||||
if (!PyFunction_Check(py_func)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s keyword: expected a function type, not a %.200s",
|
||||
keyword, Py_TYPE(py_func)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
|
||||
if (f_code->co_argcount != argcount) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%s keyword: expected a function taking %d arguments, not %d",
|
||||
keyword, argcount, f_code->co_argcount);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop)
|
||||
{
|
||||
PyObject **py_data = RNA_property_py_data_get(prop);
|
||||
if (!py_data) {
|
||||
py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
|
||||
RNA_def_py_data(prop, py_data);
|
||||
}
|
||||
return py_data;
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb)
|
||||
{
|
||||
/* assume this is already checked for type and arg length */
|
||||
if (update_cb && update_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
|
||||
py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
|
||||
|
||||
RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
BooleanPropertyGetFunc rna_get_cb = NULL;
|
||||
BooleanPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_boolean_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_boolean_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
BooleanArrayPropertyGetFunc rna_get_cb = NULL;
|
||||
BooleanArrayPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_boolean_array_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_boolean_array_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
IntPropertyGetFunc rna_get_cb = NULL;
|
||||
IntPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_int_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_int_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
IntArrayPropertyGetFunc rna_get_cb = NULL;
|
||||
IntArrayPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_int_array_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_int_array_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
FloatPropertyGetFunc rna_get_cb = NULL;
|
||||
FloatPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_float_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_float_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
FloatArrayPropertyGetFunc rna_get_cb = NULL;
|
||||
FloatArrayPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_float_array_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_float_array_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
|
||||
{
|
||||
StringPropertyGetFunc rna_get_cb = NULL;
|
||||
StringPropertyLengthFunc rna_length_cb = NULL;
|
||||
StringPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_string_get_cb;
|
||||
rna_length_cb = bpy_prop_string_length_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_string_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb);
|
||||
}
|
||||
|
||||
static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb)
|
||||
{
|
||||
EnumPropertyGetFunc rna_get_cb = NULL;
|
||||
EnumPropertyItemFunc rna_itemf_cb = NULL;
|
||||
EnumPropertySetFunc rna_set_cb = NULL;
|
||||
|
||||
if (get_cb && get_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_get_cb = bpy_prop_enum_get_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_GET] = get_cb;
|
||||
}
|
||||
|
||||
if (set_cb && set_cb != Py_None) {
|
||||
PyObject **py_data = bpy_prop_py_data_get(prop);
|
||||
|
||||
rna_set_cb = bpy_prop_enum_set_cb;
|
||||
py_data[BPY_DATA_CB_SLOT_SET] = set_cb;
|
||||
}
|
||||
|
||||
if (itemf_cb && itemf_cb != Py_None) {
|
||||
rna_itemf_cb = bpy_prop_enum_itemf_cb;
|
||||
RNA_def_property_enum_py_data(prop, (void *)itemf_cb);
|
||||
|
||||
/* watch out!, if a user is tricky they can probably crash blender
|
||||
* if they manage to free the callback, take care! */
|
||||
/* Py_INCREF(itemf_cb); */
|
||||
}
|
||||
|
||||
RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb);
|
||||
}
|
||||
|
||||
/* this define runs at the start of each function and deals with
|
||||
* returning a deferred property (to be registered later) */
|
||||
#define BPY_PROPDEF_HEAD(_func) \
|
||||
if (PyTuple_GET_SIZE(args) == 1) { \
|
||||
PyObject *ret; \
|
||||
self = PyTuple_GET_ITEM(args, 0); \
|
||||
args = PyTuple_New(0); \
|
||||
ret = BPy_##_func(self, args, kw); \
|
||||
Py_DECREF(args); \
|
||||
return ret; \
|
||||
} \
|
||||
else if (PyTuple_GET_SIZE(args) > 1) { \
|
||||
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
|
||||
return NULL; \
|
||||
} \
|
||||
srna = srna_from_self(self, #_func"(...):"); \
|
||||
if (srna == NULL) { \
|
||||
if (PyErr_Occurred()) \
|
||||
return NULL; \
|
||||
return bpy_prop_deferred_return(pymeth_##_func, kw); \
|
||||
} (void)0
|
||||
|
||||
/* terse macros for error checks shared between all funcs cant use function
|
||||
* calls because of static strings passed to pyrna_set_to_enum_bitfield */
|
||||
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
|
||||
if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%.200s' too long, max length is %d", \
|
||||
id, MAX_IDPROP_NAME - 1); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (UNLIKELY(RNA_def_property_free_identifier(srna, id) == -1)) { \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(): '%s' is defined as a non-dynamic type", \
|
||||
id); \
|
||||
return NULL; \
|
||||
} \
|
||||
if (UNLIKELY(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \
|
||||
pyopts, \
|
||||
&opts, \
|
||||
#_func"(options={ ...}):"))) \
|
||||
{ \
|
||||
return NULL; \
|
||||
} (void)0
|
||||
|
||||
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
|
||||
BPY_PROPDEF_CHECK(_func, _property_flag_items); \
|
||||
if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, \
|
||||
pysubtype, \
|
||||
&subtype) == 0)) \
|
||||
{ \
|
||||
const char *enum_str = BPy_enum_as_string(_subtype); \
|
||||
PyErr_Format(PyExc_TypeError, \
|
||||
#_func"(subtype='%s'): " \
|
||||
"subtype not found in (%s)", \
|
||||
pysubtype, enum_str); \
|
||||
MEM_freeN((void *)enum_str); \
|
||||
return NULL; \
|
||||
} (void)0
|
||||
|
||||
|
||||
#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" \
|
||||
|
||||
|
||||
#define BPY_PROPDEF_UNIT_DOC \
|
||||
" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \
|
||||
" :type unit: string\n" \
|
||||
|
||||
|
||||
#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" \
|
||||
" *Warning* there are no safety checks to avoid infinite recursion.\n" \
|
||||
" :type update: function\n" \
|
||||
|
||||
#if 0
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Function that sets RNA, NOTE - self is NULL when called from python,
|
||||
* but being abused from C so we can pass the srna along.
|
||||
* This isn't incorrect since its a python object - but be careful */
|
||||
PyDoc_STRVAR(BPy_BoolProperty_doc,
|
||||
".. function:: BoolProperty(name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=False, "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"subtype='NONE', "
|
||||
"update=None, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new boolean property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(BoolProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"options", "subtype", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
int def = 0;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssiO!sOOO:BoolProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&PySet_Type, &pyopts, &pysubtype,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
|
||||
RNA_def_property_boolean_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_boolean(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
|
||||
".. function:: BoolVectorProperty(name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=(False, False, False), "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"subtype='NONE', "
|
||||
"size=3, "
|
||||
"update=None, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new vector boolean property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg default: sequence of booleans the length of *size*.\n"
|
||||
" :type default: sequence\n"
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
||||
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', "
|
||||
"'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
||||
" :type size: int\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(BoolVectorProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"options", "subtype", "size", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
int def[PYRNA_STACK_ARRAY] = {0};
|
||||
int size = 3;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pydef = NULL;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssOO!siOOO:BoolVectorProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &pydef,
|
||||
&PySet_Type, &pyopts, &pysubtype, &size,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items);
|
||||
|
||||
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"BoolVectorProperty(size=%d): size must be between 0 and "
|
||||
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description);
|
||||
prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
|
||||
RNA_def_property_array(prop, size);
|
||||
if (pydef) RNA_def_property_boolean_array_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_IntProperty_doc,
|
||||
".. 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, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new int property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(IntProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "options", "subtype", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssiiiiiiO!sOOO:IntProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &PySet_Type, &pyopts, &pysubtype,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_INT, subtype);
|
||||
RNA_def_property_int_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_int(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_IntVectorProperty_doc,
|
||||
".. 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, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new vector int property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg default: sequence of ints the length of *size*.\n"
|
||||
" :type default: sequence\n"
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
||||
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', "
|
||||
"'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
||||
" :type size: int\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(IntVectorProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "options", "subtype", "size", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
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;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pydef = NULL;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssOiiiiiO!siOOO:IntVectorProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &pydef,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &PySet_Type, &pyopts,
|
||||
&pysubtype, &size,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items);
|
||||
|
||||
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"IntVectorProperty(size=%d): size must be between 0 and "
|
||||
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_INT, subtype);
|
||||
RNA_def_property_array(prop, size);
|
||||
if (pydef) RNA_def_property_int_array_default(prop, def);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_int_array(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(BPy_FloatProperty_doc,
|
||||
".. 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, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new float property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UNIT_DOC
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(FloatProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "precision", "options", "subtype",
|
||||
"unit", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
|
||||
int precision = 2;
|
||||
PropertyRNA *prop;
|
||||
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;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssffffffiO!ssOOO:FloatProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &precision, &PySet_Type,
|
||||
&pyopts, &pysubtype, &pyunit,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items);
|
||||
|
||||
if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
|
||||
PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
|
||||
RNA_def_property_float_default(prop, def);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_float(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
|
||||
".. 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, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new vector float property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg default: sequence of floats the length of *size*.\n"
|
||||
" :type default: sequence\n"
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', "
|
||||
"'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', "
|
||||
"'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UNIT_DOC
|
||||
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
|
||||
" :type size: int\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(FloatVectorProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"min", "max", "soft_min", "soft_max",
|
||||
"step", "precision", "options", "subtype",
|
||||
"unit", "size", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
int id_len;
|
||||
float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3;
|
||||
float def[PYRNA_STACK_ARRAY] = {0.0f};
|
||||
int precision = 2, size = 3;
|
||||
PropertyRNA *prop;
|
||||
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;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|ssOfffffiO!ssiOOO:FloatVectorProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &pydef,
|
||||
&min, &max, &soft_min, &soft_max,
|
||||
&step, &precision, &PySet_Type,
|
||||
&pyopts, &pysubtype, &pyunit, &size,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items);
|
||||
|
||||
if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
|
||||
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size < 1 || size > PYRNA_STACK_ARRAY) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"FloatVectorProperty(size=%d): size must be between 0 and "
|
||||
STRINGIFY(PYRNA_STACK_ARRAY), size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
|
||||
RNA_def_property_array(prop, size);
|
||||
if (pydef) RNA_def_property_float_array_default(prop, def);
|
||||
RNA_def_property_range(prop, min, max);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_float_array(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_StringProperty_doc,
|
||||
".. function:: StringProperty(name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=\"\", "
|
||||
"maxlen=0, "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"subtype='NONE', "
|
||||
"update=None, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new string property definition.\n"
|
||||
"\n"
|
||||
BPY_PROPDEF_NAME_DOC
|
||||
BPY_PROPDEF_DESC_DOC
|
||||
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n"
|
||||
" :type options: set\n"
|
||||
" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'NONE'].\n"
|
||||
" :type subtype: string\n"
|
||||
BPY_PROPDEF_UPDATE_DOC
|
||||
);
|
||||
static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
BPY_PROPDEF_HEAD(StringProperty);
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "name", "description", "default",
|
||||
"maxlen", "options", "subtype", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "", *def = "";
|
||||
int id_len;
|
||||
int maxlen = 0;
|
||||
PropertyRNA *prop;
|
||||
PyObject *pyopts = NULL;
|
||||
int opts = 0;
|
||||
char *pysubtype = NULL;
|
||||
int subtype = PROP_NONE;
|
||||
PyObject *update_cb = NULL;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#|sssiO!sOOO:StringProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&name, &description, &def,
|
||||
&maxlen, &PySet_Type, &pyopts, &pysubtype,
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_def_property(srna, id, PROP_STRING, subtype);
|
||||
if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
|
||||
if (def) RNA_def_property_string_default(prop, def);
|
||||
RNA_def_property_ui_text(prop, name ? name : id, description);
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_string(prop, get_cb, set_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(BPy_EnumProperty_doc,
|
||||
".. function:: EnumProperty(items, "
|
||||
"name=\"\", "
|
||||
"description=\"\", "
|
||||
"default=\"\", "
|
||||
"options={'ANIMATABLE'}, "
|
||||
"update=None)\n"
|
||||
"update=None, "
|
||||
"get=None, "
|
||||
"set=None)\n"
|
||||
"\n"
|
||||
" Returns a new enumerator property definition.\n"
|
||||
"\n"
|
||||
@@ -1246,7 +2330,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
|
||||
if (srna) {
|
||||
static const char *kwlist[] = {"attr", "items", "name", "description", "default",
|
||||
"options", "update", NULL};
|
||||
"options", "update", "get", "set", NULL};
|
||||
const char *id = NULL, *name = NULL, *description = "";
|
||||
PyObject *def = NULL;
|
||||
int id_len;
|
||||
@@ -1258,20 +2342,28 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
int opts = 0;
|
||||
short is_itemf = FALSE;
|
||||
PyObject *update_cb = NULL;
|
||||
PyObject *get_cb = NULL;
|
||||
PyObject *set_cb = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
"s#O|ssOO!O:EnumProperty",
|
||||
"s#O|ssOO!OOO:EnumProperty",
|
||||
(char **)kwlist, &id, &id_len,
|
||||
&items, &name, &description,
|
||||
&def, &PySet_Type, &pyopts,
|
||||
&update_cb))
|
||||
&update_cb, &get_cb, &set_cb))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items);
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(get_cb, "get", 1) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (bpy_prop_callback_check(set_cb, "set", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1314,22 +2406,14 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
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);
|
||||
|
||||
if (is_itemf) {
|
||||
RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
|
||||
RNA_def_enum_py_data(prop, (void *)items);
|
||||
|
||||
/* watch out!, if a user is tricky they can probably crash blender
|
||||
* if they manage to free the callback, take care! */
|
||||
/* Py_INCREF(items); */
|
||||
}
|
||||
|
||||
if (pyopts) {
|
||||
if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL));
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
|
||||
if (is_itemf == FALSE) {
|
||||
@@ -1424,7 +2508,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
|
||||
if (!ptype)
|
||||
return NULL;
|
||||
|
||||
if (bpy_prop_callback_check(update_cb, 2) == -1) {
|
||||
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1435,7 +2519,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
|
||||
if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
|
||||
}
|
||||
bpy_prop_callback_assign(prop, update_cb);
|
||||
bpy_prop_callback_assign_update(prop, update_cb);
|
||||
RNA_def_property_duplicate_pointers(srna, prop);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
|
||||
Reference in New Issue
Block a user