From 327b17b26f6afd7658fe5de0ca9f8bb0c2429f21 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 23 Jan 2013 21:55:11 +0000 Subject: [PATCH] Fix #31338: python enum properties can now specify icons for items, in the following order: (identifier, name, description, icon, unique number) This also works without the icon still, for compatibility. --- source/blender/makesrna/intern/rna_ui_api.c | 22 +++++++------- source/blender/python/intern/bpy_props.c | 32 +++++++++++++++++---- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 22a9ec72f0f..787a5d6487e 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -42,6 +42,17 @@ #include "rna_internal.h" +#define DEF_ICON_BLANK_SKIP +#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""}, +#define DEF_VICO(name) {VICO_##name, (#name), 0, (#name), ""}, +EnumPropertyItem icon_items[] = { +#include "UI_icons.h" + {0, NULL, 0, NULL, NULL} +}; +#undef DEF_ICON_BLANK_SKIP +#undef DEF_ICON +#undef DEF_VICO + #ifdef RNA_RUNTIME static void rna_uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name, int icon, @@ -181,17 +192,6 @@ static int rna_ui_get_enum_icon(bContext *C, PointerRNA *ptr, const char *propna #else -#define DEF_ICON_BLANK_SKIP -#define DEF_ICON(name) {ICON_##name, (#name), 0, (#name), ""}, -#define DEF_VICO(name) {VICO_##name, (#name), 0, (#name), ""}, -EnumPropertyItem icon_items[] = { -#include "UI_icons.h" - {0, NULL, 0, NULL, NULL} -}; -#undef DEF_ICON_BLANK_SKIP -#undef DEF_ICON -#undef DEF_VICO - static void api_ui_item_common(FunctionRNA *func) { PropertyRNA *prop; diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index f5033a97861..b42fdbd0ca4 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -1259,6 +1259,20 @@ static size_t strswapbufcpy(char *buf, const char **orig) } #endif +static int icon_id_from_name(const char *name) +{ + EnumPropertyItem *item; + int id; + + if (name[0]) { + for (item = icon_items, id = 0; item->identifier; item++, id++) + if (strcmp(item->name, name) == 0) + return item->value; + } + + return 0; +} + static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) { EnumPropertyItem *items; @@ -1305,6 +1319,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i for (i = 0; i < seq_len; i++) { EnumPropertyItem tmp = {0, "", 0, "", ""}; + const char *tmp_icon = NULL; Py_ssize_t item_size; Py_ssize_t id_str_size; Py_ssize_t name_str_size; @@ -1314,12 +1329,14 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i if ((PyTuple_CheckExact(item)) && (item_size = PyTuple_GET_SIZE(item)) && - (item_size == 3 || item_size == 4) && + (item_size >= 3 && item_size <= 5) && (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && /* TODO, number isn't ensured to be unique from the script author */ - (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) + (item_size != 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1) && + (item_size != 5 || ((tmp_icon = _PyUnicode_AsString(PyTuple_GET_ITEM(item, 3))) && + py_long_as_int(PyTuple_GET_ITEM(item, 4), &tmp.value) != -1))) { if (is_enum_flag) { if (item_size < 4) { @@ -1342,6 +1359,9 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i } } + if (tmp_icon) + tmp.icon = icon_id_from_name(tmp_icon); + items[i] = tmp; /* calculate combine string length */ @@ -1351,8 +1371,8 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i MEM_freeN(items); PyErr_SetString(PyExc_TypeError, "EnumProperty(...): expected a tuple containing " - "(identifier, name, description) and optionally a " - "unique number"); + "(identifier, name, description) and optionally an " + "icon name and unique number"); return NULL; } @@ -2503,7 +2523,7 @@ BPY_PROPDEF_DESC_DOC " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG', 'LIBRARY_EDITABLE'].\n" " :type options: set\n" " :arg items: sequence of enum items formatted:\n" -" [(identifier, name, description, number), ...] where the identifier is used\n" +" [(identifier, name, description, icon, number), ...] where the identifier is used\n" " for python access and other values are used for the interface.\n" " Note the item is optional.\n" " For dynamic values a callback can be passed which returns a list in\n" @@ -2511,7 +2531,7 @@ BPY_PROPDEF_DESC_DOC " This function must take 2 arguments (self, context)\n" " WARNING: Do not use generators here (they will work the first time, but will lead to empty values\n" " in some unload/reload scenarii)!\n" -" :type items: sequence of string triplets or a function\n" +" :type items: sequence of string triples or a function\n" BPY_PROPDEF_UPDATE_DOC ); static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)