use a metaclass to have operator attributes register and display in the order defined.

This commit is contained in:
Campbell Barton 2009-11-20 20:58:46 +00:00
parent 19aa69f6f2
commit 34e7eb1676
4 changed files with 82 additions and 38 deletions

@ -92,3 +92,18 @@ class MeshFace(StructRNA):
return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0]) return ord_ind(verts[0], verts[1]), ord_ind(verts[1], verts[2]), ord_ind(verts[2], verts[3]), ord_ind(verts[3], verts[0])
edge_keys = property(_get_edge_keys) edge_keys = property(_get_edge_keys)
import collections
class OrderedMeta(type):
def __init__(cls, name, bases, attributes):
super(OrderedMeta, cls).__init__(name, bases, attributes)
cls.order = list(attributes.keys())
def __prepare__(name, bases, **kwargs):
return collections.OrderedDict()
class Operator(StructRNA, metaclass=OrderedMeta):
'''
Only defined so operators members can be used by accessing self.order
'''
pass

@ -138,14 +138,13 @@ class WM_OT_properties_edit(bpy.types.Operator):
'''Internal use (edit a property path)''' '''Internal use (edit a property path)'''
bl_idname = "wm.properties_edit" bl_idname = "wm.properties_edit"
bl_label = "Edit Property!" bl_label = "Edit Property!"
description = StringProperty(name="Tip", default="")
path = rna_path
value = rna_value
property = rna_property
path = rna_path
property = rna_property
value = rna_value
min = rna_min min = rna_min
max = rna_max max = rna_max
description = StringProperty(name="Tip", default="")
# the class instance is not persistant, need to store in the class # the class instance is not persistant, need to store in the class
# not ideal but changes as the op runs. # not ideal but changes as the op runs.

@ -294,7 +294,6 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
* later */ * later */
RNA_def_struct_identifier(ot->srna, ot->idname); RNA_def_struct_identifier(ot->srna, ot->idname);
if(pyrna_deferred_register_props(ot->srna, item)!=0) { if(pyrna_deferred_register_props(ot->srna, item)!=0) {
/* failed to register operator props */ /* failed to register operator props */
PyErr_Print(); PyErr_Print();

@ -3550,55 +3550,86 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL; return NULL;
} }
int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
static int deferred_register_prop(StructRNA *srna, PyObject *item, PyObject *key, PyObject *dummy_args)
{ {
PyObject *dummy_args, *item, *key; /* We only care about results from C which
Py_ssize_t pos = 0; * are for sure types, save some time with error */
if(PyTuple_CheckExact(item) && PyTuple_GET_SIZE(item)==2) {
dummy_args = PyTuple_New(0);
while (PyDict_Next(class_dict, &pos, &key, &item)) {
PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret; PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
/* We only care about results from C which
* are for sure types, save some time with error */
if(PyTuple_CheckExact(item)) {
if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *); if(PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
/* not 100% nice :/, modifies the dict passed, should be ok */ PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
PyDict_SetItemString(py_kw, "attr", key);
py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw); pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
Py_DECREF(py_srna_cobject); py_srna_cobject = PyCObject_FromVoidPtr(srna, NULL);
if(py_ret) { /* not 100% nice :/, modifies the dict passed, should be ok */
Py_DECREF(py_ret); PyDict_SetItemString(py_kw, "attr", key);
}
else {
PyErr_Print();
PyErr_Clear();
PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key)); py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
Py_DECREF(dummy_args); Py_DECREF(py_srna_cobject);
return -1;
} if(py_ret) {
Py_DECREF(py_ret);
} }
else { else {
/* Since this is a class dict, ignore args that can't be passed */ PyErr_Print();
/* for testing only */
/* PyObSpit("Why doesn't this work??", item);
PyErr_Print(); */
PyErr_Clear(); PyErr_Clear();
PyErr_Format(PyExc_ValueError, "StructRNA \"%.200s\" registration error: %.200s could not register\n", RNA_struct_identifier(srna), _PyUnicode_AsString(key));
Py_DECREF(dummy_args);
return -1;
} }
} }
else {
/* Since this is a class dict, ignore args that can't be passed */
/* for testing only */
/* PyObSpit("Why doesn't this work??", item);
PyErr_Print(); */
PyErr_Clear();
}
}
return 0;
}
int pyrna_deferred_register_props(StructRNA *srna, PyObject *class_dict)
{
PyObject *item, *key;
PyObject *order;
PyObject *dummy_args;
Py_ssize_t pos = 0;
int ret;
dummy_args = PyTuple_New(0);
order= PyDict_GetItemString(class_dict, "order");
if(order && PyList_Check(order)) {
printf("using order\n");
for(pos= 0; pos<PyList_GET_SIZE(order); pos++) {
key= PyList_GET_ITEM(order, pos);
item= PyDict_GetItem(class_dict, key);
ret= deferred_register_prop(srna, item, key, dummy_args);
if(ret==-1)
break;
}
}
else {
while (PyDict_Next(class_dict, &pos, &key, &item)) {
ret= deferred_register_prop(srna, item, key, dummy_args);
if(ret==-1)
break;
}
} }
Py_DECREF(dummy_args); Py_DECREF(dummy_args);
return 0; return 0;
} }