Support for using the action window as a tool for modifying
authorChris Want <cwant@ualberta.ca>
Sun, 20 Jul 2003 23:04:09 +0000 (23:04 +0000)
committerChris Want <cwant@ualberta.ca>
Sun, 20 Jul 2003 23:04:09 +0000 (23:04 +0000)
(mesh or lattice) RVK IpoCurves: support currently includes:

- RVK sliders. Pressing the little triangle next to
  the word 'sliders' in the channel names opens them up.
- NKEY in the area where the key block names are allows the
  user to change the name of the keyblock, and the max and min
  values of the RVK sliders.
- ability to visualize the keyframes for the IpoCurves when
  the object is selected.
- right mouse can be used to select the keys
- border select in the main area can be used to border
  select keys.
- AKEY selects/deselects all of the keys
- GKEY and SKEY can be used to grab or scale the key
  selections.
- XKEY deletes the selected keys.
- DKEY duplicated the selected keys.
- VKEY, HKEY and shift-HKEY change the bezier handles for
  the selected keys.

Please, please, please test!

source/blender/include/BSE_editaction.h
source/blender/include/BSE_editaction_types.h
source/blender/include/BSE_editipo.h
source/blender/makesdna/DNA_key_types.h
source/blender/src/drawaction.c
source/blender/src/drawipo.c
source/blender/src/editaction.c
source/blender/src/editipo.c
source/blender/src/editkey.c
source/blender/src/headerbuttons.c
source/blender/src/toolbox.c

index 5e88ba90bf2bf93f7100b3f76721ace86de9f700..13539c111f01a89523e1054b17a36942d3485aa7 100644 (file)
@@ -39,6 +39,7 @@ struct bPoseChannel;
 struct Object;
 struct Ipo;
 struct BWinEvent;
+struct Key;
 
 struct bActionChannel* get_hilighted_action_channel(struct bAction* action);
 void set_exprap_action(int mode);
@@ -49,10 +50,13 @@ void set_action_key (struct bAction *act, struct bPoseChannel *chan, int adrcode
 struct bAction *add_empty_action(void);
 void deselect_actionchannel_keys (struct bAction *act, int test);
 void deselect_actionchannels (struct bAction *act, int test);
+void deselect_meshchannel_keys (struct Key *key, int test);
 void winqreadactionspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
 void remake_action_ipos(struct bAction *act);
 void select_actionchannel_by_name (struct bAction *act, char *name, int select);
 struct bAction *bake_action_with_client (struct bAction *act, struct Object *arm, float tolerance);
-
+struct Key *get_action_mesh_key(void);
+int get_nearest_key_num(struct Key *key, short *mval, float *x);
+void stupid_damn_numbuts_action(void);
 #endif /* BSE_EDITACTION_H */
 
index 16e4890daef643e60f22aa2830f78a9dc283bf2d..4df6c6712fb471e43acd2e3d36918083ae04bbae 100644 (file)
@@ -35,7 +35,8 @@
 
 #define        CHANNELHEIGHT   16
 #define        CHANNELSKIP             2
-#define ACTWIDTH       128
+#define NAMEWIDTH      128
+#define SLIDERWIDTH    125
 
 #define CHANNEL_FILTER_LOC             0x00000001      /* Show location keys */
 #define CHANNEL_FILTER_ROT             0x00000002      /* Show rotation keys */
index 3522056f21eee8c35fe0b4cbb0704bd7bcdd214b..9ae57db0a22ec7dc0044488c99d298e3951b3537 100644 (file)
@@ -90,6 +90,7 @@ void move_to_frame(void);
 void do_ipowin_buts(short event);
 void do_ipo_selectbuttons(void);
 struct EditIpo *get_editipo(void);
+struct Ipo *get_ipo(struct ID *from, short type, int make);
 struct IpoCurve *get_ipocurve(struct ID *from, short type, int adrcode, struct Ipo* useipo);
 void insert_vert_ipo(struct IpoCurve *icu, float x, float y);
 void add_vert_ipo(void);
@@ -116,6 +117,7 @@ void common_insertkey(void);
 void free_ipokey(struct ListBase *lb);
 void add_to_ipokey(struct ListBase *lb, struct BezTriple *bezt, int nr, int len);
 void make_ipokey(void);
+void make_ipokey_spec(struct ListBase *lb, struct Ipo *ipo);
 void make_ipokey_transform(struct Object *ob, struct ListBase *lb, int sel);
 void update_ipokey_val(void);
 void set_tob_old(float *old, float *poin);
@@ -141,6 +143,8 @@ int fullselect_ipo_keys(struct Ipo *ipo);
 int add_trans_ipo_keys(struct Ipo *ipo, struct TransVert *tv, int tvtot);
 void duplicate_ipo_keys(struct Ipo *ipo);
 void borderselect_ipo_key(struct Ipo *ipo, float xmin, float xmax, int val);
+void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax, 
+                                                 int (*select_function)(struct BezTriple *));
 void select_ipo_key(struct Ipo *ipo, float selx, int sel);
 void select_icu_key(struct IpoCurve *icu, float selx, int selectmode);
 int select_bezier_add(struct BezTriple *bezt);
index 55f6d81aa0605793bcc8d70fd0a85ac329feb8d0..6c36febbff70b7efdf7ade5a4c90ceba460a1a37 100644 (file)
@@ -48,7 +48,10 @@ typedef struct KeyBlock {
        int pad;
        
        void *data;
-       
+       char  name[32];
+
+       float slidermin;
+       float slidermax;
 } KeyBlock;
 
 
index 80af4d27676d2b6f859b520d0971661ff92c8312..482fb4448e6c9f4b5285f410a42ac03f1af41a5e 100644 (file)
@@ -60,6 +60,8 @@
 #include "DNA_scene_types.h"
 #include "DNA_space_types.h"
 #include "DNA_constraint_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_key_types.h"
 
 #include "BKE_action.h"
 #include "BKE_global.h"
 #include "BDR_editcurve.h"
 #include "BSE_view.h"
 #include "BSE_drawipo.h"
+#include "BSE_editaction.h"
 #include "BSE_editaction_types.h"
 #include "BDR_drawaction.h"
 
 /* 'old' stuff": defines and types, and own include -------------------- */
 
 #include "blendef.h"
+#include "interface.h"
+#include "mydevice.h"
+
+#include "BKE_ipo.h"
 
 /* local functions ----------------------------------------------------- */
 void drawactionspace(ScrArea *sa, void *spacedata);
@@ -91,10 +98,93 @@ int count_action_levels(bAction *act);
 static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert);
 static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert);
 static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert);
+static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert);
 static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos);
-
+void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos);
+static void draw_action_mesh_names(Key *key);
 
 /* implementation ------------------------------------------------------ */
+
+extern void make_rvk_slider(uiBlock *block, Key *key, int i,
+                                                       int x, int y, int w, int h); /* editkey.c */
+extern short showsliders; /* editaction .c */
+extern short ACTWIDTH;
+
+void meshactionbuts(SpaceAction *saction, Key *key)
+{
+       int           i;
+       char          str[64];
+       char          keyname[32];
+       float           x, y, ybase;
+       uiBlock       *block;
+       uiBut         *but;
+    short ofsx, ofsy = 0; 
+#define RVKBGCOL .6, .6, .8
+#define XIC 20
+#define YIC 20
+
+       /* lets make the rvk sliders */
+
+       /* reset the damn myortho2 or the sliders won't draw/redraw
+        * correctly *grumble*
+        */
+       mywinset(curarea->win);
+       myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
+
+    sprintf(str, "actionbuttonswin %d", curarea->win);
+    block= uiNewBlock (&curarea->uiblocks, str, 
+                       UI_EMBOSSX, UI_HELV, curarea->win);
+
+       x = NAMEWIDTH + 1;
+    y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP) 
+         - CHANNELHEIGHT/2  - G.v2d->cur.ymin;
+
+    uiBlockSetCol(block, BUTPURPLE);
+
+       /* make the little 'open the sliders' widget */
+    glColor3f(RVKBGCOL); 
+       glRects(2,            y + 2*CHANNELHEIGHT - 2,  
+                       ACTWIDTH - 2, y + CHANNELHEIGHT + 2);
+       glColor3ub(0, 0, 0);
+       glRasterPos2f(4, y + CHANNELHEIGHT + 6);
+       BMF_DrawString(G.font, "Sliders");
+
+       uiBlockSetEmboss(block, UI_EMBOSSN);
+
+       if (!showsliders) {
+               ACTWIDTH = NAMEWIDTH;
+               uiDefIconButS(block, TOG, B_FLIPINFOMENU, 
+                                         ICON_DISCLOSURE_TRI_RIGHT,
+                                         NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
+                                         XIC,YIC-2,
+                                         &(showsliders), 0, 0, 0, 0, 
+                                         "Show action window sliders");
+       }
+       else {
+               uiDefIconButS(block, TOG, B_FLIPINFOMENU, 
+                                         ICON_DISCLOSURE_TRI_DOWN,
+                                         NAMEWIDTH - XIC - 5, y + CHANNELHEIGHT,
+                                         XIC,YIC-2,
+                                         &(showsliders), 0, 0, 0, 0, 
+                                         "Hide action window sliders");
+               ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
+
+               /* sliders are open so draw them */
+               glColor3f(RVKBGCOL); 
+               glRects(NAMEWIDTH,  0,  NAMEWIDTH+SLIDERWIDTH,  curarea->winy);
+               uiBlockSetEmboss(block, UI_EMBOSSX);
+               for (i=1 ; i < key->totkey ; ++ i) {
+                       make_rvk_slider(block, key, i, 
+                                                       x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1);
+
+                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                       
+               }
+       }
+       uiDrawBlock(block);
+
+}
+
 void draw_cfra_action(void)
 {
        Object *ob;
@@ -129,24 +219,105 @@ void draw_cfra_action(void)
        glLineWidth(1.0);
 }
 
