From febb2c21e4fce4fbbbcc30bbab295b745920a062 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 24 Dec 2008 18:06:51 +0000 Subject: 2.5 Further simplifying making operators with menus; now you can add an 'invoke' callback: WM_menu_invoke which will automatically generate a menu with choices and assign it to the property 'type'. What also helps typing is the new RNA_enum_is_equal() function. Here's a paste of the now committed 'clear parent'. Note the undo push will become a flag too. http://pasteall.org/3660 (Brecht; fixed small bug in RNA_enum_is_equal!) To evaluate: solving dependencies for multipe scenes... probably will make a more generic flush call. --- source/blender/editors/object/object_edit.c | 162 +++++++++++---------- source/blender/editors/object/object_intern.h | 2 +- source/blender/editors/object/object_ops.c | 3 + source/blender/makesrna/intern/rna_access.c | 4 +- source/blender/windowmanager/WM_api.h | 10 +- source/blender/windowmanager/intern/wm_operators.c | 34 ++++- 6 files changed, 127 insertions(+), 88 deletions(-) (limited to 'source') diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 6e7fed9acf7..8a8f93a8290 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -913,48 +913,66 @@ void make_track(Scene *scene, View3D *v3d) BIF_undo_push("Make Track"); } +/* ******************** clear parent operator ******************* */ -void clear_parent(Scene *scene, View3D *v3d) -{ - Object *par; - Base *base; - int mode; - - if(G.obedit) return; - if(scene->id.lib) return; - mode= pupmenu("OK? %t|Clear Parent %x1|Clear and Keep Transformation (Clear Track) %x2|Clear Parent Inverse %x3"); +static EnumPropertyItem prop_clear_parent_types[] = { + {0, "CLEAR", "Clear Parent", ""}, + {1, "CLEAR_KEEP_TRANSFORM", "Clear and Keep Transformation (Clear Track)", ""}, + {2, "CLEAR_INVERSE", "Clear Parent Inverse", ""}, + {0, NULL, NULL, NULL} +}; + +/* note, poll should check for editable scene */ +static int clear_parent_exec(bContext *C, wmOperator *op) +{ - if(mode<1) return; + CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - par= NULL; - if(mode==1 || mode==2) { - par= base->object->parent; - base->object->parent= NULL; - base->object->recalc |= OB_RECALC; - - if(mode==2) { - base->object->track= NULL; - apply_obmat(base->object); - } - } - else if(mode==3) { - Mat4One(base->object->parentinv); - base->object->recalc |= OB_RECALC; - } + if(RNA_enum_is_equal(op->ptr, "type", "CLEAR")) { + ob->parent= NULL; + } + if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) { + ob->parent= NULL; + ob->track= NULL; + apply_obmat(ob); + } + if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_INVERSE")) { + Mat4One(ob->parentinv); } + ob->recalc |= OB_RECALC; } - - DAG_scene_sort(scene); - ED_anim_dag_flush_update(C); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWOOPS, 0); + CTX_DATA_END; + + DAG_scene_sort(CTX_data_scene(C)); + ED_anim_dag_flush_update(C); BIF_undo_push("Clear Parent"); + + return OPERATOR_FINISHED; +} + +void ED_VIEW3D_OT_clear_parent(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Clear parent"; + ot->idname= "ED_VIEW3D_OT_clear_parent"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= clear_parent_exec; + + ot->poll= ED_operator_areaactive; // XXX solve + ot->flag= OPTYPE_REGISTER; + + prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_clear_parent_types); } +/* ***************************** */ + void clear_track(Scene *scene, View3D *v3d) { Base *base; @@ -1346,51 +1364,47 @@ void make_proxy(Scene *scene) oldcode() { else if(mode==4) { - bConstraint *con; - bFollowPathConstraint *data; - - for(base= FIRSTBASE; base; base= base->next) { - if(TESTBASELIB(v3d, base)) { - if(base!=BASACT) { - float cmat[4][4], vec[3]; - + bConstraint *con; + bFollowPathConstraint *data; + + for(base= FIRSTBASE; base; base= base->next) { + if(TESTBASELIB(v3d, base)) { + if(base!=BASACT) { + float cmat[4][4], vec[3]; + // XXX con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH); - strcpy (con->name, "AutoPath"); - - data = con->data; - data->tar = BASACT->object; - + strcpy (con->name, "AutoPath"); + + data = con->data; + data->tar = BASACT->object; + // XXX add_constraint_to_object(con, base->object); - - get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(base->object)); - VecSubf(vec, base->object->obmat[3], cmat[3]); - - base->object->loc[0] = vec[0]; - base->object->loc[1] = vec[1]; - base->object->loc[2] = vec[2]; - } + + get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(base->object)); + VecSubf(vec, base->object->obmat[3], cmat[3]); + + base->object->loc[0] = vec[0]; + base->object->loc[1] = vec[1]; + base->object->loc[2] = vec[2]; } } + } - if(mode==PARSKEL && base->object->type==OB_MESH && par->type == OB_ARMATURE) { - /* Prompt the user as to whether he wants to - * add some vertex groups based on the bones - * in the parent armature. - */ + if(mode==PARSKEL && base->object->type==OB_MESH && par->type == OB_ARMATURE) { + /* Prompt the user as to whether he wants to + * add some vertex groups based on the bones + * in the parent armature. + */ // XXX create_vgroups_from_armature(base->object, par); - base->object->partype= PAROBJECT; - what_does_parent(base->object); - Mat4One (base->object->parentinv); - base->object->partype= mode; - } - else - what_does_parent(base->object, &workob); - Mat4Invert(base->object->parentinv, workob.obmat); - } - } - } + base->object->partype= PAROBJECT; + what_does_parent(base->object); + Mat4One (base->object->parentinv); + base->object->partype= mode; } + else + what_does_parent(base->object, &workob); + Mat4Invert(base->object->parentinv, workob.obmat); } } #endif @@ -1405,7 +1419,7 @@ oldcode() #define PAR_VERTEX 7 #define PAR_TRIA 8 -static EnumPropertyItem prop_make_parent_items[] = { +static EnumPropertyItem prop_make_parent_types[] = { {PAR_OBJECT, "OBJECT", "Object", ""}, {PAR_ARMATURE, "ARMATURE", "Armature Deform", ""}, {PAR_BONE, "BONE", "Bone", ""}, @@ -1433,7 +1447,7 @@ static int make_parent_exec(bContext *C, wmOperator *op) { Object *par= CTX_data_active_object(C); bPoseChannel *pchan= NULL; - int partype= RNA_enum_get(op->ptr, "partype"); + int partype= RNA_enum_get(op->ptr, "type"); par->recalc |= OB_RECALC_OB; @@ -1539,7 +1553,7 @@ static int make_parent_invoke(bContext *C, wmOperator *op, wmEvent *event) else str += sprintf(str, formatstr, "Object", PAR_OBJECT); - uiPupmenuOperator(C, 0, op, "partype", string); + uiPupmenuOperator(C, 0, op, "type", string); return OPERATOR_RUNNING_MODAL; } @@ -1560,8 +1574,8 @@ void ED_VIEW3D_OT_make_parent(wmOperatorType *ot) ot->poll= ED_operator_areaactive; // XXX solve ot->flag= OPTYPE_REGISTER; - prop = RNA_def_property(ot->srna, "partype", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, prop_make_parent_items); + prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_make_parent_types); } /* ******************* ***************** */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 0ae30c8366b..5bd5c26c0f9 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -33,7 +33,7 @@ /* object_edit.c */ void ED_VIEW3D_OT_make_parent(wmOperatorType *ot); - +void ED_VIEW3D_OT_clear_parent(wmOperatorType *ot); #endif /* ED_OBJECT_INTERN_H */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index bbd3492aef3..99e49d5c4e3 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -63,6 +63,8 @@ void ED_operatortypes_object(void) { WM_operatortype_append(ED_VIEW3D_OT_make_parent); + WM_operatortype_append(ED_VIEW3D_OT_clear_parent); + } /* note object keymap also for other space? */ @@ -71,6 +73,7 @@ void ED_keymap_object(wmWindowManager *wm) ListBase *keymap= WM_keymap_listbase(wm, "View3D Object", SPACE_VIEW3D, 0); WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_make_parent", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_clear_parent", PKEY, KM_PRESS, KM_ALT, 0); // RNA_int_set(WM_keymap_add_item(keymap, "ED_VIEW3D_OT_viewzoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); } diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 4c6c7cabf9e..2c207539c2f 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1598,8 +1598,8 @@ int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname) RNA_property_enum_items(ptr, prop, &item, &totitem); for(a=0; aidentifier, enumname) == 0) - return (item->value == RNA_property_enum_get(ptr, prop)); + if(strcmp(item[a].identifier, enumname) == 0) + return (item[a].value == RNA_property_enum_get(ptr, prop)); printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname); return 0; diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 60f39e4dd9c..3a550c75d59 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -104,16 +104,18 @@ struct wmTimer *WM_event_add_window_timer(wmWindow *win, double timestep); void WM_event_remove_window_timer(wmWindow *win, struct wmTimer *timer); void WM_event_window_timer_sleep(wmWindow *win, struct wmTimer *timer, int dosleep); - /* operator api, default callbacks */ - /* confirm menu + exec */ + /* operator api, default callbacks */ + /* invoke callback, uses enum property named "type" */ +int WM_menu_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); - /* context checks */ + /* poll callback, context checks */ int WM_operator_winactive (struct bContext *C); /* default error box */ void WM_error(struct bContext *C, char *str); - /* operator api */ + /* operator api */ void WM_operator_free (struct wmOperator *op); wmOperatorType *WM_operatortype_find(const char *idname); wmOperatorType *WM_operatortype_first(void); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b8b7f8fadaa..a446ddb9e82 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -97,13 +97,33 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType*)) /* ************ default op callbacks, exported *********** */ -static void operator_callback(bContext *C, void *arg, int retval) +/* invoke callback, uses enum property named "type" */ +/* only weak thing is the fixed property name... */ +int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) { - wmOperator *op= arg; - - if(op && retval > 0) - op->type->exec(C, op); - + PropertyRNA *prop= RNA_struct_find_property(op->ptr, "type"); + const EnumPropertyItem *item; + int totitem, i, len= strlen(op->type->name) + 5; + char *menu, *p; + + if(prop) { + RNA_property_enum_items(op->ptr, prop, &item, &totitem); + + for (i=0; itype->name); + for (i=0; i