diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-07-10 23:56:13 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-07-10 23:56:13 +0400 |
commit | 2e3e044d27e90dc87bdce6af9cef77d9543e4d89 (patch) | |
tree | 4d87ed9c283fd99baf9d23d4b8ace0868972f156 /source | |
parent | a95c68a3eaa692f742e7f2e626b65daa71727c17 (diff) |
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
Diffstat (limited to 'source')
27 files changed, 382 insertions, 240 deletions
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index adcf2cfc024..fde270040a9 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -38,6 +38,7 @@ struct wmEvent; struct bContext; struct Object; struct uiLayout; +struct EnumPropertyItem; void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid); void transform_operatortypes(void); @@ -114,7 +115,7 @@ int BIF_menuselectTransformOrientation(void); void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts); void BIF_selectTransformOrientationValue(struct bContext *C, int orientation); -void BIF_menuTransformOrientation(struct bContext *C, struct uiLayout *layout, void *arg); +struct EnumPropertyItem *BIF_enumTransformOrientation(struct bContext *C); char * BIF_menustringTransformOrientation(const struct bContext *C, char *title); /* the returned value was allocated and needs to be freed after use */ int BIF_countTransformOrientation(const struct bContext *C); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 4fe28c2e457..391be4ba591 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1615,6 +1615,7 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor block= MEM_callocN(sizeof(uiBlock), "uiBlock"); block->active= 1; block->dt= dt; + block->evil_C= C; // XXX BLI_strncpy(block->name, name, sizeof(block->name)); if(region) @@ -2113,11 +2114,11 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1, /* use rna values if parameters are not specified */ if(!str) { if(type == MENU && proptype == PROP_ENUM) { - const EnumPropertyItem *item; + EnumPropertyItem *item; DynStr *dynstr; - int i, totitem, value; + int i, totitem, value, free; - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); value= RNA_property_enum_get(ptr, prop); dynstr= BLI_dynstr_new(); @@ -2136,13 +2137,16 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1, str= BLI_dynstr_get_cstring(dynstr); BLI_dynstr_free(dynstr); + if(free) + MEM_freeN(item); + freestr= 1; } else if(type == ROW && proptype == PROP_ENUM) { - const EnumPropertyItem *item; - int i, totitem; + EnumPropertyItem *item; + int i, totitem, free; - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); for(i=0; i<totitem; i++) { if(item[i].identifier[0] && item[i].value == (int)max) { str= (char*)item[i].name; @@ -2152,6 +2156,8 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1, if(!str) str= (char*)RNA_property_ui_name(prop); + if(free) + MEM_freeN(item); } else { str= (char*)RNA_property_ui_name(prop); @@ -2161,10 +2167,10 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1, if(!tip) { if(type == ROW && proptype == PROP_ENUM) { - const EnumPropertyItem *item; - int i, totitem; + EnumPropertyItem *item; + int i, totitem, free; - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); for(i=0; i<totitem; i++) { if(item[i].identifier[0] && item[i].value == (int)max) { @@ -2173,6 +2179,9 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1, break; } } + + if(free) + MEM_freeN(item); } } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 1b16155c7e6..8c254419ec3 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -290,6 +290,8 @@ struct uiBlock { int tooltipdisabled; // to avoid tooltip after click int active; // to keep blocks while drawing and free them afterwards + + void *evil_C; // XXX hack for dynamic operator enums }; typedef struct uiSafetyRct { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 8e880b10185..77af58bacc1 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -429,13 +429,13 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, char *uiname, int x, int y, int w, int h) { - const EnumPropertyItem *item; + EnumPropertyItem *item; const char *identifier; char *name; - int a, totitem, itemw, icon, value; + int a, totitem, itemw, icon, value, free; identifier= RNA_property_identifier(prop); - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1)); for(a=0; a<totitem; a++) { @@ -455,6 +455,9 @@ static void ui_item_enum_row(uiLayout *layout, uiBlock *block, PointerRNA *ptr, uiDefButR(block, ROW, 0, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL); } uiBlockSetCurLayout(block, layout); + + if(free) + MEM_freeN(item); } /* create label + button for RNA property */ @@ -545,7 +548,7 @@ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDPropert } } -static char *ui_menu_enumpropname(char *opname, char *propname, int retval) +static char *ui_menu_enumpropname(uiLayout *layout, char *opname, char *propname, int retval) { wmOperatorType *ot= WM_operatortype_find(opname); PointerRNA ptr; @@ -558,13 +561,18 @@ static char *ui_menu_enumpropname(char *opname, char *propname, int retval) prop= RNA_struct_find_property(&ptr, propname); if(prop) { - const EnumPropertyItem *item; - int totitem; + EnumPropertyItem *item; + int totitem, free; const char *name; - RNA_property_enum_items(&ptr, prop, &item, &totitem); - if(RNA_enum_name(item, retval, &name)) + RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, &totitem, &free); + if(RNA_enum_name(item, retval, &name)) { + if(free) MEM_freeN(item); return (char*)name; + } + + if(free) + MEM_freeN(item); } return ""; @@ -578,7 +586,7 @@ void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *pro RNA_enum_set(&ptr, propname, value); if(!name) - name= ui_menu_enumpropname(opname, propname, value); + name= ui_menu_enumpropname(layout, opname, propname, value); uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } @@ -598,16 +606,19 @@ void uiItemsEnumO(uiLayout *layout, char *opname, char *propname) prop= RNA_struct_find_property(&ptr, propname); if(prop && RNA_property_type(prop) == PROP_ENUM) { - const EnumPropertyItem *item; - int totitem, i; + EnumPropertyItem *item; + int totitem, i, free; - RNA_property_enum_items(&ptr, prop, &item, &totitem); + RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, &totitem, &free); for(i=0; i<totitem; i++) if(item[i].identifier[0]) uiItemEnumO(layout, (char*)item[i].name, item[i].icon, opname, propname, item[i].value); else uiItemS(layout); + + if(free) + MEM_freeN(item); } } @@ -618,18 +629,22 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch /* for getting the enum */ PropertyRNA *prop; - const EnumPropertyItem *item; - int value; + EnumPropertyItem *item; + int value, free; WM_operator_properties_create(&ptr, opname); /* enum lookup */ if((prop= RNA_struct_find_property(&ptr, propname))) { - RNA_property_enum_items(&ptr, prop, &item, NULL); + RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); if(RNA_enum_value_from_id(item, value_str, &value)==0) { + if(free) MEM_freeN(item); printf("uiItemEnumO_string: %s.%s, enum %s not found.\n", RNA_struct_identifier(ptr.type), propname, value_str); return; } + + if(free) + MEM_freeN(item); } else { printf("uiItemEnumO_string: %s.%s not found.\n", RNA_struct_identifier(ptr.type), propname); @@ -640,7 +655,7 @@ void uiItemEnumO_string(uiLayout *layout, char *name, int icon, char *opname, ch /* same as uiItemEnumO */ if(!name) - name= ui_menu_enumpropname(opname, propname, value); + name= ui_menu_enumpropname(layout, opname, propname, value); uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } @@ -845,8 +860,8 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, void uiItemEnumR_string(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, char *value) { PropertyRNA *prop; - const EnumPropertyItem *item; - int ivalue, a; + EnumPropertyItem *item; + int ivalue, a, free; if(!ptr->data || !propname) return; @@ -859,9 +874,10 @@ void uiItemEnumR_string(uiLayout *layout, char *name, int icon, struct PointerRN return; } - RNA_property_enum_items(ptr, prop, &item, NULL); + RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free); if(!RNA_enum_value_from_id(item, value, &ivalue)) { + if(free) MEM_freeN(item); ui_item_disabled(layout, propname); printf("uiItemEnumR: enum property value not found: %s\n", value); return; @@ -873,6 +889,9 @@ void uiItemEnumR_string(uiLayout *layout, char *name, int icon, struct PointerRN break; } } + + if(free) + MEM_freeN(item); } void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname) @@ -887,16 +906,19 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname) } if(RNA_property_type(prop) == PROP_ENUM) { - const EnumPropertyItem *item; - int totitem, i; + EnumPropertyItem *item; + int totitem, i, free; - RNA_property_enum_items(ptr, prop, &item, &totitem); + RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free); for(i=0; i<totitem; i++) if(item[i].identifier[0]) uiItemEnumR(layout, (char*)item[i].name, 0, ptr, propname, item[i].value); else uiItemS(layout); + + if(free) + MEM_freeN(item); } } diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index a680fb5d07a..cdd51a72f4f 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1606,13 +1606,13 @@ static int mesh_separate_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Base *base= CTX_data_active_base(C); - int retval= 0; + int retval= 0, type= RNA_enum_get(op->ptr, "type"); - if(RNA_enum_is_equal(op->ptr, "type", "SELECTED")) + if(type == 0) retval= mesh_separate_selected(scene, base); - else if(RNA_enum_is_equal(op->ptr, "type", "MATERIAL")) + else if(type == 1) retval= mesh_separate_material (scene, base); - else if(RNA_enum_is_equal(op->ptr, "type", "LOOSE")) + else if(type == 2) retval= mesh_separate_loose(scene, base); if(retval) { diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index ca0f73ece68..2995e2d895b 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -1227,12 +1227,29 @@ static int select_similar_exec(bContext *C, wmOperator *op) return similar_face_select_exec(C, op); } -static EnumPropertyItem *select_similar_type_itemf(PointerRNA *ptr) +static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free) { - /* XXX need context! */ - return prop_simface_types; - return prop_simvertex_types; - return prop_simedge_types; + Object *obedit= CTX_data_edit_object(C); + + if(obedit && obedit->type == OB_MESH) { + EditMesh *em= BKE_mesh_get_editmesh(obedit->data); + EnumPropertyItem *item= NULL; + int totitem= 0; + + if(em->selectmode & SCE_SELECT_VERTEX) + RNA_enum_items_add(&item, &totitem, prop_simvertex_types); + else if(em->selectmode & SCE_SELECT_EDGE) + RNA_enum_items_add(&item, &totitem, prop_simedge_types); + else if(em->selectmode & SCE_SELECT_FACE) + RNA_enum_items_add(&item, &totitem, prop_simface_types); + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; + } + + return NULL; } void MESH_OT_select_similar(wmOperatorType *ot) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 4377f459081..682b1ee4a64 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5799,29 +5799,38 @@ static EnumPropertyItem merge_type_items[]= { {5, "COLLAPSE", 0, "Collapse", ""}, {0, NULL, 0, NULL, NULL}}; -static EnumPropertyItem *merge_type_itemf(PointerRNA *ptr) +static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *free) { - /* XXX need context here */ -#if 0 - Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - if(em->selectmode & SCE_SELECT_VERTEX) - if(em->selected.first && em->selected.last && - ((EditSelection*)em->selected.first)->type == EDITVERT && ((EditSelection*)em->selected.last)->type == EDITVERT) - event = pupmenu("Merge %t|At First %x6|At Last%x1|At Center%x3|At Cursor%x4|Collapse%x2"); - else if (em->selected.first && ((EditSelection*)em->selected.first)->type == EDITVERT) - event = pupmenu("Merge %t|At First %x6|At Center%x3|At Cursor%x4|Collapse%x2"); - else if (em->selected.last && ((EditSelection*)em->selected.last)->type == EDITVERT) - event = pupmenu("Merge %t|At Last %x1|At Center%x3|At Cursor%x4|Collapse%x2"); - else event = pupmenu("Merge %t|At Center%x3|At Cursor%x4|Collapse%x2"); - else event = pupmenu("Merge %t|At Center%x3|At Cursor%x4|Collapse%x2"); + if(obedit && obedit->type == OB_MESH) { + EditMesh *em= BKE_mesh_get_editmesh(obedit->data); + EnumPropertyItem *item= NULL; + int totitem= 0; - BKE_mesh_end_editmesh(obedit->data, em); -#endif + if(em->selectmode & SCE_SELECT_VERTEX) { + if(em->selected.first && em->selected.last && + ((EditSelection*)em->selected.first)->type == EDITVERT && ((EditSelection*)em->selected.last)->type == EDITVERT) { + RNA_enum_item_add(&item, &totitem, &merge_type_items[0]); + RNA_enum_item_add(&item, &totitem, &merge_type_items[1]); + } + else if(em->selected.first && ((EditSelection*)em->selected.first)->type == EDITVERT) + RNA_enum_item_add(&item, &totitem, &merge_type_items[1]); + else if(em->selected.last && ((EditSelection*)em->selected.last)->type == EDITVERT) + RNA_enum_item_add(&item, &totitem, &merge_type_items[0]); + } + + RNA_enum_item_add(&item, &totitem, &merge_type_items[2]); + RNA_enum_item_add(&item, &totitem, &merge_type_items[3]); + RNA_enum_item_add(&item, &totitem, &merge_type_items[4]); + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; + } - return merge_type_items; + return NULL; } void MESH_OT_merge(wmOperatorType *ot) @@ -5841,7 +5850,7 @@ void MESH_OT_merge(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", merge_type_items, 6, "Type", "Merge method to use."); + prop= RNA_def_enum(ot->srna, "type", merge_type_items, 3, "Type", "Merge method to use."); RNA_def_enum_funcs(prop, merge_type_itemf); RNA_def_boolean(ot->srna, "uvs", 0, "UVs", "Move UVs according to merge."); } diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 6bc2f240859..cfe8dd4352d 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -75,7 +75,7 @@ static int vertex_specials_invoke(bContext *C, wmOperator *op, wmEvent *event) uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); uiItemO(layout, "Remove Doubles", 0, "MESH_OT_remove_doubles"); - uiItemO(layout, "Merge...", 0, "MESH_OT_merge"); // mergmenu(em) + uiItemO(layout, "Merge...", 0, "MESH_OT_merge"); uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth"); uiItemO(layout, "Select Vertex Path", 0, "MESH_OT_select_vertex_path"); //uiItemO(layout, "Blend From Shape", 0, "MESH_OT_blend_from_shape"); @@ -387,6 +387,7 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_colors_mirror",EIGHTKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_rip",VKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0); /* add/remove */ WM_keymap_add_item(keymap, "MESH_OT_edge_face_add", FKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 0a9ed945c1d..9ea8907e172 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1379,20 +1379,21 @@ static EnumPropertyItem prop_clear_parent_types[] = { /* note, poll should check for editable scene */ static int parent_clear_exec(bContext *C, wmOperator *op) { + int type= RNA_enum_get(op->ptr, "type"); CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(RNA_enum_is_equal(op->ptr, "type", "CLEAR")) { + if(type == 0) { ob->parent= NULL; } - if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) { + else if(type == 1) { ob->parent= NULL; ob->track= NULL; ED_object_apply_obmat(ob); } - if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_INVERSE")) { + else if(type == 2) Mat4One(ob->parentinv); - } + ob->recalc |= OB_RECALC; } CTX_DATA_END; @@ -1435,6 +1436,8 @@ static EnumPropertyItem prop_clear_track_types[] = { /* note, poll should check for editable scene */ static int object_track_clear_exec(bContext *C, wmOperator *op) { + int type= RNA_enum_get(op->ptr, "type"); + if(CTX_data_edit_object(C)) { BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode"); return OPERATOR_CANCELLED; @@ -1443,9 +1446,8 @@ static int object_track_clear_exec(bContext *C, wmOperator *op) ob->track= NULL; ob->recalc |= OB_RECALC; - if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) { + if(type == 1) ED_object_apply_obmat(ob); - } } CTX_DATA_END; @@ -2663,8 +2665,9 @@ static EnumPropertyItem prop_make_track_types[] = { static int track_set_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); + int type= RNA_enum_get(op->ptr, "type"); - if(RNA_enum_is_equal(op->ptr, "type", "TRACKTO")){ + if(type == 1) { bConstraint *con; bTrackToConstraint *data; @@ -2688,7 +2691,7 @@ static int track_set_exec(bContext *C, wmOperator *op) } CTX_DATA_END; } - else if(RNA_enum_is_equal(op->ptr, "type", "LOCKTRACK")){ + else if(type == 2) { bConstraint *con; bLockTrackConstraint *data; @@ -2712,7 +2715,7 @@ static int track_set_exec(bContext *C, wmOperator *op) } CTX_DATA_END; } - else if(RNA_enum_is_equal(op->ptr, "type", "OLDTRACK")){ + else { CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { if(base!=BASACT) { base->object->track= BASACT->object; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index a030603996c..868897b76ac 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -122,11 +122,6 @@ EnumPropertyItem sequencer_prop_effect_types[] = { }; /* mute operator */ -EnumPropertyItem sequencer_prop_operate_types[] = { /* better name? */ - {SEQ_SELECTED, "SELECTED", 0, "Selected", ""}, - {SEQ_UNSELECTED, "UNSELECTED", 0, "Unselected ", ""}, - {0, NULL, 0, NULL, NULL} -}; EnumPropertyItem prop_side_types[] = { {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""}, @@ -1491,8 +1486,7 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op) if(ed==NULL) return OPERATOR_CANCELLED; - selected= RNA_enum_is_equal(op->ptr, "type", "SELECTED"); - + selected= !RNA_boolean_get(op->ptr, "unselected"); for(seq= ed->seqbasep->first; seq; seq= seq->next) { if ((seq->flag & SEQ_LOCK)==0) { @@ -1528,7 +1522,7 @@ void SEQUENCER_OT_mute(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_enum(ot->srna, "type", sequencer_prop_operate_types, SEQ_SELECTED, "Type", ""); + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips."); } @@ -1543,8 +1537,7 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op) if(ed==NULL) return OPERATOR_CANCELLED; - selected= RNA_enum_is_equal(op->ptr, "type", "SELECTED"); - + selected= !RNA_boolean_get(op->ptr, "unselected"); for(seq= ed->seqbasep->first; seq; seq= seq->next) { if ((seq->flag & SEQ_LOCK)==0) { @@ -1580,7 +1573,7 @@ void SEQUENCER_OT_unmute(struct wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_enum(ot->srna, "type", sequencer_prop_operate_types, SEQ_SELECTED, "Type", ""); + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "UnMute unselected rather than selected strips."); } diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 82047272049..f561fb2ac43 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -116,11 +116,11 @@ void sequencer_keymap(wmWindowManager *wm) RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, 0, 0)->ptr, "type", SEQ_CUT_SOFT); RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", SEQ_CUT_HARD); - RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, 0, 0)->ptr, "type", SEQ_SELECTED); - RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", SEQ_UNSELECTED); + WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_mute", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1); - RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT, 0)->ptr, "type", SEQ_SELECTED); - RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "type", SEQ_UNSELECTED); + WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_unmute", HKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0)->ptr, "unselected", 1); WM_keymap_add_item(keymap, "SEQUENCER_OT_lock", LKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "SEQUENCER_OT_unlock", HKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 70dde481018..112847272e5 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -203,10 +203,10 @@ void view3d_keymap(wmWindowManager *wm) /* selection*/ WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1); WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index fedf3a30181..2537982210a 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -715,12 +715,6 @@ void view3d_lasso_select(bContext *C, ViewContext *vc, short mcords[][2], short } -static EnumPropertyItem lasso_select_types[] = { - {0, "SELECT", 0, "Select", ""}, - {1, "DESELECT", 0, "Deselect", ""}, - {0, NULL, 0, NULL, NULL} -}; - /* lasso operator gives properties, but since old code works with short array we convert */ @@ -747,7 +741,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) /* setup view context for argument to callbacks */ view3d_set_viewcontext(C, &vc); - select= RNA_enum_is_equal(op->ptr, "type", "SELECT"); + select= !RNA_boolean_get(op->ptr, "deselect"); view3d_lasso_select(C, &vc, mcords, i, select); return OPERATOR_FINISHED; @@ -769,7 +763,7 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot) ot->flag= OPTYPE_UNDO; RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); - RNA_def_enum(ot->srna, "type", lasso_select_types, 0, "Type", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items."); } @@ -1528,11 +1522,6 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) /* *****************Selection Operators******************* */ -static EnumPropertyItem prop_select_types[] = { - {0, "EXCLUSIVE", 0, "Exclusive", ""}, - {1, "EXTEND", 0, "Extend", ""}, - {0, NULL, 0, NULL, NULL} -}; /* ****** Border Select ****** */ void VIEW3D_OT_select_border(wmOperatorType *ot) @@ -1558,7 +1547,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); - RNA_def_enum(ot->srna, "type", prop_select_types, 0, "Type", ""); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first."); } /* ****** Mouse Select ****** */ @@ -1567,7 +1556,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) { Object *obedit= CTX_data_edit_object(C); - short extend= RNA_enum_is_equal(op->ptr, "type", "EXTEND"); + short extend= RNA_boolean_get(op->ptr, "extend"); view3d_operator_needs_opengl(C); @@ -1605,7 +1594,7 @@ void VIEW3D_OT_select(wmOperatorType *ot) ot->flag= OPTYPE_UNDO; /* properties */ - RNA_def_enum(ot->srna, "type", prop_select_types, 0, "Type", ""); + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first."); } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 97fb3531718..dcd34011eef 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -109,10 +109,6 @@ TransformModeItem transform_modes[] = static int select_orientation_exec(bContext *C, wmOperator *op) { int orientation = RNA_enum_get(op->ptr, "orientation"); - int custom_index= RNA_int_get(op->ptr, "custom_index");; - - if(orientation == V3D_MANIP_CUSTOM) - orientation += custom_index; BIF_selectTransformOrientationValue(C, orientation); @@ -126,20 +122,26 @@ static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event pup= uiPupMenuBegin(C, "Orientation", 0); layout= uiPupMenuLayout(pup); - BIF_menuTransformOrientation(C, layout, NULL); + uiItemsEnumO(layout, "TFM_OT_select_orientation", "orientation"); uiPupMenuEnd(C, pup); return OPERATOR_CANCELLED; } +static EnumPropertyItem *select_orientation_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + *free= 1; + return BIF_enumTransformOrientation(C); +} + void TFM_OT_select_orientation(struct wmOperatorType *ot) { + PropertyRNA *prop; static EnumPropertyItem orientation_items[]= { {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}, {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}, {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}, {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}, - {V3D_MANIP_CUSTOM, "CUSTOM", 0, "Custom", ""}, {0, NULL, 0, NULL, NULL}}; /* identifiers */ @@ -151,8 +153,8 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) ot->exec = select_orientation_exec; ot->poll = ED_operator_areaactive; - RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_CUSTOM, "Orientation", "DOC_BROKEN"); - RNA_def_int(ot->srna, "custom_index", 0, 0, INT_MAX, "Custom Index", "", 0, INT_MAX); + prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN"); + RNA_def_enum_funcs(prop, select_orientation_itemf); } static void transformops_exit(bContext *C, wmOperator *op) diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 1e065de94e1..f3b373f0e48 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -59,6 +59,8 @@ #include "UI_interface.h" +#include "RNA_define.h" + #include "transform.h" /* *********************** TransSpace ************************** */ @@ -354,19 +356,37 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation) { v3d->twmode = orientation; } -void BIF_menuTransformOrientation(bContext *C, uiLayout *layout, void *arg) +EnumPropertyItem *BIF_enumTransformOrientation(bContext *C) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts; - int i= V3D_MANIP_CUSTOM; + TransformOrientation *ts = transform_spaces->first; + EnumPropertyItem global = {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""}; + EnumPropertyItem normal = {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""}; + EnumPropertyItem local = {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""}; + EnumPropertyItem view = {V3D_MANIP_VIEW, "VIEW", 0, "View", ""}; + EnumPropertyItem sepr = {0, "", 0, NULL, NULL}; + EnumPropertyItem tmp = {0, "", 0, "", ""}; + EnumPropertyItem *item= NULL; + int i = V3D_MANIP_CUSTOM, totitem= 0; + + RNA_enum_item_add(&item, &totitem, &global); + RNA_enum_item_add(&item, &totitem, &normal); + RNA_enum_item_add(&item, &totitem, &local); + RNA_enum_item_add(&item, &totitem, &view); + + if(ts) + RNA_enum_item_add(&item, &totitem, &sepr); + + for(; ts; ts = ts->next) { + tmp.identifier = "CUSTOM"; + tmp.name= ts->name; + tmp.value = i++; + RNA_enum_item_add(&item, &totitem, &tmp); + } - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_GLOBAL); - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_LOCAL); - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_NORMAL); - uiItemEnumO(layout, NULL, 0, "TFM_OT_select_orientation", "orientation", V3D_MANIP_VIEW); + RNA_enum_item_end(&item, &totitem); - for(ts = transform_spaces->first; ts; ts = ts->next) - uiItemIntO(layout, ts->name, 0, "TFM_OT_select_orientation", "custom_index", i++); + return item; } char * BIF_menustringTransformOrientation(const bContext *C, char *title) { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 3b2520c41b2..93fbc8b5f17 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -548,12 +548,12 @@ void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax); void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision); -int RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **identifier); -int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **name); +int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier); +int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name); -void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem); -int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value); -int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier); +void RNA_property_enum_items(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free); +int RNA_property_enum_value(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value); +int RNA_property_enum_identifier(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier); StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop); @@ -677,11 +677,11 @@ void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values) int RNA_enum_get(PointerRNA *ptr, const char *name); void RNA_enum_set(PointerRNA *ptr, const char *name, int value); -int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname); +int RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname); /* lower level functions that donr use a PointerRNA */ -int RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *value); -int RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **identifier); +int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value); +int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier); void RNA_string_get(PointerRNA *ptr, const char *name, char *value); char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen); diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index 69f5b5adc37..a3fa97bf4b1 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -160,6 +160,13 @@ void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret); void RNA_def_function_flag(FunctionRNA *func, int flag); void RNA_def_function_ui_description(FunctionRNA *func, const char *description); +/* Dynamic Enums + * strings are not freed, assumed pointing to static location. */ + +void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item); +void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item); +void RNA_enum_item_end(EnumPropertyItem **items, int *totitem); + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 98646acd727..dc2a2a1a1de 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -157,7 +157,7 @@ typedef struct EnumPropertyItem { const char *description; } EnumPropertyItem; -typedef EnumPropertyItem *(*EnumPropertyItemFunc)(PointerRNA *ptr); +typedef EnumPropertyItem *(*EnumPropertyItemFunc)(struct bContext *C, PointerRNA *ptr, int *free); typedef struct PropertyRNA PropertyRNA; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index ec509dbf863..5230c260dbd 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1597,7 +1597,6 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr DefRNA.error= 1; } } - else if(eprop->itemf); else { fprintf(stderr, "rna_generate_structs: %s%s.%s, enum must have items defined.\n", srna->identifier, errnest, prop->identifier); DefRNA.error= 1; diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 42f6250728f..f20df81d6ad 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -640,17 +640,19 @@ StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop) return &RNA_UnknownType; } -void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem) +void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free) { EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop); int tot; - if(eprop->itemf) { - *item= eprop->itemf(ptr); - if(totitem) { + *free= 0; + + if(C && eprop->itemf) { + *item= eprop->itemf(C, ptr, free); + + if(totitem) for(tot=0; (*item)[tot].identifier; tot++); - *totitem= tot; - } + *totitem= tot; } else { *item= eprop->item; @@ -659,11 +661,12 @@ void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPrope } } -int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value) +int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value) { - const EnumPropertyItem *item; + EnumPropertyItem *item; + int free; - RNA_property_enum_items(ptr, prop, &item, NULL); + RNA_property_enum_items(C, ptr, prop, &item, NULL, &free); for(; item->identifier; item++) { if(item->identifier[0] && strcmp(item->identifier, identifier)==0) { @@ -672,10 +675,13 @@ int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *iden } } + if(free) + MEM_freeN(item); + return 0; } -int RNA_enum_identifier(const EnumPropertyItem *item, const int value, const char **identifier) +int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier) { for (; item->identifier; item++) { if(item->identifier[0] && item->value==value) { @@ -686,7 +692,7 @@ int RNA_enum_identifier(const EnumPropertyItem *item, const int value, const cha return 0; } -int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **name) +int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name) { for (; item->identifier; item++) { if(item->identifier[0] && item->value==value) { @@ -697,12 +703,17 @@ int RNA_enum_name(const EnumPropertyItem *item, const int value, const char **na return 0; } -int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier) +int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier) { - const EnumPropertyItem *item= NULL; + EnumPropertyItem *item= NULL; + int result, free; - RNA_property_enum_items(ptr, prop, &item, NULL); - return RNA_enum_identifier(item, value, identifier); + RNA_property_enum_items(C, ptr, prop, &item, NULL, &free); + result= RNA_enum_identifier(item, value, identifier); + if(free) + MEM_freeN(item); + + return result; } const char *RNA_property_ui_name(PropertyRNA *prop) @@ -2384,18 +2395,22 @@ void RNA_enum_set(PointerRNA *ptr, const char *name, int value) printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name); } -int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname) +int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname) { PropertyRNA *prop= RNA_struct_find_property(ptr, name); - const EnumPropertyItem *item; + EnumPropertyItem *item; + int free; if(prop) { - RNA_property_enum_items(ptr, prop, &item, NULL); + RNA_property_enum_items(C, ptr, prop, &item, NULL, &free); for(; item->identifier; item++) if(strcmp(item->identifier, enumname) == 0) return (item->value == RNA_property_enum_get(ptr, prop)); + if(free) + MEM_freeN(item); + printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname); return 0; } @@ -2405,7 +2420,7 @@ int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname) } } -int RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *value) +int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value) { for( ; item->identifier; item++) { if(strcmp(item->identifier, identifier)==0) { @@ -2417,7 +2432,7 @@ int RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, return 0; } -int RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **identifier) +int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier) { for( ; item->identifier; item++) { if(item->value==value) { @@ -2659,7 +2674,7 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) const char *identifier; int val = RNA_property_enum_get(ptr, prop); - if(RNA_property_enum_identifier(ptr, prop, val, &identifier)) { + if(RNA_property_enum_identifier(NULL, ptr, prop, val, &identifier)) { BLI_dynstr_appendf(dynstr, "'%s'", identifier); } else { diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index cda1716f664..cd3642f65a2 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -68,6 +68,17 @@ EnumPropertyItem constraint_type_items[] ={ {CONSTRAINT_TYPE_NULL, "NULL", 0, "Null", ""}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem space_pchan_items[] = { + {0, "WORLD", 0, "World Space", ""}, + {2, "POSE", 0, "Pose Space", ""}, + {3, "LOCAL_WITH_PARENT", 0, "Local With Parent", ""}, + {1, "LOCAL", 0, "Local Space", ""}, + {0, NULL, 0, NULL, NULL}}; + +EnumPropertyItem space_object_items[] = { + {0, "WORLD", 0, "World Space", ""}, + {1, "LOCAL", 0, "Local (Without Parent) Space", ""}, + {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME @@ -166,19 +177,7 @@ static void rna_Constraint_influence_update(bContext *C, PointerRNA *ptr) rna_Constraint_update(C, ptr); } -static EnumPropertyItem space_pchan_items[] = { - {0, "WORLD", 0, "World Space", ""}, - {2, "POSE", 0, "Pose Space", ""}, - {3, "LOCAL_WITH_PARENT", 0, "Local With Parent", ""}, - {1, "LOCAL", 0, "Local Space", ""}, - {0, NULL, 0, NULL, NULL}}; - -static EnumPropertyItem space_object_items[] = { - {0, "WORLD", 0, "World Space", ""}, - {1, "LOCAL", 0, "Local (Without Parent) Space", ""}, - {0, NULL, 0, NULL, NULL}}; - -static EnumPropertyItem *rna_Constraint_owner_space_itemf(PointerRNA *ptr) +static EnumPropertyItem *rna_Constraint_owner_space_itemf(bContext *C, PointerRNA *ptr, int *free) { Object *ob= (Object*)ptr->id.data; bConstraint *con= (bConstraint*)ptr->data; @@ -189,7 +188,7 @@ static EnumPropertyItem *rna_Constraint_owner_space_itemf(PointerRNA *ptr) return space_object_items; } -static EnumPropertyItem *rna_Constraint_target_space_itemf(PointerRNA *ptr) +static EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *C, PointerRNA *ptr, int *free) { bConstraint *con= (bConstraint*)ptr->data; bConstraintTypeInfo *cti= constraint_get_typeinfo(con); @@ -1505,11 +1504,13 @@ void RNA_def_constraint(BlenderRNA *brna) prop= RNA_def_property(srna, "owner_space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "ownspace"); + RNA_def_property_enum_items(prop, space_pchan_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Constraint_owner_space_itemf"); RNA_def_property_ui_text(prop, "Owner Space", "Space that owner is evaluated in."); prop= RNA_def_property(srna, "target_space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "tarspace"); + RNA_def_property_enum_items(prop, space_pchan_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Constraint_target_space_itemf"); RNA_def_property_ui_text(prop, "Target Space", "Space that target is evaluated in."); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 2b414adf05b..07515d3ad56 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -1112,7 +1112,7 @@ void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item switch(prop->type) { case PROP_ENUM: { EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop; - eprop->item= item; + eprop->item= (EnumPropertyItem*)item; eprop->totitem= 0; for(i=0; item[i].identifier; i++) { eprop->totitem++; @@ -2262,3 +2262,37 @@ int rna_parameter_size(PropertyRNA *parm) return sizeof(void *); } +/* Dynamic Enums */ + +void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item) +{ + EnumPropertyItem *newitems; + int tot= *totitem; + + if(tot == 0) { + *items= MEM_callocN(sizeof(EnumPropertyItem)*8, "RNA_enum_items_add"); + } + else if(tot >= 8 && (tot&(tot-1)) == 0){ + /* power of two > 8 */ + newitems= MEM_callocN(sizeof(EnumPropertyItem)*tot*2, "RNA_enum_items_add"); + memcpy(newitems, *items, sizeof(EnumPropertyItem)*tot); + MEM_freeN(*items); + *items= newitems; + } + + (*items)[tot]= *item; + *totitem= tot+1; +} + +void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item) +{ + for(; item->identifier; item++) + RNA_enum_item_add(items, totitem, item); +} + +void RNA_enum_item_end(EnumPropertyItem **items, int *totitem) +{ + static EnumPropertyItem empty = {0, NULL, 0, NULL, NULL}; + RNA_enum_item_add(items, totitem, &empty); +} + diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index 401b430ebc9..b63e347e165 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -68,7 +68,7 @@ typedef int (*PropStringLengthFunc)(struct PointerRNA *ptr); typedef void (*PropStringSetFunc)(struct PointerRNA *ptr, const char *value); typedef int (*PropEnumGetFunc)(struct PointerRNA *ptr); typedef void (*PropEnumSetFunc)(struct PointerRNA *ptr, int value); -typedef EnumPropertyItem *(*PropEnumItemFunc)(struct PointerRNA *ptr); +typedef EnumPropertyItem *(*PropEnumItemFunc)(struct bContext *C, struct PointerRNA *ptr, int *free); typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr); typedef StructRNA* (*PropPointerTypeFunc)(struct PointerRNA *ptr); typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value); @@ -225,7 +225,7 @@ typedef struct EnumPropertyRNA { PropEnumSetFunc set; PropEnumItemFunc itemf; - const EnumPropertyItem *item; + EnumPropertyItem *item; int totitem; int defaultvalue; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index bb19b66b34d..c4f2c29409f 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -40,6 +40,57 @@ #include "WM_types.h" #include "WM_api.h" +EnumPropertyItem part_from_items[] = { + {PART_FROM_VERT, "VERT", 0, "Verts", ""}, + {PART_FROM_FACE, "FACE", 0, "Faces", ""}, + {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_reactor_from_items[] = { + {PART_FROM_VERT, "VERT", 0, "Verts", ""}, + {PART_FROM_FACE, "FACE", 0, "Faces", ""}, + {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, + {PART_FROM_PARTICLE, "PARTICLE", 0, "Particle", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_draw_as_items[] = { + {PART_DRAW_NOT, "NONE", 0, "None", ""}, + {PART_DRAW_REND, "RENDER", 0, "Rendered", ""}, + {PART_DRAW_DOT, "DOT", 0, "Point", ""}, + {PART_DRAW_CIRC, "CIRC", 0, "Circle", ""}, + {PART_DRAW_CROSS, "CROSS", 0, "Cross", ""}, + {PART_DRAW_AXIS, "AXIS", 0, "Axis", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_hair_draw_as_items[] = { + {PART_DRAW_NOT, "NONE", 0, "None", ""}, + {PART_DRAW_REND, "RENDER", 0, "Rendered", ""}, + {PART_DRAW_PATH, "PATH", 0, "Path", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_ren_as_items[] = { + {PART_DRAW_NOT, "NONE", 0, "None", ""}, + {PART_DRAW_HALO, "HALO", 0, "Halo", ""}, + {PART_DRAW_LINE, "LINE", 0, "Line", ""}, + {PART_DRAW_PATH, "PATH", 0, "Path", ""}, + {PART_DRAW_OB, "OBJECT", 0, "Object", ""}, + {PART_DRAW_GR, "GROUP", 0, "Group", ""}, + {PART_DRAW_BB, "BILLBOARD", 0, "Billboard", ""}, + {0, NULL, 0, NULL, NULL} +}; + +EnumPropertyItem part_hair_ren_as_items[] = { + {PART_DRAW_NOT, "NONE", 0, "None", ""}, + {PART_DRAW_PATH, "PATH", 0, "Path", ""}, + {PART_DRAW_OB, "OBJECT", 0, "Object", ""}, + {PART_DRAW_GR, "GROUP", 0, "Group", ""}, + {0, NULL, 0, NULL, NULL} +}; + #ifdef RNA_RUNTIME #include "BKE_context.h" @@ -248,85 +299,34 @@ static void rna_ParticleSystem_name_get(PointerRNA *ptr, char *str) strcpy(str, ""); } -static EnumPropertyItem from_items[] = { - {PART_FROM_VERT, "VERT", 0, "Vertexes", ""}, - {PART_FROM_FACE, "FACE", 0, "Faces", ""}, - {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static EnumPropertyItem reactor_from_items[] = { - {PART_FROM_VERT, "VERT", 0, "Vertexes", ""}, - {PART_FROM_FACE, "FACE", 0, "Faces", ""}, - {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""}, - {PART_FROM_PARTICLE, "PARTICLE", 0, "Particle", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static EnumPropertyItem *rna_Particle_from_itemf(PointerRNA *ptr) +static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, int *free) { ParticleSettings *part = ptr->id.data; if(part->type==PART_REACTOR) - return reactor_from_items; + return part_reactor_from_items; else - return from_items; + return part_from_items; } -static EnumPropertyItem draw_as_items[] = { - {PART_DRAW_NOT, "NONE", 0, "None", ""}, - {PART_DRAW_REND, "RENDER", 0, "Rendered", ""}, - {PART_DRAW_DOT, "DOT", 0, "Point", ""}, - {PART_DRAW_CIRC, "CIRC", 0, "Circle", ""}, - {PART_DRAW_CROSS, "CROSS", 0, "Cross", ""}, - {PART_DRAW_AXIS, "AXIS", 0, "Axis", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static EnumPropertyItem hair_draw_as_items[] = { - {PART_DRAW_NOT, "NONE", 0, "None", ""}, - {PART_DRAW_REND, "RENDER", 0, "Rendered", ""}, - {PART_DRAW_PATH, "PATH", 0, "Path", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static EnumPropertyItem ren_as_items[] = { - {PART_DRAW_NOT, "NONE", 0, "None", ""}, - {PART_DRAW_HALO, "HALO", 0, "Halo", ""}, - {PART_DRAW_LINE, "LINE", 0, "Line", ""}, - {PART_DRAW_PATH, "PATH", 0, "Path", ""}, - {PART_DRAW_OB, "OBJECT", 0, "Object", ""}, - {PART_DRAW_GR, "GROUP", 0, "Group", ""}, - {PART_DRAW_BB, "BILLBOARD", 0, "Billboard", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static EnumPropertyItem hair_ren_as_items[] = { - {PART_DRAW_NOT, "NONE", 0, "None", ""}, - {PART_DRAW_PATH, "PATH", 0, "Path", ""}, - {PART_DRAW_OB, "OBJECT", 0, "Object", ""}, - {PART_DRAW_GR, "GROUP", 0, "Group", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static EnumPropertyItem *rna_Particle_draw_as_itemf(PointerRNA *ptr) +static EnumPropertyItem *rna_Particle_draw_as_itemf(bContext *C, PointerRNA *ptr, int *free) { ParticleSettings *part = ptr->id.data; if(part->type==PART_HAIR) - return hair_draw_as_items; + return part_hair_draw_as_items; else - return draw_as_items; + return part_draw_as_items; } -static EnumPropertyItem *rna_Particle_ren_as_itemf(PointerRNA *ptr) +static EnumPropertyItem *rna_Particle_ren_as_itemf(bContext *C, PointerRNA *ptr, int *free) { ParticleSettings *part = ptr->id.data; if(part->type==PART_HAIR) - return hair_ren_as_items; + return part_hair_ren_as_items; else - return ren_as_items; + return part_ren_as_items; } @@ -801,6 +801,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "emit_from", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "from"); + RNA_def_property_enum_items(prop, part_reactor_from_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_from_itemf"); RNA_def_property_ui_text(prop, "Emit From", "Where to emit particles from"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); @@ -914,12 +915,14 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "draw_as", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "draw_as"); + RNA_def_property_enum_items(prop, part_draw_as_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_draw_as_itemf"); RNA_def_property_ui_text(prop, "Particle Drawing", "How particles are drawn in viewport"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); prop= RNA_def_property(srna, "ren_as", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "ren_as"); + RNA_def_property_enum_items(prop, part_ren_as_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_ren_as_itemf"); RNA_def_property_ui_text(prop, "Particle Rendering", "How particles are rendered"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 996e54384e2..b4422541718 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -173,7 +173,7 @@ static EnumPropertyItem dc_rgb_items[] = {DC_RGB, DC_LCMS, DC_ZERO}; static EnumPropertyItem dc_alpha_items[] = {DC_RGB, DC_RGBA, DC_ALPHA, DC_LCMS, DC_ZERO}; static EnumPropertyItem dc_z_items[] = {DC_RGB, DC_Z, DC_LCMS, DC_ZERO}; -static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(PointerRNA *ptr) +static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *C, PointerRNA *ptr, int *free) { SpaceImage *sima= (SpaceImage*)ptr->data; ImBuf *ibuf= ED_space_image_buffer(sima); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index c6fbda0caef..49bca247431 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -223,10 +223,16 @@ static void pyrna_struct_dealloc( BPy_StructRNA * self ) static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { - const EnumPropertyItem *item; + EnumPropertyItem *item; + char *result; + int free; - RNA_property_enum_items(ptr, prop, &item, NULL); - return (char*)BPy_enum_as_string((EnumPropertyItem*)item); + RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); + result= (char*)BPy_enum_as_string(item); + if(free) + MEM_freeN(item); + + return result; } PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) @@ -309,14 +315,15 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) const char *identifier; int val = RNA_property_enum_get(ptr, prop); - if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) { + if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) { ret = PyUnicode_FromString( identifier ); } else { - const EnumPropertyItem *item; + EnumPropertyItem *item; + int free; /* don't throw error here, can't trust blender 100% to give the * right values, python code should not generate error for that */ - RNA_property_enum_items(ptr, prop, &item, NULL); + RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if(item->identifier) { ret = PyUnicode_FromString( item->identifier ); } @@ -329,6 +336,9 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) ret = PyUnicode_FromString( "" ); } + if(free) + MEM_freeN(item); + /*PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val); ret = NULL;*/ } @@ -626,7 +636,7 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v return -1; } else { int val; - if (RNA_property_enum_value(ptr, prop, param, &val)) { + if (RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, &val)) { if(data) *((int*)data)= val; else RNA_property_enum_set(ptr, prop, val); } else { @@ -1818,19 +1828,23 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) const char *identifier; int val = *(int*)data; - if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) { + if (RNA_property_enum_identifier(BPy_GetContext(), ptr, prop, val, &identifier)) { ret = PyUnicode_FromString( identifier ); } else { - const EnumPropertyItem *item; + EnumPropertyItem *item; + int free; /* don't throw error here, can't trust blender 100% to give the * right values, python code should not generate error for that */ - RNA_property_enum_items(ptr, prop, &item, NULL); + RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if(item[0].identifier) ret = PyUnicode_FromString( item[0].identifier ); else ret = PyUnicode_FromString( "" ); + if(free) + MEM_freeN(item); + /*PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val); ret = NULL;*/ } diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index bce73b903c0..9f1ef0c6251 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -412,7 +412,8 @@ char *BPy_enum_as_string(EnumPropertyItem *item) char *cstring; for (e= item; item->identifier; item++) { - BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier); + if(item->identifier[0]) + BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier); } cstring = BLI_dynstr_get_cstring(dynstr); |