+
+static void draw_action_channel_names(bAction  *act) {
+    bActionChannel *chan;
+    bConstraintChannel *conchan;
+    float      x, y;
+
+    x = 0.0;
+               y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
+
+               for (chan=act->chanbase.first; chan; chan=chan->next){
+        glColor3ub(0xAA, 0xAA, 0xAA);
+        glRectf(x,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
+
+        if (chan->flag & ACHAN_SELECTED)
+            glColor3ub(255, 255, 255);
+        else
+            glColor3ub(0, 0, 0);
+        glRasterPos2f(x+8,  y-4);
+        BMF_DrawString(G.font, chan->name);
+        y-=CHANNELHEIGHT+CHANNELSKIP;
+
+        /* Draw constraint channels */
+        for (conchan=chan->constraintChannels.first; 
+             conchan; conchan=conchan->next){
+            if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
+                glColor3ub(255, 255, 255);
+            else
+                glColor3ub(0, 0, 0);
+                               
+            glRasterPos2f(x+32,  y-4);
+            BMF_DrawString(G.font, conchan->name);
+            y-=CHANNELHEIGHT+CHANNELSKIP;
+        }
+               }
+}
+
+
+static void draw_action_mesh_names(Key *key) {
+       /* draws the names of the rvk keys in the
+        * left side of the action window
+        */
+       int          i;
+       char     keyname[32];
+       float    x, y;
+       KeyBlock *kb;
+
+       x = 0.0;
+       y= key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+
+       kb= key->block.first;
+
+       for (i=1 ; i < key->totkey ; ++ i) {
+               glColor3ub(0xAA, 0xAA, 0xAA);
+               glRectf(x,      y-CHANNELHEIGHT/2,      (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
+
+               glColor3ub(0, 0, 0);
+
+               glRasterPos2f(x+8,      y-4);
+               kb = kb->next;
+               /* Blender now has support for named
+                * key blocks. If a name hasn't
+                * been set for an key block then
+                * just display the key number -- 
+                * otherwise display the name stored
+                * in the keyblock.
+                */
+               if (kb->name[0] == '\0') {
+                 sprintf(keyname, "Key %d", i);
+                 BMF_DrawString(G.font, keyname);
+               }
+               else {
+                 BMF_DrawString(G.font, kb->name);
+               }
+
+               y-=CHANNELHEIGHT+CHANNELSKIP;
+
+       }
+}
+
 static void draw_channel_names(void) 
 {
        short ofsx, ofsy = 0; 
-
+       float y;
        bAction *act;
-       bActionChannel *chan;
-       bConstraintChannel *conchan;
-       float   x, y;
-       
-       myortho2                (0,     ACTWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax);    //      Scaling
+       Key *key;
+
+       myortho2                (0,     NAMEWIDTH, G.v2d->cur.ymin, G.v2d->cur.ymax);   //      Scaling
 
        /* Blank out the area */
        if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
                if(G.v2d->scroll) {     
                        ofsx= curarea->winrct.xmin;     
                        ofsy= curarea->winrct.ymin;
-                       glViewport(ofsx,  ofsy+G.v2d->mask.ymin-SCROLLB, ACTWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB)); 
-                       glScissor(ofsx,  ofsy+G.v2d->mask.ymin-SCROLLB, ACTWIDTH, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB));
+                       glViewport(ofsx,  ofsy+G.v2d->mask.ymin-SCROLLB, NAMEWIDTH, 
+                                          (ofsy+G.v2d->mask.ymax) -
+                                          (ofsy+G.v2d->mask.ymin-SCROLLB)); 
+                       glScissor(ofsx,  ofsy+G.v2d->mask.ymin-SCROLLB, NAMEWIDTH, 
+                                         (ofsy+G.v2d->mask.ymax) -
+                                         (ofsy+G.v2d->mask.ymin-SCROLLB));
                }
        }
        
@@ -158,76 +329,67 @@ static void draw_channel_names(void)
        glColor3ub(0x00, 0x00, 0x00);
 
        act=G.saction->action;
-       x = 0.0;
-
-       if (act) {              
-               y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
-
-               for (chan=act->chanbase.first; chan; chan=chan->next){
-                       glColor3ub(0xAA, 0xAA, 0xAA);
-                       glRectf(x,  y-CHANNELHEIGHT/2,  (float)ACTWIDTH,  y+CHANNELHEIGHT/2);
-
-                       if (chan->flag & ACHAN_SELECTED)
-                               glColor3ub(255, 255, 255);
-                       else
-                               glColor3ub(0, 0, 0);
-                       glRasterPos2f(x+8,  y-4);
-                       BMF_DrawString(G.font, chan->name);
-                       y-=CHANNELHEIGHT+CHANNELSKIP;
-
-                       /* Draw constraint channels */
-                       for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){
-                               if (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
-                                       glColor3ub(255, 255, 255);
-                               else
-                                       glColor3ub(0, 0, 0);
-                               
-                               glRasterPos2f(x+32,  y-4);
-                               BMF_DrawString(G.font, conchan->name);
-                               y-=CHANNELHEIGHT+CHANNELSKIP;
-                       }
-               }
-       }
        
-
-       myortho2                (0,     ACTWIDTH, 0, ( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB));        //      Scaling
-
-       glShadeModel(GL_SMOOTH);
+       
+       if (act) {
+               /* if there is a selected action then
+                * draw the channel names
+                */
+               draw_action_channel_names(act);
+       }
+       else {
+           if ( (key = get_action_mesh_key()) ) {
+            /* if there is a mesh selected with rvk's,
+             * then draw the RVK names
+             */
+            draw_action_mesh_names(key);
+        }
+    }
+
+    myortho2 (0,       NAMEWIDTH, 0, 
+              (ofsy+G.v2d->mask.ymax) -
+              (ofsy+G.v2d->mask.ymin-SCROLLB));        //      Scaling
+
+    glShadeModel(GL_SMOOTH);
  
-       y=9;
-
-       /* Draw sexy shaded block thingies */
-       glEnable (GL_BLEND);
-       glBegin(GL_QUAD_STRIP);
-       glColor4ub (0xCC,0xCC,0xCC,0x00);
-       glVertex2f (0,SCROLLB*2-y);
-       glVertex2f (ACTWIDTH,SCROLLB*2-y);
-
-       glColor4ub (0xCC,0xCC,0xCC,0xFF);
-       glVertex2f (0,SCROLLB-y);
-       glVertex2f (ACTWIDTH,SCROLLB-y);
-
-       glColor4ub (0xCC,0xCC,0xCC,0xFF);
-       glVertex2f (0,0-y);
-       glVertex2f (ACTWIDTH,0-y);
-
-       glEnd();
-
-/*     y=( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB);
-
-       glBegin(GL_QUAD_STRIP);
-       glColor4ub (0x88,0x88,0x88,0xFF);
-       glVertex2f (0,y);
-       glVertex2f (ACTWIDTH,y);
-       glColor4ub (0x88,0x88,0x88,0x00);
-       glVertex2f (0,y-SCROLLB);
-       glVertex2f (ACTWIDTH,y-SCROLLB);
+    y=9;
+
+    /* Draw sexy shaded block thingies
+          Reevan: if you start developing this stuff again
+          you can have your blend's back
+          
+    glEnable (GL_BLEND);
+    glBegin(GL_QUAD_STRIP);
+    glColor4ub (0xCC,0xCC,0xCC,0x00);
+    glVertex2f (0,SCROLLB*2-y);
+    glVertex2f (NAMEWIDTH,SCROLLB*2-y);
+
+    glColor4ub (0xCC,0xCC,0xCC,0xFF);
+    glVertex2f (0,SCROLLB-y);
+    glVertex2f (NAMEWIDTH,SCROLLB-y);
+
+    glColor4ub (0xCC,0xCC,0xCC,0xFF);
+    glVertex2f (0,0-y);
+    glVertex2f (NAMEWIDTH,0-y);
+
+    glEnd();
+       */
+
+    /* y=( ofsy+G.v2d->mask.ymax)-( ofsy+G.v2d->mask.ymin-SCROLLB);
+
+        glBegin(GL_QUAD_STRIP);
+        glColor4ub (0x88,0x88,0x88,0xFF);
+        glVertex2f (0,y);
+        glVertex2f (NAMEWIDTH,y);
+        glColor4ub (0x88,0x88,0x88,0x00);
+        glVertex2f (0,y-SCROLLB);
+        glVertex2f (NAMEWIDTH,y-SCROLLB);
        
-       glEnd();
-*/
-       glDisable (GL_BLEND);
+        glEnd();
+    */
+    glDisable (GL_BLEND);
 
-       glShadeModel(GL_FLAT);
+    glShadeModel(GL_FLAT);
 
 }
 
