2.5
authorTon Roosendaal <ton@blender.org>
Wed, 24 Dec 2008 18:06:51 +0000 (18:06 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 24 Dec 2008 18:06:51 +0000 (18:06 +0000)
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
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/makesrna/intern/rna_access.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_operators.c

index 6e7fed9acf7f2faf2d03fcd87e92ed5e5856e97c..8a8f93a8290736205ec986bb1d73637da63fe96f 100644 (file)
@@ -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);
 }
 
 /* *******************  ***************** */
index 0ae30c8366ba8b8ddc197ca9aeb85f63dc9ddade..5bd5c26c0f99c751be2585ac8e7ec667afc9fca3 100644 (file)
@@ -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 */
 
index bbd3492aef3cabe9946bae8b1885759d6ca1b1e5..99e49d5c4e3d84cc12ac8cdd5daf352f27a26397 100644 (file)
@@ -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);
 }
index 4c6c7cabf9efc3049b63209f1b7a21a0a3bb5cc4..2c207539c2fe438fda91fb95d648296a5bde84fe 100644 (file)
@@ -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;
index 60f39e4dd9c4759cd318320d96f4a03b2e753e50..3a550c75d59b1dbadc6ce9ee99df77e85045af82 100644 (file)
@@ -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);
index b8b7f8fadaaa41ad6796559aa3cd93cc6297c723..a446ddb9e82aa60ade91b3761f47da2967232dbf 100644 (file)
@@ -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);
        
 }