== Action Editor Bugfixes (BugReport #7049) ==
authorJoshua Leung <aligorith@gmail.com>
Wed, 15 Aug 2007 10:04:45 +0000 (10:04 +0000)
committerJoshua Leung <aligorith@gmail.com>
Wed, 15 Aug 2007 10:04:45 +0000 (10:04 +0000)
This commit fixes several issues related to using the Action Editor with Shapekeys. I've known about most of them for a while, so now's the time to fix that.

1) When the shapekey anim data for an object comes from an Action (key's IPO block is linked to the "Shape" action-channel), the names of the individual shapekeys is now shown. They will only do so if the Action Editor is not pinned though.

2) Slider limits for the case described above should now be sane again

3) "Add New" option from the popup menu in the Action Editor header will now convert shapekey animation data from IPO to Action if the action editor is displaying Shapekey data at the time. Many users have often found the old way of having to toggle the "running man" in the IPO-editor header, too clumsy and confusing.

source/blender/blenkernel/intern/ipo.c
source/blender/include/BSE_editipo.h
source/blender/src/drawaction.c
source/blender/src/editaction.c
source/blender/src/editipo_lib.c
source/blender/src/headerbuttons.c

index 16abf78952da58f26281cf9a60d3ffba7ababb60..39602f000534ae1bc2850df23e6ee7a784549b65 100644 (file)
@@ -1523,7 +1523,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
 
 void set_icu_vars(IpoCurve *icu)
 {
-       
+       /* defaults. 0.0 for y-extents makes these ignored */
        icu->ymin= icu->ymax= 0.0;
        icu->ipo= IPO_BEZ;
        
@@ -1812,6 +1812,14 @@ void set_icu_vars(IpoCurve *icu)
                        break;
                }
        }
+       else if(icu->blocktype==ID_CO) {
+               icu->ymin= 0.0;
+               icu->ymax= 1.0f;
+       }
+       
+       /* by default, slider limits will be icu->ymin and icu->ymax */
+       icu->slide_min= icu->ymin;
+       icu->slide_max= icu->ymax;
 }
 
 /* not for actions or constraints! */
index 66c9cef8693be6d4433d1d89ec5d71714e9e826c..428d9c89629d1d91ef2b090d9a1d8d9def7adbd3 100644 (file)
@@ -60,7 +60,7 @@ char *getname_cam_ei(int nr);
 char *getname_snd_ei(int nr);
 char *getname_fluidsim_ei(int nr);
 
-char *getname_ipocurve(struct IpoCurve *icu);
+char *getname_ipocurve(struct IpoCurve *icu, struct Object *ob);
 int geticon_ipo_blocktype(short blocktype);
 
 struct EditIpo *get_active_editipo(void);