@@ -345,21 +507,96 @@ static void draw_channel_strips(SpaceAction *saction)
        glaEnd2DDraw(di);
 }
 
+static void draw_mesh_strips(SpaceAction *saction, Key *key)
+{
+       /* draw the RVK keyframes as those little square button things
+        */
+       rcti scr_rct;
+       gla2DDrawInfo *di;
+       float   y, ybase;
+       IpoCurve *icu;
+
+       if (!key->ipo) return;
+
+       scr_rct.xmin= saction->area->winrct.xmin + ACTWIDTH;
+       scr_rct.ymin= saction->area->winrct.ymin + saction->v2d.mask.ymin-SCROLLB;
+       scr_rct.xmax= saction->area->winrct.xmin + saction->v2d.hor.xmax;
+       scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax; 
+       di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
+
+       ybase = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+
+       for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+
+               int frame1_x, channel_y;
+
+               /* lets not deal with the "speed" Ipo
+                */
+               if (icu->adrcode==0) continue;
+
+               y = ybase       - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
+               gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+
+               /* all frames that have a frame number less than one
+                * get a desaturated orange background
+                */
+               glEnable(GL_BLEND);
+               glColor4b(0x55, 0x22, 0x11, 0x22);
+               glRectf(0,        channel_y-CHANNELHEIGHT/2,  
+                               frame1_x, channel_y+CHANNELHEIGHT/2);
+
+               /* frames one and higher get a saturated orange background
+                */
+               glColor4b(0x55, 0x22, 0x11, 0x44);
+               glRectf(frame1_x,         channel_y-CHANNELHEIGHT/2,  
+                               G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2);
+               glDisable(GL_BLEND);
+
+               /* draw the little squares
+                */
+               draw_icu_channel(di, icu, 0, y); 
+       }
+
+       glaEnd2DDraw(di);
+}
+
 void drawactionspace(ScrArea *sa, void *spacedata)
 {
 
        short ofsx = 0, ofsy = 0;
-       
+       Key *key;
+       short maxymin;
+
        if (!G.saction)
                return;
 
-
        if (!G.saction->pin) {
                if (OBACT)
                        G.saction->action = OBACT->action;
                else
                        G.saction->action=NULL;
        }
+       key = get_action_mesh_key();
+
+       /* Damn I hate hunting to find my rvk's because
+        * they have scrolled off of the screen ... this
+        * oughta fix it
+        */
+                  
+       if (key) {
+               if (G.v2d->cur.ymin < -CHANNELHEIGHT) 
+                       G.v2d->cur.ymin = -CHANNELHEIGHT;
+               
+               maxymin = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+               if (G.v2d->cur.ymin > maxymin) G.v2d->cur.ymin = maxymin;
+       }
+       
+       /* Lets make sure the width of the left hand of the screen
+        * is set to an appropriate value based on whether sliders
+        * are showing of not
+        */
+       if (key && showsliders) ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
+       else ACTWIDTH = NAMEWIDTH;
 
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
 
@@ -369,15 +606,20 @@ void drawactionspace(ScrArea *sa, void *spacedata)
                if(G.v2d->scroll) {     
                        ofsx= curarea->winrct.xmin;     
                        ofsy= curarea->winrct.ymin;
-                       glViewport(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
-                       glScissor(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
+                       glViewport(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, 
+                                          ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
+                                          ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
+                       glScissor(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, 
+                                         ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
+                                         ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
                }
        }
 
        glClearColor(.45, .45, .45, 0.0); 
        glClear(GL_COLOR_BUFFER_BIT);
 
-       myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+       myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, 
+                         G.v2d->cur.ymin, G.v2d->cur.ymax);
 
        /*      Draw backdrop */
        calc_ipogrid(); 
@@ -386,25 +628,49 @@ void drawactionspace(ScrArea *sa, void *spacedata)
        /* Draw channel strips */
        draw_channel_strips(G.saction);
 
+       if (key) {
+               /* if there is a mesh with rvk's selected,
+                * then draw the key frames in the action window
+                */
+               draw_mesh_strips(G.saction, key);
+               /*meshactionbuts(G.saction, key);*/
+       }
+
+
        /* Draw current frame */
-       glViewport(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
-       glScissor(ofsx+G.v2d->mask.xmin,  ofsy+G.v2d->mask.ymin, ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
-       myortho2 (G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
+       glViewport(ofsx+G.v2d->mask.xmin,  
+             ofsy+G.v2d->mask.ymin, 
+             ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
+             ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1); 
+       glScissor(ofsx+G.v2d->mask.xmin,  
+            ofsy+G.v2d->mask.ymin, 
+            ( ofsx+G.v2d->mask.xmax-1)-(ofsx+G.v2d->mask.xmin)+1, 
+            ( ofsy+G.v2d->mask.ymax-1)-( ofsy+G.v2d->mask.ymin)+1);
+       myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, 
+           G.v2d->cur.ymin, G.v2d->cur.ymax);
        draw_cfra_action();
 
        /* Draw scroll */
        mywinset(curarea->win);
        if(curarea->winx>SCROLLB+10 && curarea->winy>SCROLLH+10) {
-               myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
-               if(G.v2d->scroll) drawscroll(0);
+      myortho2(-0.5, curarea->winx+0.5, -0.5, curarea->winy+0.5);
+      if(G.v2d->scroll) drawscroll(0);
        }
 
        /* Draw channel names */
        draw_channel_names();
 
+       if ( key ) {
+               /* if there is a mesh with rvk's selected,
+                * then draw the key frames in the action window
+                */
+               meshactionbuts(G.saction, key);
+       }
+
        curarea->win_swap= WIN_BACK_OK;
 }
 
+
 void draw_channel_name(const char* name, short type, float ypos, int selected)
 {
 }
@@ -449,6 +715,20 @@ void draw_ipo_channel(gla2DDrawInfo *di, Ipo *ipo, int flags, float ypos)
        }
 }
 
+void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos)
+{
+       /* draw the keys for an IpoCurve
+        */
+       BezTriple **blist;
+       int totvert;
+
+       blist = icu_to_keylist(icu, flags, &totvert);
+       if (blist){
+               draw_keylist(di,totvert, blist, ypos);
+               MEM_freeN(blist);
+       }
+}
+
 void draw_action_channel(gla2DDrawInfo *di, bAction *act, int flags, float ypos)
 {
        BezTriple **blist;
@@ -503,6 +783,31 @@ static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert)
        return list;
 }
 
