diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-01-15 20:23:16 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-01-15 20:23:16 +0300 |
commit | a4732eefa5fa4ba06b8042c530748be6a4e4194c (patch) | |
tree | ec84eee9d719d441de5448a829b1faaa82c1d7fa /source/blender | |
parent | 2aaee044e565f1123b812d1a0350bfb5ac5e1de4 (diff) |
a new generic invoke function - WM_enum_search_invoke()
This can search operators enum property.
Make proxy menu could easily get too big. use the new search popup.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/object/object_relations.c | 105 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 82 |
3 files changed, 121 insertions, 67 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 95fbcdd4223..5cf11771004 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -261,39 +261,6 @@ void OBJECT_OT_vertex_parent_set(wmOperatorType *ot) /********************** Make Proxy Operator *************************/ -/* present menu listing the possible objects within the group to proxify */ -static void proxy_group_objects_menu (bContext *C, wmOperator *op, Object *ob, Group *group) -{ - uiPopupMenu *pup; - uiLayout *layout; - GroupObject *go; - int len=0; - - /* check if there are any objects within the group to assign for */ - for (go= group->gobject.first; go; go= go->next) { - if (go->ob) len++; - } - if (len==0) return; - - /* now create the menu to draw */ - pup= uiPupMenuBegin(C, "Make Proxy For:", 0); - layout= uiPupMenuLayout(pup); - - for (go= group->gobject.first; go; go= go->next) { - if (go->ob) { - PointerRNA props_ptr; - - /* create operator menu item with relevant properties filled in */ - props_ptr= uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); - RNA_string_set(&props_ptr, "object", go->ob->id.name+2); - RNA_string_set(&props_ptr, "group_object", go->ob->id.name+2); - } - } - - /* display the menu, and be done */ - uiPupMenuEnd(C, pup); -} - /* set the object to proxify */ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) { @@ -307,7 +274,10 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) /* Get object to work on - use a menu if we need to... */ if (ob->dup_group && ob->dup_group->id.lib) { /* gives menu with list of objects in group */ - proxy_group_objects_menu(C, op, ob, ob->dup_group); + //proxy_group_objects_menu(C, op, ob, ob->dup_group); + WM_enum_search_invoke(C, op, evt); + return OPERATOR_CANCELLED; + } else if (ob->id.lib) { uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); @@ -332,39 +302,10 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) static int make_proxy_exec (bContext *C, wmOperator *op) { - Object *ob=NULL, *gob=NULL; + Object *ob, *gob= CTX_data_active_object(C); + GroupObject *go= BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "type")); Scene *scene= CTX_data_scene(C); - char ob_name[21], gob_name[21]; - - /* get object and group object - * - firstly names - * - then pointers from context - */ - RNA_string_get(op->ptr, "object", ob_name); - RNA_string_get(op->ptr, "group_object", gob_name); - - if (gob_name[0]) { - Group *group; - GroupObject *go; - - /* active object is group object... */ - // FIXME: we should get the nominated name instead - gob= CTX_data_active_object(C); - group= gob->dup_group; - - /* find the object to affect */ - for (go= group->gobject.first; go; go= go->next) { - if ((go->ob) && strcmp(go->ob->id.name+2, gob_name)==0) { - ob= go->ob; - break; - } - } - } - else { - /* just use the active object for now */ - // FIXME: we should get the nominated name instead - ob= CTX_data_active_object(C); - } + ob= go->ob; if (ob) { Object *newob; @@ -407,8 +348,37 @@ static int make_proxy_exec (bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* Generic itemf's for operators that take library args */ +static EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + EnumPropertyItem *item= NULL, item_tmp; + int totitem= 0; + int i= 0; + Object *ob= CTX_data_active_object(C); + GroupObject *go; + + if(!ob || !ob->dup_group) + return &DummyRNA_NULL_items; + + memset(&item_tmp, 0, sizeof(item_tmp)); + + /* find the object to affect */ + for (go= ob->dup_group->gobject.first; go; go= go->next) { + item_tmp.identifier= item_tmp.name= go->ob->id.name+2; + item_tmp.value= i++; + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; +} + void OBJECT_OT_proxy_make (wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name= "Make Proxy"; ot->idname= "OBJECT_OT_proxy_make"; @@ -424,7 +394,8 @@ void OBJECT_OT_proxy_make (wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "object", "", 19, "Proxy Object", "Name of lib-linked/grouped object to make a proxy for."); - RNA_def_string(ot->srna, "group_object", "", 19, "Group Object", "Name of group instancer (if applicable)."); + prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", "Group object"); /* XXX, relies on hard coded ID at the moment */ + RNA_def_enum_funcs(prop, proxy_group_object_itemf); } /********************** Clear Parent Operator ******************* */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 4cc116e7bbd..4defd781db9 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -171,6 +171,7 @@ void WM_event_timer_sleep(struct wmWindowManager *wm, struct wmWindow *win, str /* operator api, default callbacks */ /* invoke callback, uses enum property named "type" */ int WM_menu_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event); +int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* invoke callback, confirm menu + exec */ int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* invoke callback, file selector "path" unset + exec */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 88ac8986936..278c597ab4a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -632,6 +632,88 @@ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } + +/* ENUM Search popup */ +static void operator_enum_search_cb(const struct bContext *C, void *arg_ot, char *str, uiSearchItems *items) +{ + wmOperatorType *ot = (wmOperatorType *)arg_ot; + PointerRNA ptr; + PropertyRNA *prop; + + /* enum */ + EnumPropertyItem *item, *item_array; + int free, found; + + RNA_pointer_create(NULL, ot->srna, NULL, &ptr); + prop = RNA_struct_find_property(&ptr, "type"); // XXX, SHOULD NOT USE HARD CODED VALUE + + RNA_property_enum_items((bContext *)C, &ptr, prop, &item_array, NULL, &free); + + for(item= item_array; item->identifier; item++) { + /* note: need to give the intex rather then the dientifier because the enum can be freed */ + if(BLI_strcasestr(item->name, str)) + if(0==uiSearchItemAdd(items, item->name, SET_INT_IN_POINTER(item->value), 0)) + break; + } + + found= (item->identifier != NULL); /* could be alloc'd, assign before free */ + + if(free) + MEM_freeN(item_array); + +} + +static void operator_enum_call_cb(struct bContext *C, void *arg1, void *arg2) +{ + wmOperatorType *ot= arg1; + int enum_value= GET_INT_FROM_POINTER(arg2); + + if(ot) { + PointerRNA props_ptr; + WM_operator_properties_create_ptr(&props_ptr, ot); + RNA_enum_set(&props_ptr, "type", enum_value); // XXX, SHOULD NOT USE HARD CODED VALUE + WM_operator_name_call(C, ot->idname, WM_OP_EXEC_DEFAULT, &props_ptr); + WM_operator_properties_free(&props_ptr); + } +} + +static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op) +{ + static char search[256]= ""; + wmEvent event; + wmWindow *win= CTX_wm_window(C); + uiBlock *block; + uiBut *but; + + block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT); + + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, ""); + uiButSetSearchFunc(but, operator_enum_search_cb, ((wmOperator *)arg_op)->type, operator_enum_call_cb, NULL); + + /* fake button, it holds space for search items */ + uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL); + + uiPopupBoundsBlock(block, 6.0f, 0, -20); /* move it downwards, mouse over button */ + uiEndBlock(C, block); + + event= *(win->eventstate); /* XXX huh huh? make api call */ + event.type= EVT_BUT_OPEN; + event.val= KM_PRESS; + event.customdata= but; + event.customdatafree= FALSE; + wm_event_add(win, &event); + + return block; +} + + +int WM_enum_search_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + uiPupBlock(C, wm_enum_search_menu, op); + return OPERATOR_CANCELLED; +} + /* Can't be used as an invoke directly, needs message arg (can be NULL) */ int WM_operator_confirm_message(bContext *C, wmOperator *op, char *message) { |