index ea1b0dbaffe5a5413bac746a5ca125c77b1959fb..8d525b8847274f76f7668ed268cb2d097d052abe 100644 (file)
@@ -228,8 +228,8 @@ static void make_icu_slider(uiBlock *block, IpoCurve *icu,
        
        if (IS_EQ(icu->slide_max, icu->slide_min)) {
                if (IS_EQ(icu->ymax, icu->ymin)) {
-                       if (icu->blocktype == ID_CO) {
-                               /* hack for constraints (and maybe a few others) */
+                       if (ELEM(icu->blocktype, ID_CO, ID_KE)) {
+                               /* hack for constraints and shapekeys (and maybe a few others) */
                                icu->slide_min= 0.0;
                                icu->slide_max= 1.0;
                        }
@@ -491,7 +491,10 @@ static void draw_channel_names(void)
                                        mute = ICON_MUTE_IPO_OFF;
                                
                                sel = SEL_ICU(icu);
-                               sprintf(name, getname_ipocurve(icu));
+                               if (G.saction->pin)
+                                       sprintf(name, getname_ipocurve(icu, NULL));
+                               else
+                                       sprintf(name, getname_ipocurve(icu, OBACT));
                        }
                                break;
                        case ACTTYPE_SHAPEKEY: /* shapekey channel */
@@ -827,18 +830,20 @@ void drawactionspace(ScrArea *sa, void *spacedata)
        short ofsx = 0, ofsy = 0;
        float col[3];
 
-       if (!G.saction)
+       /* this is unlikely to occur, but it may */
+       if (G.saction == NULL)
                return;
 
        /* warning: blocks need to be freed each time, handlers dont remove  */
        uiFreeBlocksWin(&sa->uiblocks, sa->win);
 
-       if (!G.saction->pin) {
+       /* only try to refresh action that's displayed if not pinned */
+       if (G.saction->pin==0) {
                /* TODO: allow more than one active action sometime? */
                if (OBACT)
                        G.saction->action = OBACT->action;
                else
-                       G.saction->action=NULL;
+                       G.saction->action= NULL;
        }
        
        /* get data */
index cb46247d5c2ba1d8f41218f736bf60a7ada27d38..0098da1284dc573b36db57c98ed18c278089489d 100644 (file)
@@ -480,6 +480,7 @@ void actdata_filter (ListBase *act_data, int filter_mode, void *data, short data
  * returns key data for RVK type meshes). If there
  * is an action that is pinned, return null
  */
+/* Note: there's a similar function in key.c (ob_get_key) */
 Key *get_action_mesh_key(void) 
 {
     Object *ob;
@@ -1720,7 +1721,10 @@ static void clever_achannel_names (short *mval)
        else if (chantype == ACTTYPE_ICU) {
                icu= (IpoCurve *)act_channel;
                
-               strcpy(str, getname_ipocurve(icu));
+               if (G.saction->pin)
+                       sprintf(str, getname_ipocurve(icu, NULL));
+               else
+                       sprintf(str, getname_ipocurve(icu, OBACT));
                
                if (IS_EQ(icu->slide_max, icu->slide_min)) {
                        if (IS_EQ(icu->ymax, icu->ymin)) {
index 96be44e12348b7b756dbe4a8d036b02729d27912..971d5365538b16ce70b75ef0530a645c67a6d7ea 100644 (file)
 
 #include "DNA_curve_types.h"
 #include "DNA_ipo_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
 #include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_view3d_types.h"
 
 #include "BKE_global.h"
 #include "BKE_ipo.h"
+#include "BKE_key.h"
 #include "BKE_utildefines.h"
 
 #include "BIF_resources.h"
@@ -130,8 +133,11 @@ int geticon_ipo_blocktype(short blocktype)
        }
 }
 
-/* get name of ipo-curve (icu should be valid pointer) */
-char *getname_ipocurve(IpoCurve *icu)
+/* get name of ipo-curve
+ *     - icu should be valid pointer
+ *     - ob is only needed for a shapekey-related hack
+ */
+char *getname_ipocurve(IpoCurve *icu, Object *ob)
 {
        switch (icu->blocktype) {
                case ID_OB: 
@@ -140,11 +146,29 @@ char *getname_ipocurve(IpoCurve *icu)
                        return getname_ac_ei(icu->adrcode);
                case ID_KE:
                        {
-                               /* quick 'hack' - must find a better solution to this
-                                * although shapekey ipo-curves can have names,
-                                * we don't have access to that info yet.
-                                */
                                static char name[32];
+                               Key *key= ob_get_key(ob);
+                               
+                               if (key) {
+                                       KeyBlock *kb= key->block.first;
+                                       int i;
+                                       
+                                       for (i= 1; i < key->totkey; i++) {
+                                               kb= kb->next;
+                                               
+                                               if (icu->adrcode == i) {
+                                                       /* only return name if it has been set, otherwise use 
+                                                        * default method using static string (Key #)
+                                                        */
+                                                       if (kb->name[0] == '\0')
+                                                               break; /* stop looping through keyblocks */
+                                                       else
+                                                               return kb->name; /* return keyblock's name  */
+                                               }
+                                       }
+                               }
+                               
+                               /* in case keyblock is not named or no key/keyblock was found */
                                sprintf(name, "Key %d", icu->adrcode);
                                return name;
                        }
index 7685ec99b2e52a45adc0abd58dd4d2c126df8bf8..3d03adbc4bbada455e502809b818374630b70261 100644 (file)
@@ -949,13 +949,43 @@ void do_global_buttons(unsigned short event)
                else {
 
                        /* Store current action */
-                       if (!idtest){
+                       if (!idtest) {
+                               /* 'Add New' option: 
+                                *      - make a copy of an exisiting action
+                                *      - or make a new empty action if no existing action
+                                */
                                if (act) {
                                        idtest= (ID *)copy_action(act);
-                               } else { 
+                               } 
+                               else { 
                                        if (ID_OB==ob->type) {
+                                               /* for empties */
                                                idtest=(ID *)add_empty_action("ObAction");
-                                       } else {
+                                       } 
+                                       else if (ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
+                                               /* shapekey - like if B_IPO_ACTION_KEY is triggered */
+                                               bActionChannel *achan;
+                                               Key *key= ob_get_key(ob);
+                                               
+                                               ob->ipoflag |= OB_ACTION_KEY;
+                                               
+                                               act = add_empty_action("ShapeAction");
+                                               idtest=(ID *)act;
+                                               
+                                               achan= verify_action_channel(act, "Shape");
+                                               achan->flag = (ACHAN_HILIGHTED|ACHAN_SELECTED|ACHAN_EXPANDED|ACHAN_SHOWIPO);
+                                               
+                                               if(achan->ipo==NULL && key->ipo) {
+                                                       achan->ipo= key->ipo;
+                                                       key->ipo= NULL;
+                                                       
+                                                       allqueue(REDRAWVIEW3D, 0);
+                                                       allqueue(REDRAWIPO, 0);
+                                                       allqueue(REDRAWOOPS, 0);
+                                               }
+                                       }
+                                       else {
+                                               /* a plain action */
                                                idtest=(ID *)add_empty_action("Action");
                                        }
                                }