+static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert)
+{
+       /* compile a list of all bezier triples in an
+        * IpoCurve.
+        */
+       int v, count = 0;
+
+       BezTriple **list = NULL;
+
+       count=icu->totvert;
+
+       if (count){
+               list = MEM_callocN(sizeof(BezTriple*)*count, "beztlist");
+               count=0;
+                       
+               for (v=0; v<icu->totvert; v++){
+                       list[count++]=&icu->bezt[v];
+               }
+               qsort(list, count, sizeof(BezTriple*), bezt_compare);
+       }
+       (*totvert)=count;
+       return list;
+
+}
+
 static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert)
 {
        IpoCurve *icu;
index 0fa5e6d365f0bd821a1340e44c659623795d87bc..e82e19b3cff4e3c114253ac5d05c4924306b8036 100644 (file)
@@ -94,7 +94,7 @@ static int ipomachtx, ipomachty;
 
 static int vertymin, vertymax, horxmin, horxmax;       /* globals om LEFTMOUSE op scrollbar te testen */
 
-
+extern short ACTWIDTH;
 
 static void scroll_prstr(float x, float y, float val, char dir, int disptype)
 {
index 01f0ff4ff2bd783f5bab0db6e9cc2a055484da97..dbde1c22d84a55f3f1224d112e55568217cbafea 100644 (file)
@@ -57,6 +57,9 @@
 #include "DNA_screen_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_lattice_types.h"
 
 #include "BKE_armature.h"
 #include "BKE_constraint.h"
@@ -67,6 +70,7 @@
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_action.h"
+#include "BKE_key.h"
 
 #include "BIF_gl.h"
 #include "BIF_mywindow.h"
@@ -107,17 +111,24 @@ static void mouse_actionchannels(bAction *act, short *mval,
                                  short *mvalo, int selectmode);
 static void borderselect_action(void);
 static void mouse_action(int selectmode);
+static void mouse_mesh_action(int selectmode, Key *key);
 static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, bConstraintChannel **conchan);
+static void sethandles_actionchannel_keys(int code);
 static void delete_actionchannels(void);
 static void delete_actionchannel_keys(void);
 static void duplicate_actionchannel_keys(void);
 static void transform_actionchannel_keys(char mode);
+static void transform_meshchannel_keys(char mode, Key *key);
 static void select_poseelement_by_name (char *name, int select);
 static void hilight_channel (bAction *act, bActionChannel *chan, short hilight);
 static void set_action_key_time (bAction *act, bPoseChannel *chan, int adrcode, short makecurve, float time);
+static void clever_numbuts_meshaction(Key *key, short* mval);
 
 /* Implementation */
 
+short showsliders = 0;
+short ACTWIDTH = NAMEWIDTH;
+
 static void select_poseelement_by_name (char *name, int select)
 {
        /* Synchs selection of channels with selection of object elements in posemode */
@@ -277,6 +288,40 @@ void remake_action_ipos(bAction *act)
        }
 }
 
+void remake_meshaction_ipos(Ipo *ipo)
+{
+       /* this puts the bezier triples in proper
+        * order and makes sure the bezier handles
+        * aren't too strange.
+        */
+       IpoCurve *icu;
+
+       for (icu = ipo->curve.first; icu; icu=icu->next){
+               sort_time_ipocurve(icu);
+               testhandles_ipocurve(icu);
+       }
+}
+
+static void meshkey_do_redraw(Key *key)
+{
+       remake_meshaction_ipos(key->ipo);
+    do_all_ipos();
+    do_spec_key(key);
+
+       allspace(REMAKEIPO, 0);
+       allqueue(REDRAWACTION, 0);
+       allqueue(REDRAWIPO, 0);
+       allqueue(REDRAWNLA, 0);
+
+}
+
+static void duplicate_meshchannel_keys(Key *key)
+{
+       duplicate_ipo_keys(key->ipo);
+       transform_meshchannel_keys ('g', key);
+}
+
+
 static void duplicate_actionchannel_keys(void)
 {
        bAction *act;
@@ -396,6 +441,110 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel,
        return firstchan;
 }
 
+static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
+{
+       /* This function tries to find the RVK key that is
+        * closest to the user's mouse click
+        */
+    Key      *key;
+    IpoCurve *icu; 
+    IpoCurve *firsticu=NULL;
+    int             foundsel=0;
+    float    firstvert=-1, foundx=-1;
+       int      i;
+    short    mval[2];
+    float    ymin, ymax, ybase;
+    rctf     rectf;
+
+    *index=0;
+
+    key = get_action_mesh_key();
+       
+    /* lets get the mouse position and process it so 
+     * we can start testing selections
+     */
+    getmouseco_areawin (mval);
+    mval[0]-=7;
+    areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+    mval[0]+=14;
+    areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
+
+    ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
+    *sel=0;
+
+    /* lets loop through the IpoCurves trying to find the closest
+     * bezier
+     */
+    for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+        /* lets not deal with the "speed" Ipo
+         */
+        if (!icu->adrcode) continue;
+
+        ymax = ybase   - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
+        ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
+
+        /* Does this curve coorespond to the right
+         * strip?
+         */
+        if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))){
+                       
+            /* loop through the beziers in the curve
+             */
+            for (i=0; i<icu->totvert; i++){
+
+                /* Is this bezier in the right area?
+                 */
+                if (icu->bezt[i].vec[1][0] > rectf.xmin && 
+                    icu->bezt[i].vec[1][0] <= rectf.xmax ){
+
+                    /* if no other curves have been picked ...
+                     */
+                    if (!firsticu){
+                        /* mark this curve/bezier as the first
+                         * selected
+                         */
+                        firsticu=icu;
+                        firstvert=icu->bezt[i].vec[1][0];
+
+                        /* sel = (is the bezier is already selected) ? 1 : 0;
+                         */
+                        *sel = icu->bezt[i].f2 & 1;    
+                    }
+
+                    /* if the bezier is selected ...
+                     */
+                    if (icu->bezt[i].f2 & 1){ 
+                        /* if we haven't found a selected one yet ...
+                         */
+                        if (!foundsel){
+                            /* record the found x value
+                             */
+                            foundsel=1;
+                            foundx = icu->bezt[i].vec[1][0];
+                        }
+                    }
+
+                    /* if the bezier is unselected and not at the x
+                     * position of a previous found selected bezier ...
+                     */
+                    else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
+                        /* lets return this found curve/bezier
+                         */
+                        *index=icu->bezt[i].vec[1][0];
+                        *sel = 0;
+                        return icu;
+                    }
+                }
+            }
+        }
+       }
+       
+    /* return what we've found
+     */
+    *index=firstvert;
+    return firsticu;
+}
+
 static void mouse_action(int selectmode)
 {
        bAction *act;
@@ -439,6 +588,63 @@ static void mouse_action(int selectmode)
        }
 }
 
+static void mouse_mesh_action(int selectmode, Key *key)
+{
+       /* Handle a right mouse click selection in an
+        * action window displaying RVK data
+        */
+
+    IpoCurve *icu;
+    short  sel;
+    float  selx;
+    short  mval[2];
+
+    /* going to assume that the only reason 
+     * we got here is because it has been 
+     * determined that we are a mesh with
+     * the right properties (i.e., have key
+     * data, etc)
+     */
+
+       /* get the click location, and the cooresponding
+        * ipo curve and selection time value
+        */
+    getmouseco_areawin (mval);
+    icu = get_nearest_meshchannel_key(&selx, &sel);
+
+    if (icu){
+        if (selectmode == SELECT_REPLACE) {
+                       /* if we had planned to replace the
+                        * selection, then we will first deselect
+                        * all of the keys, and if the clicked on
+                        * key had been unselected, we will select 
+                        * it, otherwise, we are done.
+                        */
+            deselect_meshchannel_keys(key, 0);
+
+            if (sel == 0)
+                selectmode = SELECT_ADD;
+            else
+                               /* the key is selected so we should
+                                * deselect -- but everything is now deselected
+                                * so we are done.
+                                */
+                               return;
+        }
+               
+               /* select the key using the given mode
+                * and redraw as mush stuff as needed.
+                */
+               select_icu_key(icu, selx, selectmode);
+
+        allqueue(REDRAWIPO, 0);
+        allqueue(REDRAWVIEW3D, 0);
+        allqueue(REDRAWACTION, 0);
+        allqueue(REDRAWNLA, 0);
+
+    }
+}
+
 static void borderselect_action(void)
 { 
        rcti rect;
@@ -496,6 +702,61 @@ static void borderselect_action(void)
        }
 }
 
