diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-11-04 13:25:57 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-11-04 13:25:57 +0300 |
commit | 46c8bfe15182371b0f1a161726f27d5010ef3bbb (patch) | |
tree | bd9553b4d5e11575206393b0a23eebf6d20b5232 /source | |
parent | b221e57fd2722eda1e1f3738106709d4574c4d00 (diff) |
Make Links (Ctrl+L) back
- split into 2 operators: object.make_links_data() & object.make_links_scene since they are quite different.
- added reusable functions RNA_group_itemf & RNA_scene_itemf which can be used for any operator that takes ID data (easy to add more types Mesh, Text etc)
- DummyRNA_NULL_items for dynamic items so each operator need not define its own empty enum.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/object/object_add.c | 30 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 5 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 258 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_enum_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 30 |
7 files changed, 173 insertions, 164 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index e1c23123b84..63bb3f87480 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -678,31 +678,8 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ED_object_add_generic_props(ot, FALSE); } -/* add dupligroup */ -static EnumPropertyItem *add_dupligroup_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - EnumPropertyItem *item= NULL, item_tmp; - int totitem= 0; - int i= 0; - Group *group; - - memset(&item_tmp, 0, sizeof(item_tmp)); - - for(group= CTX_data_main(C)->group.first; group; group= group->id.next) { - item_tmp.identifier= item_tmp.name= group->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; -} - static int group_instance_add_exec(bContext *C, wmOperator *op) { - /* XXX, using an enum for library lookups is a bit dodgy */ Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "type")); int view_align, enter_editmode; @@ -728,9 +705,6 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) void OBJECT_OT_group_instance_add(wmOperatorType *ot) { PropertyRNA *prop; - static EnumPropertyItem prop_group_dummy_types[] = { - {0, NULL, 0, NULL, NULL} - }; /* identifiers */ ot->name= "Add Group Instance"; @@ -746,8 +720,8 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot) ot->flag= 0; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_group_dummy_types, 0, "Type", ""); - RNA_def_enum_funcs(prop, add_dupligroup_itemf); + prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", ""); + RNA_def_enum_funcs(prop, RNA_group_itemf); ED_object_add_generic_props(ot, FALSE); } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index ebc36dddb33..8f27f0fbae4 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -60,6 +60,8 @@ void OBJECT_OT_slow_parent_set(struct wmOperatorType *ot); void OBJECT_OT_slow_parent_clear(struct wmOperatorType *ot); void OBJECT_OT_make_local(struct wmOperatorType *ot); void OBJECT_OT_make_single_user(struct wmOperatorType *ot); +void OBJECT_OT_make_links_scene(struct wmOperatorType *ot); +void OBJECT_OT_make_links_data(struct wmOperatorType *ot); void OBJECT_OT_move_to_layer(struct wmOperatorType *ot); /* object_edit.c */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index ab35320cc74..ccb6e8cdea3 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -92,6 +92,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_slow_parent_clear); WM_operatortype_append(OBJECT_OT_make_local); WM_operatortype_append(OBJECT_OT_make_single_user); + WM_operatortype_append(OBJECT_OT_make_links_scene); + WM_operatortype_append(OBJECT_OT_make_links_data); WM_operatortype_append(OBJECT_OT_move_to_layer); WM_operatortype_append(OBJECT_OT_select_inverse); @@ -290,6 +292,9 @@ void ED_keymap_object(wmKeyConfig *keyconf) kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", UKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_make_single_user"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", LKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_make_links"); WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move_linked", DKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 6849cefbbd9..cbd1e1be8d5 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -72,6 +72,7 @@ #include "BKE_object.h" #include "BKE_report.h" #include "BKE_sca.h" +#include "BKE_scene.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -83,6 +84,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "ED_anim_api.h" #include "ED_armature.h" @@ -92,10 +94,6 @@ #include "object_intern.h" -/* ************* XXX **************** */ -static int pupmenu(const char *msg) {return 0;} -static int pupmenu_col(const char *msg, int val) {return 0;} - /*********************** Make Vertex Parent Operator ************************/ static int vertex_parent_set_poll(bContext *C) @@ -1132,97 +1130,77 @@ void link_to_scene(unsigned short nr) #endif } +static int make_links_scene_exec(bContext *C, wmOperator *op) +{ + Scene *scene_to= BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "type")); + + if(scene_to==NULL) { + BKE_report(op->reports, RPT_ERROR, "Scene not found"); + return OPERATOR_CANCELLED; + } + + if(scene_to == CTX_data_scene(C)) { + BKE_report(op->reports, RPT_ERROR, "Can't link objects into the same scene"); + return OPERATOR_CANCELLED; + } + + CTX_DATA_BEGIN(C, Base*, base, selected_bases) + { + if(!object_in_scene(base->object, scene_to)) { + Base *nbase= MEM_mallocN( sizeof(Base), "newbase"); + *nbase= *base; + BLI_addhead( &(scene_to->base), nbase); + id_us_plus((ID *)base->object); + } + } + CTX_DATA_END; + + ED_anim_dag_flush_update(C); + + /* one day multiple scenes will be visible, then we should have some update function for them */ + return OPERATOR_FINISHED; +} + +enum { + MAKE_LINKS_OBDATA = 1, + MAKE_LINKS_MATERIALS, + MAKE_LINKS_ANIMDATA, + MAKE_LINKS_DUPLIGROUP, +}; -void make_links(bContext *C, wmOperator *op, Scene *scene, View3D *v3d, short event) +static int make_links_data_exec(bContext *C, wmOperator *op) { - Object *ob, *obt; - Base *base, *nbase, *sbase; - Scene *sce = NULL; + int event = RNA_int_get(op->ptr, "type"); + Object *ob; ID *id; int a; - short nr=0; - char *strp; - if(!(ob=OBACT)) return; + ob= CTX_data_active_object(C); - if(event==1) { - IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), 0, &nr); - - if(nr == -2) { - MEM_freeN(strp); + CTX_DATA_BEGIN(C, Object*, obt, selected_editable_objects) { + if(ob != obt) { + switch(event) { + case MAKE_LINKS_OBDATA: /* obdata */ + id= obt->data; + id->us--; -// XXX activate_databrowse((ID *)scene, ID_SCE, 0, B_INFOSCE, &(G.curscreen->scenenr), link_to_scene ); - - return; - } - else { - event= pupmenu_col(strp, 20); - MEM_freeN(strp); - - if(event<= 0) return; - - nr= 1; - sce= G.main->scene.first; - while(sce) { - if(nr==event) break; - nr++; - sce= sce->id.next; - } - if(sce==scene) { - BKE_report(op->reports, RPT_ERROR, "This is the current scene"); - return; - } - if(sce==0 || sce->id.lib) return; - - /* remember: is needed below */ - event= 1; - } - } + id= ob->data; + id_us_plus(id); + obt->data= id; - /* All non group linking */ - for(base= FIRSTBASE; base; base= base->next) { - if(event==1 || base != BASACT) { - - obt= base->object; + /* if amount of material indices changed: */ + test_object_materials(obt->data); - if(TESTBASE(v3d, base)) { - - if(event==1) { /* to scene */ - - /* test if already linked */ - sbase= sce->base.first; - while(sbase) { - if(sbase->object==base->object) break; - sbase= sbase->next; - } - if(sbase) { /* remove */ - continue; - } - - nbase= MEM_mallocN( sizeof(Base), "newbase"); - *nbase= *base; - BLI_addhead( &(sce->base), nbase); - id_us_plus((ID *)base->object); + obt->recalc |= OB_RECALC_DATA; + break; + case MAKE_LINKS_MATERIALS: + /* new approach, using functions from kernel */ + for(a=0; a<ob->totcol; a++) { + Material *ma= give_current_material(ob, a+1); + assign_material(obt, ma, a+1); /* also works with ma==NULL */ } - } - if(TESTBASELIB(v3d, base)) { - if(event==2 || event==5) { /* obdata */ - if(ob->type==obt->type) { - - id= obt->data; - id->us--; - - id= ob->data; - id_us_plus(id); - obt->data= id; - - /* if amount of material indices changed: */ - test_object_materials(obt->data); - - obt->recalc |= OB_RECALC_DATA; - } - } - else if(event==4) { /* ob ipo */ + break; + case MAKE_LINKS_ANIMDATA: #if 0 // XXX old animation system if(obt->ipo) obt->ipo->id.us--; obt->ipo= ob->ipo; @@ -1231,67 +1209,75 @@ void make_links(bContext *C, wmOperator *op, Scene *scene, View3D *v3d, short ev do_ob_ipo(scene, obt); } #endif // XXX old animation system + break; + case MAKE_LINKS_DUPLIGROUP: + if(ob->dup_group) ob->dup_group->id.us--; + obt->dup_group= ob->dup_group; + if(obt->dup_group) { + id_us_plus((ID *)obt->dup_group); + obt->transflag |= OB_DUPLIGROUP; } - else if(event==6) { - if(ob->dup_group) ob->dup_group->id.us--; - obt->dup_group= ob->dup_group; - if(obt->dup_group) { - id_us_plus((ID *)obt->dup_group); - obt->transflag |= OB_DUPLIGROUP; - } - } - else if(event==3) { /* materials */ - - /* new approach, using functions from kernel */ - for(a=0; a<ob->totcol; a++) { - Material *ma= give_current_material(ob, a+1); - assign_material(obt, ma, a+1); /* also works with ma==NULL */ - } - } + break; } } } - - ED_anim_dag_flush_update(C); + CTX_DATA_END; + ED_anim_dag_flush_update(C); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + return OPERATOR_FINISHED; } -void make_links_menu(bContext *C, Scene *scene, View3D *v3d) + +void OBJECT_OT_make_links_scene(wmOperatorType *ot) { - Object *ob; - short event=0; - char str[140]; - - if(!(ob=OBACT)) return; - - strcpy(str, "Make Links %t|To Scene...%x1|%l|Object Ipo%x4"); - - if(ob->type==OB_MESH) - strcat(str, "|Mesh Data%x2|Materials%x3"); - else if(ob->type==OB_CURVE) - strcat(str, "|Curve Data%x2|Materials%x3"); - else if(ob->type==OB_FONT) - strcat(str, "|Text Data%x2|Materials%x3"); - else if(ob->type==OB_SURF) - strcat(str, "|Surface Data%x2|Materials%x3"); - else if(ob->type==OB_MBALL) - strcat(str, "|Materials%x3"); - else if(ob->type==OB_CAMERA) - strcat(str, "|Camera Data%x2"); - else if(ob->type==OB_LAMP) - strcat(str, "|Lamp Data%x2"); - else if(ob->type==OB_LATTICE) - strcat(str, "|Lattice Data%x2"); - else if(ob->type==OB_ARMATURE) - strcat(str, "|Armature Data%x2"); - - event= pupmenu(str); - - if(event<= 0) return; - - make_links(C, NULL, scene, v3d, event); + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Link Objects to Scene"; + ot->description = "Make linked data local to each object."; + ot->idname= "OBJECT_OT_make_links_scene"; + + /* api callbacks */ + ot->exec= make_links_scene_exec; + /* better not run the poll check */ + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", ""); + RNA_def_enum_funcs(prop, RNA_scene_itemf); +} + +void OBJECT_OT_make_links_data(wmOperatorType *ot) +{ + static EnumPropertyItem make_links_items[]= { + {MAKE_LINKS_OBDATA, "OBDATA", 0, "Object Data", ""}, + {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Materials", ""}, + {MAKE_LINKS_ANIMDATA, "ANIMATION", 0, "Animation Data", ""}, + {MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""}, + {0, NULL, 0, NULL, NULL}}; + + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Link Data"; + ot->description = "Make links from the active object to other selected objects."; + ot->idname= "OBJECT_OT_make_links_data"; + + /* api callbacks */ + ot->exec= make_links_data_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "type", make_links_items, 0, "Type", ""); } + /**************************** Make Single User ********************************/ static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin) diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index ca44e3405f6..318178d1522 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -31,6 +31,8 @@ extern EnumPropertyItem id_type_items[]; +/* use in cases where only dynamic types are used */ +extern EnumPropertyItem DummyRNA_NULL_items[]; extern EnumPropertyItem object_mode_items[]; @@ -69,6 +71,11 @@ struct bContext; struct PointerRNA; EnumPropertyItem *rna_TransformOrientation_itemf(struct bContext *C, struct PointerRNA *ptr, int *free); +/* Generic functions, return an enum from library data, index is the position + * in the linked list can add more for different types as needed */ +EnumPropertyItem *RNA_group_itemf(struct bContext *C, struct PointerRNA *ptr, int *free); +EnumPropertyItem *RNA_scene_itemf(struct bContext *C, struct PointerRNA *ptr, int *free); + #endif /* RNA_ENUM_TYPES */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index f0aaceec4aa..93e83492efa 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -734,6 +734,11 @@ StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop) return &RNA_UnknownType; } +/* Reuse for dynamic types */ +EnumPropertyItem DummyRNA_NULL_items[] = { + {0, NULL, 0, NULL, NULL} +}; + void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free) { EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 743a4ceebe8..db09619046e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2446,3 +2446,33 @@ void wm_window_keymap(wmKeyConfig *keyconf) RNA_string_set(km->ptr, "value", "DOPESHEET_EDITOR"); } +/* Generic itemf's for operators that take library args */ +static EnumPropertyItem *rna_id_itemf(bContext *C, PointerRNA *ptr, int *free, ID *id) +{ + EnumPropertyItem *item= NULL, item_tmp; + int totitem= 0; + int i= 0; + + memset(&item_tmp, 0, sizeof(item_tmp)); + + for( ; id; id= id->next) { + item_tmp.identifier= item_tmp.name= 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; +} + +/* can add more */ +EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + rna_id_itemf(C, ptr, free, (ID *)CTX_data_main(C)->group.first); +} +EnumPropertyItem *RNA_scene_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + rna_id_itemf(C, ptr, free, (ID *)CTX_data_main(C)->scene.first); +} |