diff options
author | Ton Roosendaal <ton@blender.org> | 2008-12-24 21:06:51 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2008-12-24 21:06:51 +0300 |
commit | febb2c21e4fce4fbbbcc30bbab295b745920a062 (patch) | |
tree | d97d6653a737718bebe80af64066e3bc17b5d449 | |
parent | 3c612bc0e237c48bc8a3f6fdc20cec4a3b140228 (diff) |
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.
-rw-r--r-- | source/blender/editors/object/object_edit.c | 162 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 3 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 10 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 34 |
6 files changed, 127 insertions, 88 deletions
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; a<totitem; a++) - if(strcmp(item->identifier, 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; i<totitem; i++) + len+= strlen(item[i].name) + 5; + + menu= MEM_callocN(len, "string"); + + p= menu + sprintf(menu, "%s %%t", op->type->name); + for (i=0; i<totitem; i++) + p+= sprintf(p, "|%s %%x%d", item[i].name, item[i].value); + + uiPupmenuOperator(C, totitem/30, op, "type", menu); + MEM_freeN(menu); + + return OPERATOR_RUNNING_MODAL; + } + return OPERATOR_CANCELLED; } /* call anywhere */ @@ -113,7 +133,7 @@ void WM_error(bContext *C, char *str) BLI_strncpy(testbuf, str, 128); sprintf(buf, "Error %%i%d%%t|%s", ICON_ERROR, testbuf); - uiPupmenu(C, 0, operator_callback, NULL, buf); + uiPupmenu(C, 0, NULL, NULL, buf); } |