+static void borderselect_mesh(Key *key)
+{ 
+       rcti     rect;
+       int      val, adrcodemax, adrcodemin;
+       short    mval[2];
+       float    xmin, xmax;
+       int      (*select_function)(BezTriple *);
+       IpoCurve *icu;
+
+       if ( (val = get_border(&rect, 3)) ){
+               /* set the selection function based on what
+                * mouse button had been used in the border
+                * select
+                */
+               if (val == LEFTMOUSE)
+                       select_function = select_bezier_add;
+               else
+                       select_function = select_bezier_subtract;
+
+               /* get the minimum and maximum adrcode numbers
+                * for the IpoCurves (this is the number that
+                * relates an IpoCurve to the keyblock it
+                * controls).
+                */
+               mval[0]= rect.xmin;
+               mval[1]= rect.ymin+2;
+               adrcodemax = get_nearest_key_num(key, mval, &xmin);
+               adrcodemax = (adrcodemax >= key->totkey) ? key->totkey : adrcodemax;
+
+               mval[0]= rect.xmax;
+               mval[1]= rect.ymax-2;
+               adrcodemin = get_nearest_key_num(key, mval, &xmax);
+               adrcodemin = (adrcodemin < 1) ? 1 : adrcodemin;
+
+               /* Lets loop throug the IpoCurves and do borderselect
+                * on the curves with adrcodes in our selected range.
+                */
+               for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+                       /* lets not deal with the "speed" Ipo
+                        */
+                       if (!icu->adrcode) continue;
+                       if ( (icu->adrcode >= adrcodemin) && 
+                                (icu->adrcode <= adrcodemax) ) {
+                               borderselect_icu_key(icu, xmin, xmax, select_function);
+                       }
+               }
+
+               /* redraw stuff */
+               allqueue(REDRAWNLA, 0);
+               allqueue(REDRAWACTION, 0);
+               allqueue(REDRAWIPO, 0);
+       }
+}
+
+
 bActionChannel* get_hilighted_action_channel(bAction* action)
 {
        bActionChannel *chan;
@@ -1017,6 +1278,192 @@ static void transform_actionchannel_keys(char mode)
        MEM_freeN (tv);
 }
 
+static void transform_meshchannel_keys(char mode, Key *key)
+{
+       /* this is the function that determines what happens
+        * to those little blocky rvk key things you have selected 
+        * after you press a 'g' or an 's'. I'd love to say that
+        * I have an intimate knowledge of all of what this function
+        * is doing, but instead I'm just going to pretend.
+        */
+    TransVert *tv;
+    int /*sel=0,*/  i;
+    short      mvals[2], mvalc[2], cent[2];
+    float      sval[2], cval[2], lastcval[2];
+    short      cancel=0;
+    float      fac=0.0F;
+    int                loop=1;
+    int                tvtot=0;
+    float      deltax, startx;
+    float      cenf[2];
+    int                invert=0, firsttime=1;
+    char       str[256];
+
+       /* count all of the selected beziers, and
+        * set all 3 control handles to selected
+        */
+    tvtot=fullselect_ipo_keys(key->ipo);
+    
+    /* If nothing is selected, bail out 
+        */
+    if (!tvtot)
+        return;
+       
+       
+    /* Build the transvert structure 
+        */
+    tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
+    tvtot=0;
+
+    tvtot = add_trans_ipo_keys(key->ipo, tv, tvtot);
+
+    /* Do the event loop 
+        */
+    cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
+    cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2;
+    areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]);
+
+    getmouseco_areawin (mvals);
+    areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
+
+    startx=sval[0];
+    while (loop) {
+        /* Get the input
+                * If we're cancelling, reset transformations
+                * Else calc new transformation
+                * Perform the transformations 
+                */
+        while (qtest()) {
+            short val;
+            unsigned short event= extern_qread(&val);
+
+            if (val) {
+                switch (event) {
+                case LEFTMOUSE:
+                case SPACEKEY:
+                case RETKEY:
+                    loop=0;
+                    break;
+                case XKEY:
+                    break;
+                case ESCKEY:
+                case RIGHTMOUSE:
+                    cancel=1;
+                    loop=0;
+                    break;
+                default:
+                    arrows_move_cursor(event);
+                    break;
+                };
+            }
+        }
+        
+        if (cancel) {
+            for (i=0; i<tvtot; i++) {
+                tv[i].loc[0]=tv[i].oldloc[0];
+                tv[i].loc[1]=tv[i].oldloc[1];
+            }
+        } 
+               else {
+            getmouseco_areawin (mvalc);
+            areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
+                       
+            if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
+                PIL_sleep_ms(1);
+            } else {
+                for (i=0; i<tvtot; i++){
+                    tv[i].loc[0]=tv[i].oldloc[0];
+
+                    switch (mode){
+                    case 'g':
+                        deltax = cval[0]-sval[0];
+                        fac= deltax;
+                                               
+                        apply_keyb_grid(&fac, 0.0, 1.0, 0.1, 
+                                        U.flag & AUTOGRABGRID);
+
+                        tv[i].loc[0]+=fac;
+                        break;
+                    case 's':
+                        startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax
+                                                     -curarea->winrct.xmin)/2);
+                        deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax
+                                                     -curarea->winrct.xmin)/2);
+                        fac= fabs(deltax/startx);
+                                               
+                        apply_keyb_grid(&fac, 0.0, 0.2, 0.1, 
+                                        U.flag & AUTOSIZEGRID);
+               
+                        if (invert){
+                            if (i % 03 == 0){
+                                memcpy (tv[i].loc, tv[i].oldloc, 
+                                        sizeof(tv[i+2].oldloc));
+                            }
+                            if (i % 03 == 2){
+                                memcpy (tv[i].loc, tv[i].oldloc, 
+                                        sizeof(tv[i-2].oldloc));
+                            }
+                                                       
+                            fac*=-1;
+                        }
+                        startx= (G.scene->r.cfra);
+                        
+                        tv[i].loc[0]-= startx;
+                        tv[i].loc[0]*=fac;
+                        tv[i].loc[0]+= startx;
+               
+                        break;
+                    }
+                }
+            }
+                       /* Display a message showing the magnitude of
+                        * the grab/scale we are performing
+                        */
+            if (mode=='s'){
+                sprintf(str, "sizeX: %.3f", fac);
+                headerprint(str);
+            }
+            else if (mode=='g'){
+                sprintf(str, "deltaX: %.3f", fac);
+                headerprint(str);
+            }
+       
+            if (G.saction->lock){
+                               /* doubt any of this code ever gets
+                                * executed, but it might in the
+                                * future
+                                */
+                                
+                do_all_actions();
+                allqueue (REDRAWVIEW3D, 0);
+                allqueue (REDRAWACTION, 0);
+                allqueue (REDRAWIPO, 0);
+                allqueue(REDRAWNLA, 0);
+                force_draw_all();
+            }
+            else {
+                addqueue (curarea->win, REDRAWALL, 0);
+                force_draw ();
+            }
+        }
+               
+        lastcval[0]= cval[0];
+        lastcval[1]= cval[1];
+        firsttime= 0;
+    }
+       
+       /* fix up the Ipocurves and redraw stuff
+        */
+    meshkey_do_redraw(key);
+
+    MEM_freeN (tv);
+
+       /* did you understand all of that? I pretty much understand
+        * what it does, but the specifics seem a little weird and crufty.
+        */
+}
+
+
 void deselect_actionchannel_keys (bAction *act, int test)
 {
        bActionChannel  *chan;
@@ -1059,6 +1506,26 @@ void deselect_actionchannel_keys (bAction *act, int test)
        }
 }
 
+void deselect_meshchannel_keys (Key *key, int test)
+{
+       /* should deselect the rvk keys
+        */
+    int                sel=1;
+
+    /* Determine if this is selection or deselection */
+    if (test){
+        if (is_ipo_key_selected(key->ipo)){
+            sel = 0;
+        }
+    }
+    else {
+        sel=0;
+    }
+       
+    /* Set the flags */
+    set_ipo_key_selection(key->ipo, sel);
+}
+
 void deselect_actionchannels (bAction *act, int test)
 {
        bActionChannel *chan;
@@ -1125,6 +1592,12 @@ static void hilight_channel (bAction *act, bActionChannel *chan, short select)
        }
 }
 
