Exemplo n.º 1
0
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
	StructRNA *srna;

	BPY_PROPDEF_HEAD(EnumProperty)
	
	if(srna) {
		static const char *kwlist[] = {"attr", "items", "name", "description", "default", "options", NULL};
		const char *id=NULL, *name="", *description="";
		PyObject *def= NULL;
		int id_len;
		int defvalue=0;
		PyObject *items, *items_fast;
		EnumPropertyItem *eitems;
		PropertyRNA *prop;
		PyObject *pyopts= NULL;
		int opts=0;

		if (!PyArg_ParseTupleAndKeywords(args, kw, "s#O|ssOO!:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts))
			return NULL;

		BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items)

		if(!(items_fast= PySequence_Fast(items, "EnumProperty(...): expected a sequence of tuples for the enum items"))) {
			return NULL;
		}

		eitems= enum_items_from_py(items_fast, def, &defvalue, (opts & PROP_ENUM_FLAG)!=0);

		Py_DECREF(items_fast);

		if(!eitems)
			return NULL;

		if(opts & PROP_ENUM_FLAG)	prop= RNA_def_enum_flag(srna, id, eitems, defvalue, name, description);
		else						prop= RNA_def_enum(srna, id, eitems, defvalue, name, 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);
		}
		RNA_def_property_duplicate_pointers(srna, prop);
		MEM_freeN(eitems);
	}
	Py_RETURN_NONE;
}
Exemplo n.º 2
0
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
	StructRNA *srna;

	BPY_PROPDEF_HEAD(EnumProperty)
	
	if(srna) {
		static const char *kwlist[]= {"attr", "items", "name", "description", "default", "options", "update", NULL};
		const char *id=NULL, *name="", *description="";
		PyObject *def= NULL;
		int id_len;
		int defvalue=0;
		PyObject *items, *items_fast;
		EnumPropertyItem *eitems;
		PropertyRNA *prop;
		PyObject *pyopts= NULL;
		int opts=0;
		short is_itemf= FALSE;
		PyObject *update_cb= NULL;

		if (!PyArg_ParseTupleAndKeywords(args, kw,
		                                 "s#O|ssOO!O:EnumProperty",
		                                 (char **)kwlist, &id, &id_len,
		                                 &items, &name, &description,
		                                 &def, &PySet_Type, &pyopts,
		                                 &update_cb))
		{
			return NULL;
		}

		BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items)

		if (bpy_prop_callback_check(update_cb, 2) == -1) {
			return NULL;
		}

		/* items can be a list or a callable */
		if(PyFunction_Check(items)) { /* dont use PyCallable_Check because we need the function code for errors */
			PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(items);
			if(f_code->co_argcount != 2) {
				PyErr_Format(PyExc_ValueError,
				             "EnumProperty(...): expected 'items' function to take 2 arguments, not %d",
				             f_code->co_argcount);
				return NULL;
			}

			if(def) {
				/* note, using type error here is odd but python does this for invalid arguments */
				PyErr_SetString(PyExc_TypeError,
				                "EnumProperty(...): 'default' can't be set when 'items' is a function");
				return NULL;
			}

			is_itemf= TRUE;
			eitems= DummyRNA_NULL_items;
		}
		else {
			if(!(items_fast= PySequence_Fast(items, "EnumProperty(...): expected a sequence of tuples for the enum items or a function"))) {
				return NULL;
			}

			eitems= enum_items_from_py(items_fast, def, &defvalue, (opts & PROP_ENUM_FLAG)!=0);

			Py_DECREF(items_fast);

			if(!eitems) {
				return NULL;
			}
		}

		if(opts & PROP_ENUM_FLAG)	prop= RNA_def_enum_flag(srna, id, eitems, defvalue, name, description);
		else						prop= RNA_def_enum(srna, id, eitems, defvalue, name, description);

		if(is_itemf) {
			RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
			RNA_def_enum_py_data(prop, (void *)items);
			/* Py_INCREF(items); */ /* watch out!, if user is tricky they can probably crash blender if they manage to free the callback, take care! */
		}

		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);
		}
		bpy_prop_callback_assign(prop, update_cb);
		RNA_def_property_duplicate_pointers(srna, prop);

		if(is_itemf == FALSE) {
			MEM_freeN(eitems);
		}
	}
	Py_RETURN_NONE;
}
Exemplo n.º 3
0
static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
{
	PyGILState_STATE gilstate;

	PyObject *py_func= RNA_property_enum_py_data_get(prop);
	PyObject *self= NULL;
	PyObject *args;
	PyObject *items; /* returned from the function call */

	EnumPropertyItem *eitems= NULL;
	int err= 0;

	bpy_context_set(C, &gilstate);

	args= PyTuple_New(2);
	self= pyrna_struct_as_instance(ptr);
	PyTuple_SET_ITEM(args, 0, self);

	/* now get the context */
	PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
	Py_INCREF(bpy_context_module);

	items= PyObject_CallObject(py_func, args);

	Py_DECREF(args);

	if(items==NULL) {
		err= -1;
	}
	else {
		PyObject *items_fast;
		int defvalue_dummy=0;

		if(!(items_fast= PySequence_Fast(items, "EnumProperty(...): return value from the callback was not a sequence"))) {
			err= -1;
		}
		else {
			eitems= enum_items_from_py(items_fast, NULL, &defvalue_dummy, (RNA_property_flag(prop) & PROP_ENUM_FLAG)!=0);

			Py_DECREF(items_fast);

			if(!eitems) {
				err= -1;
			}
		}

		Py_DECREF(items);
	}

	if(err != -1) { /* worked */
		*free= 1;
	}
	else {
		printf_func_error(py_func);

		eitems= DummyRNA_NULL_items;
	}


	bpy_context_clear(C, &gilstate);
	return eitems;
}