diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-07-28 07:54:40 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-07-28 07:54:40 +0400 |
commit | 858450767191660618fbeeaaf39e1ad91f338a70 (patch) | |
tree | 88a3549e8c1a37a1a2c9bf50c00f7bf412d4809f /source/blender/editors/object | |
parent | fe881aa7ad0ba77052d0c637a5a4056f8ef427f8 (diff) |
2.5 - Start of Make Proxy Operator
The code has been ported to the operator+rna system, however, there are currently issues related to how the pointer-rna's work for use as operator properties. (NOTE: RNA_property_pointer_set only takes into account builtin props for now, but not id-props, while the corresponding get method seems to take them into account)
The alternative to using pointer-properties for the operator, is to store strings and look up the relevant objects later, but there should be a nicer way...
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_edit.c | 154 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 2 |
3 files changed, 115 insertions, 42 deletions
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 1ee3f1b2f53..0d3118fd654 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -2666,68 +2666,110 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d) DAG_scene_sort(scene); } -static Object *group_objects_menu(Group *group) + +/* ******************** 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) { + PointerRNA gob_ptr; + uiPopupMenu *pup; + uiLayout *layout; GroupObject *go; - int len= 0; - short a, nr; - char *str; - - for(go= group->gobject.first; go; go= go->next) { - if(go->ob) - len++; + 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 NULL; + if (len==0) return; - str= MEM_callocN(40+32*len, "menu"); + /* now create the menu to draw */ + pup= uiPupMenuBegin(C, "Make Proxy For:", 0); + layout= uiPupMenuLayout(pup); - strcpy(str, "Make Proxy for: %t"); - a= strlen(str); - for(nr=1, go= group->gobject.first; go; go= go->next, nr++) { - a+= sprintf(str+a, "|%s %%x%d", go->ob->id.name+2, nr); - } + /* make RNA pointer for object that group belongs to */ + RNA_id_pointer_create((ID *)ob, &gob_ptr); - a= pupmenu_col(str, 20); - MEM_freeN(str); - if(a>0) { - go= BLI_findlink(&group->gobject, a-1); - return go->ob; + for (go= group->gobject.first; go; go= go->next) { + if (go->ob) { + PointerRNA props_ptr, ob_ptr; + + /* create pointer for this object */ + RNA_id_pointer_create((ID *)go->ob, &ob_ptr); + + /* create operator properties, and assign the relevant pointers to that, + * and add a menu entry which uses these props + */ + WM_operator_properties_create(&props_ptr, op->idname); + RNA_pointer_set(&props_ptr, "object", ob_ptr); + RNA_pointer_set(&props_ptr, "group_object", gob_ptr); + uiItemFullO(layout, go->ob->id.name+2, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN); + } } - return NULL; + + /* display the menu, and be done */ + uiPupMenuEnd(C, pup); } - -/* adds empty object to become local replacement data of a library-linked object */ -void make_proxy(Scene *scene) +/* set the object to proxify */ +static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt) { - Object *ob= OBACT; - Object *gob= NULL; - - if(scene->id.lib) return; - if(ob==NULL) return; - + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_active_object(C); - if(ob->dup_group && ob->dup_group->id.lib) { - gob= ob; + /* sanity checks */ + if (!scene || scene->id.lib || !ob) + return OPERATOR_CANCELLED; + + /* 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 */ - ob= group_objects_menu(ob->dup_group); + proxy_group_objects_menu(C, op, ob, ob->dup_group); } - else if(ob->id.lib) { - if(okee("Make Proxy Object")==0) - return; + else if (ob->id.lib) { + uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION); + uiLayout *layout= uiPupMenuLayout(pup); + PointerRNA ob_ptr, props_ptr; + + /* create pointer for this object */ + RNA_id_pointer_create((ID *)ob, &ob_ptr); + + /* create operator properties, and assign the relevant pointers to that, + * and add a menu entry which uses these props + */ + WM_operator_properties_create(&props_ptr, op->idname); + RNA_pointer_set(&props_ptr, "object", ob_ptr); + uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN); + + /* present the menu and be done... */ + uiPupMenuEnd(C, pup); } else { - error("Can only make proxy for a referenced object or group"); - return; + /* error.. cannot continue */ + BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group"); } - if(ob) { + /* this invoke just calls another instance of this operator... */ + return OPERATOR_CANCELLED; +} + +static int make_proxy_exec (bContext *C, wmOperator *op) +{ + PointerRNA ob_ptr= RNA_pointer_get(op->ptr, "object"); + PointerRNA gob_ptr= RNA_pointer_get(op->ptr, "group_object"); + Object *ob= ob_ptr.data; + Object *gob= gob_ptr.data; + Scene *scene= CTX_data_scene(C); + + if (ob) { Object *newob; Base *newbase, *oldbase= BASACT; char name[32]; + /* Add new object for the proxy */ newob= add_object(scene, OB_EMPTY); - if(gob) + if (gob) strcpy(name, gob->id.name+2); else strcpy(name, ob->id.name+2); @@ -2740,15 +2782,43 @@ void make_proxy(Scene *scene) newob->lay= newbase->lay; /* remove base, leave user count of object, it gets linked in object_make_proxy */ - if(gob==NULL) { + if (gob==NULL) { BLI_remlink(&scene->base, oldbase); MEM_freeN(oldbase); - } + } + object_make_proxy(newob, ob, gob); + /* depsgraph flushes are needed for the new data */ DAG_scene_sort(scene); DAG_object_flush_update(scene, newob, OB_RECALC); } + else { + BKE_report(op->reports, RPT_ERROR, "No object to make proxy for"); + return OPERATOR_CANCELLED; + } + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_proxy_make (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Proxy"; + ot->idname= "OBJECT_OT_proxy_make"; + ot->description= "Add empty object to become local replacement data of a library-linked object"; + + /* callbacks */ + ot->invoke= make_proxy_invoke; + ot->exec= make_proxy_exec; + ot->poll= ED_operator_object_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_pointer(ot->srna, "object", "Object", "Proxy Object", "Lib-linked/grouped object to make a proxy for."); + RNA_def_pointer(ot->srna, "group_object", "Object", "Group Object", "Group instancer (if applicable)."); } /* ******************** make parent operator *********************** */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 29076d9f32a..da34f35e647 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -66,6 +66,7 @@ void OBJECT_OT_object_add(struct wmOperatorType *ot); void OBJECT_OT_duplicate(struct wmOperatorType *ot); void OBJECT_OT_delete(struct wmOperatorType *ot); void OBJECT_OT_join(struct wmOperatorType *ot); +void OBJECT_OT_proxy_make(struct wmOperatorType *ot); void OBJECT_OT_shade_smooth(struct wmOperatorType *ot); void OBJECT_OT_shade_flat(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index c54a8cef8dc..f4407de60db 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -88,6 +88,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_duplicates_make_real); WM_operatortype_append(OBJECT_OT_duplicate); WM_operatortype_append(OBJECT_OT_join); + WM_operatortype_append(OBJECT_OT_proxy_make); WM_operatortype_append(OBJECT_OT_shade_smooth); WM_operatortype_append(OBJECT_OT_shade_flat); WM_operatortype_append(GROUP_OT_group_create); @@ -185,6 +186,7 @@ void ED_keymap_object(wmWindowManager *wm) WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1); WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); // XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0); |