+/* select_mode = SELECT_REPLACE
+ *             = SELECT_ADD
+ *             = SELECT_SUBTRACT
+ *             = SELECT_INVERT
+ */
+
 static int select_channel(bAction *act, bActionChannel *chan,
                           int selectmode) {
        /* Select the channel based on the selection mode
@@ -1277,6 +1750,15 @@ static void mouse_actionchannels(bAction *act, short *mval,
        allqueue (REDRAWNLA, 0);
 }
 
+static void delete_meshchannel_keys(Key *key)
+{
+       if (!okee("Erase selected keys"))
+               return;
+
+       delete_ipo_keys(key->ipo);
+
+       meshkey_do_redraw(key);
+}
 
 static void delete_actionchannel_keys(void)
 {
@@ -1369,6 +1851,13 @@ static void delete_actionchannels (void)
 
 }
 
+static void sethandles_meshchannel_keys(int code, Key *key)
+{
+    sethandles_ipo_keys(key->ipo, code);
+
+       meshkey_do_redraw(key);
+}
+
 static void sethandles_actionchannel_keys(int code)
 {
        bAction *act;
@@ -1660,7 +2149,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
        short   mval[2];
        float dx,dy;
        int     cfra;
-       
+       Key *key;
+
        if(curarea->win==0) return;
 
        saction= curarea->spacedata.first;
@@ -1674,6 +2164,8 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                
                getmouseco_areawin(mval);
 
+               key = get_action_mesh_key();
+
                switch(event) {
                case UI_BUT_EVENT:
                        do_blenderbuttons(val);
@@ -1690,92 +2182,172 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        break;
 
                case DKEY:
-                       if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
-                               duplicate_actionchannel_keys();
-                               remake_action_ipos(act);
+                       if (key) {
+                               if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH) {
+                                       duplicate_meshchannel_keys(key);
+                               }
+                       }
+                       else {
+                               if (G.qual & LR_SHIFTKEY && mval[0]>ACTWIDTH){
+                                       duplicate_actionchannel_keys();
+                                       remake_action_ipos(act);
+                               }
                        }
                        break;
+
                case DELKEY:
+
                case XKEY:
-                       if (mval[0]<ACTWIDTH)
-                               delete_actionchannels ();
-                       else
-                               delete_actionchannel_keys ();
+                       if (key) {
+                               delete_meshchannel_keys(key);
+                       }
+                       else {
+                               if (mval[0]<NAMEWIDTH)
+                                       delete_actionchannels ();
+                               else
+                                       delete_actionchannel_keys ();
+                       }
                        break;
+
                case GKEY:
-                       if (mval[0]>=ACTWIDTH)
-                               transform_actionchannel_keys ('g');
+                       if (mval[0]>=ACTWIDTH) {
+                               if (key) {
+                                       transform_meshchannel_keys('g', key);
+                               }
+                               else {
+                                       transform_actionchannel_keys ('g');
+                               }
+                       }
                        break;
+
                case SKEY:
-                       if (mval[0]>=ACTWIDTH)
-                               transform_actionchannel_keys ('s');
+                       if (mval[0]>=ACTWIDTH) {
+                               if (key) {
+                                       transform_meshchannel_keys('s', key);
+                               }
+                               else {
+                                       transform_actionchannel_keys ('s');
+                               }
+                       }
                        break;
+
                case AKEY:
-                       if (mval[0]<ACTWIDTH){
-                               deselect_actionchannels (act, 1);
-                               allqueue (REDRAWVIEW3D, 0);
-                               allqueue (REDRAWACTION, 0);
-                               allqueue(REDRAWNLA, 0);
-                               allqueue (REDRAWIPO, 0);
+                       if (key) {
+                               if (mval[0]<ACTWIDTH){
+                                       /* to do ??? */
+                               }
+                               else{
+                                       deselect_meshchannel_keys(key, 1);
+                                       allqueue (REDRAWACTION, 0);
+                                       allqueue(REDRAWNLA, 0);
+                                       allqueue (REDRAWIPO, 0);
+                               }
                        }
-                       else{
-                               deselect_actionchannel_keys (act, 1);
-                               allqueue (REDRAWACTION, 0);
-                               allqueue(REDRAWNLA, 0);
-                               allqueue (REDRAWIPO, 0);
+                       else {
+                               if (mval[0]<NAMEWIDTH){
+                                       deselect_actionchannels (act, 1);
+                                       allqueue (REDRAWVIEW3D, 0);
+                                       allqueue (REDRAWACTION, 0);
+                                       allqueue(REDRAWNLA, 0);
+                                       allqueue (REDRAWIPO, 0);
+                               }
+                               else if (mval[0]>ACTWIDTH){
+                                       deselect_actionchannel_keys (act, 1);
+                                       allqueue (REDRAWACTION, 0);
+                                       allqueue(REDRAWNLA, 0);
+                                       allqueue (REDRAWIPO, 0);
+                               }
                        }
                        break;
 
-                       /*** set the Ipo handles ***/
                case VKEY:
-                       sethandles_actionchannel_keys(HD_VECT);
+                       if (key) {
+                               sethandles_meshchannel_keys(HD_VECT, key);
+                               /* to do */
+                       }
+                       else {
+                               sethandles_actionchannel_keys(HD_VECT);
+                       }
                        break;
                case HKEY:
-                       if(G.qual & LR_SHIFTKEY) sethandles_actionchannel_keys(HD_AUTO);
-                       else sethandles_actionchannel_keys(HD_ALIGN);
+                       if (key) {
+                               if(G.qual & LR_SHIFTKEY) {
+                                       sethandles_meshchannel_keys(HD_AUTO, key);
+                               }
+                               else { 
+                                       sethandles_meshchannel_keys(HD_ALIGN, key);
+                               }
+                       }
+                       else {
+                               if(G.qual & LR_SHIFTKEY) {
+                                       sethandles_actionchannel_keys(HD_AUTO);
+                               }
+                               else { 
+                                       sethandles_actionchannel_keys(HD_ALIGN);
+                               }
+                       }
                        break;
+
                        /*** set the Ipo type  ***/
                case TKEY:
-                       set_ipotype_actionchannels();
+                       if (key) {
+                               /* to do */
+                       }
+                       else {
+                               set_ipotype_actionchannels();
+                       }
                        break;
 
                case BKEY:
-                       /* If the border select is initiated in the
-                        * part of the action window where the channel
-                        * names reside, then select the channels
-                        */
-                       if (mval[0]<ACTWIDTH){
-                               borderselect_function(mouse_actionchannels);
+                       if (key) {
+                               if (mval[0]<ACTWIDTH){
+                                       /* to do?? */
+                               }
+                               else {
+                                       borderselect_mesh(key);
+                               }
                        }
+                       else {
 
-                       /* If the border select is initiated in the
-                        * vertical scrollbar, then (de)select all keys
-                        * for the channels in the selection region
-                        */
-                       else if (IN_2D_VERT_SCROLL(mval)) {
-                               borderselect_function(select_all_keys_channels);
-                       }
+                               /* If the border select is initiated in the
+                                * part of the action window where the channel
+                                * names reside, then select the channels
+                                */
+                               if (mval[0]<NAMEWIDTH){
+                                       borderselect_function(mouse_actionchannels);
+                               }
+                               else if (mval[0]>ACTWIDTH){
+
+                                       /* If the border select is initiated in the
+                                        * vertical scrollbar, then (de)select all keys
+                                        * for the channels in the selection region
+                                        */
+                                       if (IN_2D_VERT_SCROLL(mval)) {
+                                               borderselect_function(select_all_keys_channels);
+                                       }
 
-                       /* If the border select is initiated in the
-                        * horizontal scrollbar, then (de)select all keys
-                        * for the keyframes in the selection region
-                        */
-                       else if (IN_2D_HORIZ_SCROLL(mval)) {
-                               borderselect_function(select_all_keys_frames);
-                       }
+                                       /* If the border select is initiated in the
+                                        * horizontal scrollbar, then (de)select all keys
+                                        * for the keyframes in the selection region
+                                        */
+                                       else if (IN_2D_HORIZ_SCROLL(mval)) {
+                                               borderselect_function(select_all_keys_frames);
+                                       }
 
-                       /* Other wise, select the action keys
-                        */
-                       else {
-                               borderselect_action();
+                                       /* Other wise, select the action keys
+                                        */
+                                       else {
+                                               borderselect_action();
+                                       }
+                               }
                        }
                        break;
+
                case RIGHTMOUSE:
                        /* Right clicking in the channel area selects the
                         * channel or constraint channel
                         */
-                       if (mval[0]<ACTWIDTH) {
+                       if (mval[0]<NAMEWIDTH) {
                                if(G.qual & LR_SHIFTKEY)
                                        mouse_actionchannels(act, mval, NULL, 
                                                                                 SELECT_INVERT);
@@ -1783,40 +2355,50 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        mouse_actionchannels(act, mval, NULL, 
                                                                                 SELECT_REPLACE);
                        }
+                       else if (mval[0]>ACTWIDTH) {
+
+                               /* Right clicking in the vertical scrollbar selects
+                                * all of the keys for that channel at that height
+                                */
+                               if (IN_2D_VERT_SCROLL(mval)) {
+                                       if(G.qual & LR_SHIFTKEY)
+                                               select_all_keys_channels(act, mval, NULL, 
+                                                                                                SELECT_INVERT);
+                                       else
+                                               select_all_keys_channels(act, mval, NULL, 
+                                                                                                SELECT_REPLACE);
+                               }
 
-                       /* Right clicking in the vertical scrollbar selects
-                        * all of the keys for that channel at that height
-                        */
-                       else if (IN_2D_VERT_SCROLL(mval)) {
-                               if(G.qual & LR_SHIFTKEY)
-                                       select_all_keys_channels(act, mval, NULL, 
-                                                                                        SELECT_INVERT);
-                               else
-                                       select_all_keys_channels(act, mval, NULL, 
-                                                                                        SELECT_REPLACE);
-                       }
-
-                       /* Right clicking in the horizontal scrollbar selects
-                        * all of the keys within 0.5 of the nearest integer
-                        * frame
-                        */
-                       else if (IN_2D_HORIZ_SCROLL(mval)) {
-                               if(G.qual & LR_SHIFTKEY)
-                                       select_all_keys_frames(act, mval, NULL, 
-                                                                                  SELECT_INVERT);
-                               else
-                                       select_all_keys_frames(act, mval, NULL, 
-                                                                                  SELECT_REPLACE);
-                       }
-
-                       /* Clicking in the main area of the action window
-                        * selects keys
-                        */
-                       else {
-                               if(G.qual & LR_SHIFTKEY)
-                                       mouse_action(SELECT_INVERT);
-                               else
-                                       mouse_action(SELECT_REPLACE);
+                               /* Right clicking in the horizontal scrollbar selects
+                                * all of the keys within 0.5 of the nearest integer
+                                * frame
+                                */
+                               else if (IN_2D_HORIZ_SCROLL(mval)) {
+                                       if(G.qual & LR_SHIFTKEY)
+                                               select_all_keys_frames(act, mval, NULL, 
+                                                                                          SELECT_INVERT);
+                                       else
+                                               select_all_keys_frames(act, mval, NULL, 
+                                                                                          SELECT_REPLACE);
+                               }
+                               
+                               /* Clicking in the main area of the action window
+                                * selects keys
+                                */
+                               else {
+                                       if (key) {
+                                               if(G.qual & LR_SHIFTKEY)
+                                                       mouse_mesh_action(SELECT_INVERT, key);
+                                               else
+                                                       mouse_mesh_action(SELECT_REPLACE, key);
+                                       }
+                                       else {
+                                               if(G.qual & LR_SHIFTKEY)
+                                                       mouse_action(SELECT_INVERT);
+                                               else
+                                                       mouse_action(SELECT_REPLACE);
+                                       }
+                               }
                        }
                        break;
 
@@ -1854,3 +2436,119 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
        
 }
 
+Key *get_action_mesh_key(void) {
+       /* gets the key data from the currently selected
+        * mesh/lattice. If a mesh is not selected, or does not have
+        * key data, then we return NULL (currently only
+        * returns key data for RVK type meshes). If there
+        * is an action that is pinned, return null
+        */
+    Object *ob;
+    Key    *key;
+
+    ob = OBACT;
+    if (!ob) return NULL;
+
+       if (G.saction->pin) return NULL;
+
+    if (ob->type==OB_MESH ) {
+               key = ((Mesh *)ob->data)->key;
+    }
+       else if (ob->type==OB_LATTICE ) {
+               key = ((Lattice *)ob->data)->key;
+       }
+       else return NULL;
+
+       if (key) {
+               if (key->type == KEY_RELATIVE)
+                       return key;
+       }
+
+    return NULL;
+}
+
+int get_nearest_key_num(Key *key, short *mval, float *x) {
+       /* returns the key num that cooresponds to the
+        * y value of the mouse click. Does not check
+        * if this is a valid keynum. Also gives the Ipo
+        * x coordinate.
+        */
+    int num;
+    float ybase, y;
+
+    areamouseco_to_ipoco(G.v2d, mval, x, &y);
+
+    ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
+    num = (int) ((ybase - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+    return (num + 1);
+}
+
+static void clever_keyblock_names(Key *key, short* mval){
+    int        but=0, i, keynum;
+    char       str[64];
+       float      x, min, max;
+       KeyBlock   *kb;
+       /* get the keynum cooresponding to the y value
+        * of the mouse pointer, return if this is
+        * an invalid key number (and we don't deal
+        * with the speed ipo).
+        */
+
+    keynum = get_nearest_key_num(key, mval, &x);
+    if ( (keynum < 1) || (keynum >= key->totkey) )
+        return;
+
+       kb= key->block.first;
+       for (i=0; i<keynum; ++i) kb = kb->next; 
+
+       if (kb->name[0] == '\0') {
+               sprintf(str, "Key %d", keynum);
+       }
+       else {
+               strcpy(str, kb->name);
+       }
+
+       if ( (kb->slidermin >= kb->slidermax) ) {
+               kb->slidermin = 0.0;
+               kb->slidermax = 1.0;
+       }
+
+    add_numbut(but++, TEX, "KB: ", 0, 24, str, 
+               "Does this really need a tool tip?");
+       add_numbut(but++, NUM|FLO, "Slider min:", 
+                          -10000, kb->slidermax, &kb->slidermin, 0);
+       add_numbut(but++, NUM|FLO, "Slider max:", 
+                          kb->slidermin, 10000, &kb->slidermax, 0);
+
+    if (do_clever_numbuts(str, but, REDRAW)) {
+               strcpy(kb->name, str);
+        allqueue (REDRAWACTION, 0);
+        allqueue (REDRAWIPO, 0);
+       }
+
+       
+}
+
+void stupid_damn_numbuts_action(void){
+    /* I think this function might have been
+     * deemed clever if it could have been
+     * called from the event processing
+     * routine in this file -- rather than having
+     * to go from the NKEY event from blenderqread
+     * in toets.c (which returns 0 so nobody else
+     * can use the NKEY) then into the clever_numbuts
+     * routine in toolbox.c, the finally to this
+     * function. Grumble, grumble, grumble ...
+     */
+
+    Key *key;
+    short mval[2];
+
+    if ( (key = get_action_mesh_key()) ) {
+        getmouseco_areawin (mval);
+               if (mval[0]<NAMEWIDTH) {
+                       clever_keyblock_names(key, mval);
+               }
+    }
+}
index b0cf75ff7da00072f01f621722a7dfe5c5303865..b799d9d99f0564672a8f5909bde1b8c61ecac5c4 100644 (file)
@@ -1866,7 +1866,7 @@ EditIpo *get_editipo()
 }
 
 
-static Ipo *get_ipo(ID *from, short type, int make)
+Ipo *get_ipo(ID *from, short type, int make)
 {
        Object *ob;
        Material *ma;
index 0d8b04339c1fa578bf20d9ca176829d1bc172531..3f8a3e98705880ac709f0418bc2a5dfef590aabb 100644 (file)
@@ -69,6 +69,7 @@
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
+#include "BKE_displist.h"
 
 #include "BIF_editkey.h"
 #include "BIF_editview.h"
@@ -76,6 +77,7 @@
 #include "BIF_screen.h"
 #include "BIF_space.h"
 #include "BIF_toolbox.h"
+#include "BIF_interface.h"
 
 #include "BSE_editipo.h"
 #include "BSE_trans_types.h"
 #include "blendef.h"
 #include "mydevice.h"
 #include "ipo.h"
+#include "interface.h"
 
 extern ListBase editNurb; /* in editcurve.c */
 
+/* temporary storage for slider values */
+float meshslidervals[32] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+
+static IpoCurve *get_key_icu(Key *key, int keynum) {
+       /* return the Ipocurve that has the specified
+        * keynum as ardcode -- return NULL if no such 
+        * curve exists.
+        */
+    IpoCurve *icu;
+       if (!(key->ipo)) {
+               key->ipo = get_ipo(key, ID_KE, 1);
+               return NULL;
+       }
+
+
+    for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
+        if (!icu->adrcode) continue;
+        if (icu->adrcode == keynum) return icu;
+    }
+
+    return NULL;
+}
+
+static BezTriple *get_bezt_icu_time(IpoCurve *icu, float *frame, float *val) {
+       /* this function tries to find a bezier that is within
+        * 0.25 time units from the specified frame. If there
+        * are more than one such beziers, it returns the
+        * closest one.
+        */
+       int   i;
+       float d, dmin = 0.25, newframe;
+       BezTriple *bezt = NULL;
+       
+       newframe = *frame;
+
+       for (i=0; i<icu->totvert; i++){
+               d = fabs(icu->bezt[i].vec[1][0] - *frame);
+               if (d < dmin) {
+                       dmin     = d;
+                       newframe = icu->bezt[i].vec[1][0];
+                       *val     = icu->bezt[i].vec[1][1];
+                       bezt     = icu->bezt + i;
+               }
+       }
+
+       *frame = newframe;
+       return bezt;
+}
+
+static void rvk_slider_func(void *voidkey, void *voidkeynum) {
+       /* the callback for the rvk sliders ... copies the
+        * value from the temporary array into a bezier at the
+        * right frame on the right ipo curve (creating both the
+        * ipo curve and the bezier if needed).
+        */
+       int       *keynum = (int *) voidkeynum;
+       Key       *key = (Key *) voidkey;
+       float     cfra, rvkval;
+       IpoCurve  *icu=NULL;
+       BezTriple *bezt=NULL;
+
+       cfra = frame_to_float(CFRA);
+
+       icu    = get_key_icu(key, *keynum);
+
+       if (icu) {
+               /* if the ipocurve exists, try to get a bezier
+                * for this frame
+                */
+               bezt = get_bezt_icu_time(icu, &cfra, &rvkval);
+       }
+       else {
+               /* create an IpoCurve if one doesn't already
+                * exist.
+                */
+               icu = get_ipocurve(key->from, GS(key->from->name), 
+                                                  *keynum, key->ipo);
+       }
+       
+       /* create the bezier triple if one doesn't exist,
+        * otherwise modify it's value
+        */
+       if (!bezt) {
+               insert_vert_ipo(icu, cfra, meshslidervals[*keynum]);
+       }
+       else {
+               bezt->vec[1][1] = meshslidervals[*keynum];
+       }
+
+       /* make sure the Ipo's are properly process and
+        * redraw as necessary
+        */
+       sort_time_ipocurve(icu);
+       testhandles_ipocurve(icu);
+
+       do_all_ipos();
+       do_spec_key(key);
+       /* if I'm deformed by a lattice, update my
+        * displists
+        */
+       makeDispList(OBACT);
+
+       /* if I'm a lattice, update the displists of
+        * my children
+        */
+       if (OBACT->type==OB_LATTICE ) {
+               Base *base;
+
+               base= FIRSTBASE;
+               while(base) {
+                       if (base->object->parent == OBACT) {
+                               makeDispList(base->object);
+                       }
+                       base= base->next;
+               }
+       }
+       allqueue (REDRAWVIEW3D, 0);
+       allqueue (REDRAWACTION, 0);
+       allqueue (REDRAWNLA, 0);
+       allqueue (REDRAWIPO, 0);
+
+}
+
+static float getrvkval(Key *key, int keynum) {
+       /* get the value of the rvk from the
+        * ipo curve at the current time -- return 0
+        * if no ipo curve exists
+        */
+       IpoCurve  *icu=NULL;
+       BezTriple *bezt=NULL;
+       float     rvkval = 0.0;
+       float     cfra;
+
+       cfra = frame_to_float(CFRA);
+       icu    = get_key_icu(key, keynum);
+       if (icu) {
+               bezt = get_bezt_icu_time(icu, &cfra, &rvkval);
+               if (!bezt) {
+                       rvkval = eval_icu(icu, cfra);
+               }
+       }
+
+       return rvkval;
+
+}
+
+void make_rvk_slider(uiBlock *block, Key *key, int keynum,
+                                        int x, int y, int w, int h)
+{
+       /* create a slider for the rvk */
+       uiBut         *but;
+       KeyBlock   *kb;
+       float min, max;
+       int i;
+
+       /* dang, need to pass a pointer to int to uiButSetFunc
+        * that is on the heap, not the stack ... hence this
+        * kludgy static array
+        */
+       static int keynums[] = {0,1,2,3,4,5,6,7,
+                                                       8,9,10,11,12,13,14,15,
+                                                       16,17,18,19,20,21,22,23,
+                                                       24,25,26,27,28,29,30,31};
+
+       meshslidervals[keynum] = getrvkval(key, keynum);
+
+       kb= key->block.first;
+       for (i=0; i<keynum; ++i) kb = kb->next; 
+
+       if ( (kb->slidermin >= kb->slidermax) ) {
+               kb->slidermin = 0.0;
+               kb->slidermax = 1.0;
+       }
+
+       min = (kb->slidermin < meshslidervals[keynum]) ? 
+               kb->slidermin: meshslidervals[keynum];
+
+       max = (kb->slidermax > meshslidervals[keynum]) ? 
+               kb->slidermax: meshslidervals[keynum];
+
+       but=uiDefButF(block, NUMSLI, REDRAWVIEW3D, "",
+                                 x, y , w, h,
+                                 meshslidervals+keynum, min, max, 10, 2,
+                                 "Slider to control rvk");
+       uiButSetFunc(but, rvk_slider_func, key, keynums+keynum);
+}
+
 static void default_key_ipo(Key *key)
 {
        IpoCurve *icu;
@@ -168,10 +361,20 @@ void insert_meshkey(Mesh *me)
        Key *key;
        KeyBlock *kb, *kkb;
        float curpos;
-       
+       short rel;
+
        if(me->key==0) {
                me->key= add_key( (ID *)me);
-               default_key_ipo(me->key);
+               rel = pupmenu("Relative Vertex Keys? %t|Yes Please! %x1"
+                                         "|Naw, the other kind %x2");
+               switch (rel) {
+               case 1:
+                       me->key->type = KEY_RELATIVE;
+                       break;
+               default:
+                       default_key_ipo(me->key);
+                       break;
+               }
        }
        key= me->key;
        
index eaa66bd5b220e75345ccbb29f8881c6f01d7cabb..1a7b24aff85ca864fd7b67bc5a78569fa9de7135 100644 (file)
@@ -4032,17 +4032,25 @@ void action_buttons(void)
        uiDefIconBut(block, BUT, B_ACTHOME, ICON_HOME,  xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "Zooms window to home view showing all items (HOMEKEY)");
 
        
-       /* NAME ETC */
-       ob=OBACT;
-       from = (ID*) ob;
+       if (!get_action_mesh_key()) {
+               /* NAME ETC */
+               ob=OBACT;
+               from = (ID*) ob;
 
-       xco= std_libbuttons(block, xco+1.5*XIC, B_ACTPIN, &G.saction->pin, B_ACTIONBROWSE, (ID*)G.saction->action, from, &(G.saction->actnr), B_ACTALONE, B_ACTLOCAL, B_ACTIONDELETE, 0, 0);    
+               xco= std_libbuttons(block, xco+1.5*XIC, B_ACTPIN, &G.saction->pin, 
+                                                       B_ACTIONBROWSE, (ID*)G.saction->action, 
+                                                       from, &(G.saction->actnr), B_ACTALONE, 
+                                                       B_ACTLOCAL, B_ACTIONDELETE, 0, 0);      
 
 #ifdef __NLA_BAKE
-       /* Draw action baker */
-       uiDefBut(block, BUT, B_ACTBAKE, "Bake", xco+=XIC, 0, 64, YIC, 0, 0, 0, 0, 0, "Generates an Action with the constraint effects converted into ipo keys");
-       xco+=64;
+               /* Draw action baker */
+               uiDefBut(block, BUT, B_ACTBAKE, "Bake", 
+                                xco+=XIC, 0, 64, YIC, 0, 0, 0, 0, 0, 
+                                "Generate an action with the constraint "
+                                "effects converted into ipo keys");
+               xco+=64;
 #endif
+       }
        uiClearButLock();
 
        /* draw LOCK */
index 364193c52e18b6f981e8c7d5d4e340e475f27f61..4c879b5a94e2556cd94bf8b2dbeab11803ff78f7 100644 (file)
@@ -1452,9 +1452,9 @@ void clever_numbuts(void)
        else if(curarea->spacetype==SPACE_OOPS) {
                clever_numbuts_oops();
        }
-//     else if(curarea->spacetype==SPACE_ACTION){
-//             stupid_damn_numbuts_action();
-//     }
+       else if(curarea->spacetype==SPACE_ACTION){
+               stupid_damn_numbuts_action();
+       }
        else if(curarea->spacetype==SPACE_FILE) {
                clever_numbuts_filesel();
        }