== Action Editor - Individual IPO-Curves Now Shown ==
authorJoshua Leung <aligorith@gmail.com>
Fri, 13 Apr 2007 11:15:08 +0000 (11:15 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 13 Apr 2007 11:15:08 +0000 (11:15 +0000)
Continuing on from my previous 'Expandable/Collapsable Action Channel' commit, this commit introduces the ability to show/hide the keyframes in each ipo-curve represented by an Action Channel.

When you expand an Action-Channel by clicking on the triangle beside its name, you will now be presented with options to show/hide the ipo-curves represented by
the Action-Channel, and/or the Constraint Channels belonging to that Action-Channel. Actual ipo-curves will not be drawn in the Action-Editor, but the keyframes
will be shown.

Screenshot:
* http://wiki.blender.org/index.php/Image:244_ActionEditor_SubTracks_01.png

Possibly Coming Soon/Further Work:
* 'Protection' options for ipo-curves (currently disabled in code, as all IPO-related
 tools will need to be made aware of this)
* Sliders for IPO-Curve Channels of the active Action-Channel

source/blender/include/BIF_editaction.h
source/blender/include/BSE_editipo.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_ipo_types.h
source/blender/src/drawaction.c
source/blender/src/editaction.c
source/blender/src/editipo_lib.c
source/blender/src/editipo_mods.c

index 974ffc412d4b389b0f80281c374df6b552d5b940..2d92b120b9abe58b219bf750b76f50cee2698c46 100644 (file)
 
 #define        CHANNELHEIGHT   16
 #define        CHANNELSKIP             2
 
 #define        CHANNELHEIGHT   16
 #define        CHANNELSKIP             2
-#define NAMEWIDTH      144
+#define NAMEWIDTH      164
 #define SLIDERWIDTH    125
 #define ACTWIDTH               (G.saction->actwidth)
 
 /* Some types for easier type-testing */
 #define SLIDERWIDTH    125
 #define ACTWIDTH               (G.saction->actwidth)
 
 /* Some types for easier type-testing */
-#define ACTTYPE_NONE   0
-#define ACTTYPE_ACHAN  1
-#define ACTTYPE_CONCHAN        2
+#define ACTTYPE_NONE           0
+#define ACTTYPE_ACHAN          1
+#define ACTTYPE_CONCHAN                2
+#define ACTTYPE_ICU                    3
+#define ACTTYPE_FILLIPO                4
+#define ACTTYPE_FILLCON                5
 
 /* Macros for easier/more consistant state testing */
 #define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0)
 #define EDITABLE_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && ((achan->flag & ACHAN_PROTECTED)==0))
 #define EXPANDED_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && (achan->flag & ACHAN_EXPANDED))
 #define SEL_ACHAN(achan) ((achan->flag & ACHAN_SELECTED) || (achan->flag & ACHAN_HILIGHTED))
 
 /* Macros for easier/more consistant state testing */
 #define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0)
 #define EDITABLE_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && ((achan->flag & ACHAN_PROTECTED)==0))
 #define EXPANDED_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && (achan->flag & ACHAN_EXPANDED))
 #define SEL_ACHAN(achan) ((achan->flag & ACHAN_SELECTED) || (achan->flag & ACHAN_HILIGHTED))
+#define FILTER_IPO_ACHAN(achan) ((achan->flag & ACHAN_SHOWIPO))
+#define FILTER_CON_ACHAN(achan) ((achan->flag & ACHAN_SHOWCONS))
 
 #define EDITABLE_CONCHAN(conchan) ((conchan->flag & CONSTRAINT_CHANNEL_PROTECTED)==0)
 #define SEL_CONCHAN(conchan) (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
 
 
 #define EDITABLE_CONCHAN(conchan) ((conchan->flag & CONSTRAINT_CHANNEL_PROTECTED)==0)
 #define SEL_CONCHAN(conchan) (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
 
-#define CHANNEL_FILTER_LOC             0x00000001      /* Show location keys */
-#define CHANNEL_FILTER_ROT             0x00000002      /* Show rotation keys */
-#define CHANNEL_FILTER_SIZE            0x00000004      /* Show size keys */
-#define CHANNEL_FILTER_CON             0x00000008      /* Show constraint keys */
-#define CHANNEL_FILTER_RGB             0x00000010      /* Show object color keys */
-
-#define CHANNEL_FILTER_CU              0x00010000      /* Show curve keys */
-#define CHANNEL_FILTER_ME              0x00020000      /* Show mesh keys */
-#define CHANNEL_FILTER_LA              0x00040000      /* Show lamp keys */
-
+#define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
+#define SEL_ICU(icu) (icu->flag & IPO_SELECT)
 
 struct bAction;
 struct bActionChannel;
 
 struct bAction;
 struct bActionChannel;
index 0de71298978be81c0c6326f95a61e60a1a0c9282..6ec0420a95f8ff7a982c6a7386c91093ced73ad7 100644 (file)
@@ -60,6 +60,9 @@ char *getname_cam_ei(int nr);
 char *getname_snd_ei(int nr);
 char *getname_fluidsim_ei(int nr);
 
 char *getname_snd_ei(int nr);
 char *getname_fluidsim_ei(int nr);
 
+char *getname_ipocurve(struct IpoCurve *icu);
+int geticon_ipo_blocktype(short blocktype);
+
 struct EditIpo *get_active_editipo(void);
 
 void boundbox_ipocurve(struct IpoCurve *icu);
 struct EditIpo *get_active_editipo(void);
 
 void boundbox_ipocurve(struct IpoCurve *icu);
index 2f1b9ed85f00a46839dab94901daf1ced461ddc3..259167b6e6ee48e0edc1a759c96e55b40faf715e 100644 (file)
@@ -95,10 +95,10 @@ typedef struct bActionChannel {
        struct bActionChannel   *next, *prev;
        struct Ipo                              *ipo;
        ListBase                                constraintChannels;
        struct bActionChannel   *next, *prev;
        struct Ipo                              *ipo;
        ListBase                                constraintChannels;
+       
        int             flag;
        char    name[32];               /* Channel name */
        int             reserved1;
        int             flag;
        char    name[32];               /* Channel name */
        int             reserved1;
-
 } bActionChannel;
 
 typedef struct bAction {
 } bActionChannel;
 
 typedef struct bAction {
@@ -127,6 +127,8 @@ typedef struct SpaceAction {
 #define ACHAN_HIDDEN   0x00000004
 #define ACHAN_PROTECTED 0x00000008
 #define ACHAN_EXPANDED         0x00000010
 #define ACHAN_HIDDEN   0x00000004
 #define ACHAN_PROTECTED 0x00000008
 #define ACHAN_EXPANDED         0x00000010
+#define ACHAN_SHOWIPO  0x00000020
+#define ACHAN_SHOWCONS         0x00000040
 #define ACHAN_MOVED     0x80000000
 
 /* SpaceAction flag */
 #define ACHAN_MOVED     0x80000000
 
 /* SpaceAction flag */
index 434d4f4926f681a4d97bff0eb5c71939225170e1..441a3fc43fc6ec21f232e10c43957aa32cffbf54 100644 (file)
@@ -390,6 +390,7 @@ typedef short IPO_Channel;
 #define IPO_LOCK               8
 #define IPO_AUTO_HORIZ 16
 #define IPO_ACTIVE             32
 #define IPO_LOCK               8
 #define IPO_AUTO_HORIZ 16
 #define IPO_ACTIVE             32
+#define IPO_PROTECT            64
 
 #endif
 
 
 #endif
 
index 42060fddff408d495fd0d3cfe3c1e7e9bbe940ca..44117c1ba3d1c3ee95b6bbaa93b0caef331d1422 100644 (file)
@@ -82,6 +82,7 @@
 
 #include "BSE_drawnla.h"
 #include "BSE_drawipo.h"
 
 #include "BSE_drawnla.h"
 #include "BSE_drawipo.h"
+#include "BSE_editipo.h"
 #include "BSE_time.h"
 #include "BSE_view.h"
 
 #include "BSE_time.h"
 #include "BSE_view.h"
 
@@ -136,7 +137,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
                                          XIC,YIC-2,
                                          &(G.saction->flag), 0, 0, 0, 0, 
                                          "Show action window sliders");
                                          XIC,YIC-2,
                                          &(G.saction->flag), 0, 0, 0, 0, 
                                          "Show action window sliders");
-               // no hilite, the winmatrix is not correct later on...
+               /* no hilite, the winmatrix is not correct later on... */
                uiButSetFlag(but, UI_NO_HILITE);
 
        }
                uiButSetFlag(but, UI_NO_HILITE);
 
        }
@@ -147,7 +148,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
                                          XIC,YIC-2,
                                          &(G.saction->flag), 0, 0, 0, 0, 
                                          "Hide action window sliders");
                                          XIC,YIC-2,
                                          &(G.saction->flag), 0, 0, 0, 0, 
                                          "Hide action window sliders");
-               // no hilite, the winmatrix is not correct later on...
+               /* no hilite, the winmatrix is not correct later on... */
                uiButSetFlag(but, UI_NO_HILITE);
                                          
                ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
                uiButSetFlag(but, UI_NO_HILITE);
                                          
                ACTWIDTH = NAMEWIDTH + SLIDERWIDTH;
@@ -205,12 +206,12 @@ void draw_cfra_action(void)
        glLineWidth(1.0);
 }
 
        glLineWidth(1.0);
 }
 
-
 /* left hand */
 /* left hand */
-static void draw_action_channel_names(bAction  *act) 
+static void draw_action_channel_names(bAction *act) 
 {
     bActionChannel *achan;
     bConstraintChannel *conchan;
 {
     bActionChannel *achan;
     bConstraintChannel *conchan;
+       IpoCurve *icu;
     float      x, y;
 
     x = 0.0;
     float      x, y;
 
     x = 0.0;
@@ -226,12 +227,10 @@ static void draw_action_channel_names(bAction     *act)
                        glRectf(x,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
                        
                        /* draw expand/collapse triangle for action-channel */
                        glRectf(x,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
                        
                        /* draw expand/collapse triangle for action-channel */
-                       if (achan->constraintChannels.first) { /* until we get ipo-channels */
-                               if (EXPANDED_ACHAN(achan))
-                                       BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
-                               else
-                                       BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
-                       }
+                       if (EXPANDED_ACHAN(achan))
+                               BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
+                       else
+                               BIF_icon_draw(x+1, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
                        
                        /* draw name of action channel */
                        if (SEL_ACHAN(achan))
                        
                        /* draw name of action channel */
                        if (SEL_ACHAN(achan))
@@ -249,26 +248,106 @@ static void draw_action_channel_names(bAction    *act)
                        y-=CHANNELHEIGHT+CHANNELSKIP;
                        
                        if (EXPANDED_ACHAN(achan)) {
                        y-=CHANNELHEIGHT+CHANNELSKIP;
                        
                        if (EXPANDED_ACHAN(achan)) {
-                               /* Draw constraint channels */
-                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                       /* draw backing strip behind constraint channel*/
+                               /* Draw IPO-curves show/hide widget */
+                               if (achan->ipo) {                                       
+                                       /* draw backing strip behind */
                                        BIF_ThemeColorShade(TH_HEADER, -20);
                                        glRectf(x+7,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
                                        
                                        BIF_ThemeColorShade(TH_HEADER, -20);
                                        glRectf(x+7,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
                                        
-                                       /* draw name of constraint channel */
-                                       if (SEL_CONCHAN(conchan))
+                                       /* draw expand/collapse triangle for showing sub-channels  */
+                                       if (FILTER_IPO_ACHAN(achan))
+                                               BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
+                                       else
+                                               BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
+                                       
+                                       /* draw icon showing type of ipo-block */
+                                       BIF_icon_draw(x+24, y-CHANNELHEIGHT/2, geticon_ipo_blocktype(achan->ipo->blocktype));
+                                       
+                                       /* draw name of ipo-block */
+                                       if (SEL_ACHAN(achan))
                                                BIF_ThemeColor(TH_TEXT_HI);
                                        else
                                                BIF_ThemeColor(TH_TEXT);
                                                BIF_ThemeColor(TH_TEXT_HI);
                                        else
                                                BIF_ThemeColor(TH_TEXT);
-                                       glRasterPos2f(x+18,  y-4);
-                                       BMF_DrawString(G.font, conchan->name);
+                                       glRasterPos2f(x+40,  y-4);
+                                       BMF_DrawString(G.font, "IPO Curves"); // TODO: make proper naming scheme
+                               
+                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                               
+                                       /* Draw IPO-curve-channels? */
+                                       if (FILTER_IPO_ACHAN(achan)) {
+                                               for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+                                                       /* draw backing strip behind ipo-curve channel*/
+                                                       BIF_ThemeColorShade(TH_HEADER, -40);
+                                                       glRectf(x+14,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
+                                                       
+                                                       /* draw name of ipo-curve channel */
+                                                       if (SEL_ICU(icu))
+                                                               BIF_ThemeColor(TH_TEXT_HI);
+                                                       else
+                                                               BIF_ThemeColor(TH_TEXT);
+                                                       glRasterPos2f(x+24,  y-4);
+                                                       BMF_DrawString(G.font, getname_ipocurve(icu));
+                                                       
+#if 0 /* tempolarily disabled until all ipo-code can support this option */
+                                                       /* draw 'lock' to indicate if ipo-curve channel is protected */
+                                                       if (EDITABLE_ICU(icu)==0) 
+                                                               BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
+                                                       else 
+                                                               BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);  
+#endif
+                                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                               }
+                                       }
+                               }
+
+                               /* Draw constraints show/hide widget */
+                               if (achan->constraintChannels.first) {
+                                       /* draw backing strip behind */
+                                       BIF_ThemeColorShade(TH_HEADER, -20);
+                                       glRectf(x+7,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
                                        
                                        
-                                       /* draw 'lock' to indicate if constraint channel is protected */
-                                       if (EDITABLE_CONCHAN(conchan)==0) 
-                                               BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
-                                       else 
-                                               BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);  
+                                       /* draw expand/collapse triangle for showing sub-channels  */
+                                       if (FILTER_CON_ACHAN(achan))
+                                               BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_DOWN);
+                                       else
+                                               BIF_icon_draw(x+8, y-CHANNELHEIGHT/2, ICON_TRIA_RIGHT);
+                                       
+                                       /* draw constraint icon */
+                                       BIF_icon_draw(x+24, y-CHANNELHEIGHT/2, ICON_CONSTRAINT);
+                                       
+                                       /* draw name of widget */
+                                       if (SEL_ACHAN(achan))
+                                               BIF_ThemeColor(TH_TEXT_HI);
+                                       else
+                                               BIF_ThemeColor(TH_TEXT);
+                                       glRasterPos2f(x+40,  y-4);
+                                       BMF_DrawString(G.font, "Constraints");
+                               
                                        y-=CHANNELHEIGHT+CHANNELSKIP;
                                        y-=CHANNELHEIGHT+CHANNELSKIP;
+                               
+                                       /* Draw constraint channels?  */
+                                       if (FILTER_CON_ACHAN(achan)) {
+                                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                                       /* draw backing strip behind constraint channel*/
+                                                       BIF_ThemeColorShade(TH_HEADER, -40);
+                                                       glRectf(x+14,  y-CHANNELHEIGHT/2,  (float)NAMEWIDTH,  y+CHANNELHEIGHT/2);
+                                                       
+                                                       /* draw name of constraint channel */
+                                                       if (SEL_CONCHAN(conchan))
+                                                               BIF_ThemeColor(TH_TEXT_HI);
+                                                       else
+                                                               BIF_ThemeColor(TH_TEXT);
+                                                       glRasterPos2f(x+25,  y-4);
+                                                       BMF_DrawString(G.font, conchan->name);
+                                                       
+                                                       /* draw 'lock' to indicate if constraint channel is protected */
+                                                       if (EDITABLE_CONCHAN(conchan)==0) 
+                                                               BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_LOCKED);
+                                                       else 
+                                                               BIF_icon_draw(NAMEWIDTH-16, y-CHANNELHEIGHT/2, ICON_UNLOCKED);  
+                                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                               }
+                                       }
                                }
                        }
                        
                                }
                        }
                        
@@ -369,17 +448,27 @@ static void draw_channel_names(void)
 int count_action_levels(bAction *act)
 {
        bActionChannel *achan;
 int count_action_levels(bAction *act)
 {
        bActionChannel *achan;
-       int y= 0;
+       int y=0;
 
 
-       if (!act)
+       if (!act) 
                return 0;
 
        for (achan=act->chanbase.first; achan; achan=achan->next) {
                if(VISIBLE_ACHAN(achan)) {
                return 0;
 
        for (achan=act->chanbase.first; achan; achan=achan->next) {
                if(VISIBLE_ACHAN(achan)) {
-                       y+= 1;
+                       y++;
                        
                        
-                       if (EXPANDED_ACHAN(achan))
-                               y+= BLI_countlist(&achan->constraintChannels);
+                       if (EXPANDED_ACHAN(achan)) {
+                               if (achan->constraintChannels.first) {
+                                       y++;
+                                       if (FILTER_CON_ACHAN(achan))
+                                               y += BLI_countlist(&achan->constraintChannels);
+                               }
+                               else if (achan->ipo) {
+                                       y++;
+                                       if (FILTER_IPO_ACHAN(achan))
+                                               y += BLI_countlist(&achan->ipo->curve);
+                               }
+                       }
                }
        }
 
                }
        }
 
@@ -417,6 +506,7 @@ static void draw_channel_strips(SpaceAction *saction)
        bAction *act;
        bActionChannel *achan;
        bConstraintChannel *conchan;
        bAction *act;
        bActionChannel *achan;
        bConstraintChannel *conchan;
+       IpoCurve *icu;
        float y, sta, end;
        int act_start, act_end, dummy;
        char col1[3], col2[3];
        float y, sta, end;
        int act_start, act_end, dummy;
        char col1[3], col2[3];
@@ -466,20 +556,48 @@ static void draw_channel_strips(SpaceAction *saction)
                        /*      Increment the step */
                        y-=CHANNELHEIGHT+CHANNELSKIP;
                        
                        /*      Increment the step */
                        y-=CHANNELHEIGHT+CHANNELSKIP;
                        
-                       /* Draw constraint channels */
+                       /* Draw sub channels */
                        if (EXPANDED_ACHAN(achan)) {
                        if (EXPANDED_ACHAN(achan)) {
-                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                       gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
-                                       
-                                       if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
-                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
-                                       glRectf(frame1_x,  channel_y-CHANNELHEIGHT/2+4,  G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2-4);
-                                       
-                                       if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
-                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
-                                       glRectf(act_start,  channel_y-CHANNELHEIGHT/2+4,  act_end,  channel_y+CHANNELHEIGHT/2-4);
+                               /* Draw ipo channels */
+                               if (achan->ipo) {
+                                       y-=CHANNELHEIGHT+CHANNELSKIP;
                                        
                                        
+                                       if (FILTER_IPO_ACHAN(achan)) {
+                                               for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+                                                       gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+                                                       
+                                                       if (SEL_ICU(icu)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+                                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+                                                       glRectf(frame1_x,  channel_y-CHANNELHEIGHT/2+4,  G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2-4);
+                                                       
+                                                       if (SEL_ICU(icu)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+                                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+                                                       glRectf(act_start,  channel_y-CHANNELHEIGHT/2+4,  act_end,  channel_y+CHANNELHEIGHT/2-4);
+                                                       
+                                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                               }
+                                       }
+                               }
+                               
+                               /* Draw constraint channels */
+                               if (achan->constraintChannels.first) {
                                        y-=CHANNELHEIGHT+CHANNELSKIP;
                                        y-=CHANNELHEIGHT+CHANNELSKIP;
+                                       
+                                       if (FILTER_CON_ACHAN(achan)) {
+                                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                                       gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y);
+                                                       
+                                                       if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+                                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+                                                       glRectf(frame1_x,  channel_y-CHANNELHEIGHT/2+4,  G.v2d->hor.xmax,  channel_y+CHANNELHEIGHT/2-4);
+                                                       
+                                                       if (SEL_CONCHAN(conchan)) glColor4ub(col1[0], col1[1], col1[2], 0x22);
+                                                       else glColor4ub(col2[0], col2[1], col2[2], 0x22);
+                                                       glRectf(act_start,  channel_y-CHANNELHEIGHT/2+4,  act_end,  channel_y+CHANNELHEIGHT/2-4);
+                                                       
+                                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                               }
+                                       }
                                }
                        }
                }
                                }
                        }
                }
@@ -497,11 +615,30 @@ static void draw_channel_strips(SpaceAction *saction)
                        draw_ipo_channel(di, achan->ipo, y);
                        y-=CHANNELHEIGHT+CHANNELSKIP;
 
                        draw_ipo_channel(di, achan->ipo, y);
                        y-=CHANNELHEIGHT+CHANNELSKIP;
 
-                       /* Draw constraint channels */
+                       /* Draw sub channels */
                        if (EXPANDED_ACHAN(achan)) {
                        if (EXPANDED_ACHAN(achan)) {
-                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                       draw_ipo_channel(di, conchan->ipo, y);
+                               /* Draw ipo curves */
+                               if (achan->ipo) {
                                        y-=CHANNELHEIGHT+CHANNELSKIP;
                                        y-=CHANNELHEIGHT+CHANNELSKIP;
+                                       
+                                       if (FILTER_IPO_ACHAN(achan)) {
+                                               for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+                                                       draw_icu_channel(di, icu, y);
+                                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                               }
+                                       }
+                               }
+                               
+                               /* Draw constraint channels */
+                               if (achan->constraintChannels.first) {
+                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                       
+                                       if (FILTER_CON_ACHAN(achan)) {
+                                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                                       draw_ipo_channel(di, conchan->ipo, y);
+                                                       y-=CHANNELHEIGHT+CHANNELSKIP;
+                                               }
+                                       }
                                }
                        }
                }
                                }
                        }
                }
@@ -639,6 +776,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
        uiFreeBlocksWin(&sa->uiblocks, sa->win);
 
        if (!G.saction->pin) {
        uiFreeBlocksWin(&sa->uiblocks, sa->win);
 
        if (!G.saction->pin) {
+               /* allow more than one active action sometime? */
                if (OBACT)
                        G.saction->action = OBACT->action;
                else
                if (OBACT)
                        G.saction->action = OBACT->action;
                else
index a46d74bf8f35177c83ece1ba4df9ea636418c7cd..e88a234cc46b9ea04f27cd997d4df025b5ee7e08 100644 (file)
@@ -96,7 +96,7 @@
 #include "nla.h"
 
 /* Local Function prototypes, are forward needed */
 #include "nla.h"
 
 /* Local Function prototypes, are forward needed */
-static void hilight_channel (bAction *act, bActionChannel *chan, short hilight);
+static void hilight_channel (bAction *act, bActionChannel *achan, short select);
 
 /* messy call... */
 static void select_poseelement_by_name (char *name, int select)
 
 /* messy call... */
 static void select_poseelement_by_name (char *name, int select)
@@ -206,7 +206,7 @@ static void meshkey_do_redraw(Key *key)
 void duplicate_meshchannel_keys(Key *key)
 {
        duplicate_ipo_keys(key->ipo);
 void duplicate_meshchannel_keys(Key *key)
 {
        duplicate_ipo_keys(key->ipo);
-       transform_meshchannel_keys ('g', key);
+       transform_meshchannel_keys('g', key);
 }
 
 void duplicate_actionchannel_keys(void)
 }
 
 void duplicate_actionchannel_keys(void)
@@ -220,11 +220,11 @@ void duplicate_actionchannel_keys(void)
                return;
 
        /* Find selected items */
                return;
 
        /* Find selected items */
-       for (achan = act->chanbase.first; achan; achan= achan->next){
+       for (achan = act->chanbase.first; achan; achan= achan->next) {
                if(EDITABLE_ACHAN(achan)) {
                        duplicate_ipo_keys(achan->ipo);
                        
                if(EDITABLE_ACHAN(achan)) {
                        duplicate_ipo_keys(achan->ipo);
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                duplicate_ipo_keys(conchan->ipo);
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                duplicate_ipo_keys(conchan->ipo);
@@ -236,35 +236,103 @@ void duplicate_actionchannel_keys(void)
        transform_actionchannel_keys ('g', 0);
 }
 
        transform_actionchannel_keys ('g', 0);
 }
 
-static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, bConstraintChannel **rchan)
+/* helper for get_nearest_[action,mesh]channel_key */
+static IpoCurve *get_nearest_icu_key (IpoCurve *curve, float *selx, short *sel, float xrange[])
 {
 {
-       bAction *act;
+       /* try to find first beztriple in bounds that is selected */
+       IpoCurve *icu, *firsticu=NULL;
+    int             foundsel=0;
+    float    firstvert=-1, foundx=-1;
+       int      i;
+       
+       if (curve == NULL)
+               return NULL;
+       
+    /* lets loop through the IpoCurves trying to find the closest bezier */
+       for (icu= curve; icu ; icu= icu->next) {
+               /* 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] > xrange[0] && 
+                               icu->bezt[i].vec[1][0] <= xrange[1] ) {
+
+                               /* if no other curves have been picked ... */
+                               if (firsticu==NULL) {
+                                       /* 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 */
+                                       *sel = 0;
+                                       *selx= icu->bezt[i].vec[1][0];
+                                       return icu;
+                               }
+                       }
+               }
+       }
+       
+    /* return what we've found */
+    *selx=firstvert;
+    return firsticu;
+}
+
+static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_type, bActionChannel **par)
+{
+       bAction *act= G.saction->action;
        bActionChannel *achan;
        bActionChannel *achan;
+       bConstraintChannel *conchan;
        IpoCurve *icu;
        IpoCurve *icu;
-       bActionChannel *firstchan=NULL;
-       bConstraintChannel *conchan, *firstconchan=NULL;
-       rctf    rectf;
-       float firstvert=-1, foundx=-1;
-       float ymin, ymax, xmin, xmax;
-       int i;
-       int     foundsel=0;
+       rctf rectf;
+       float xmin, xmax, x, y;
+       int clickmin, clickmax;
+       int     wsize;
        short mval[2];
        short mval[2];
-       
-       *index=0;
+               
+       getmouseco_areawin (mval);
 
 
-       *rchan=NULL;
-       act= G.saction->action; /* We presume that we are only called during a valid action */
+       /* action-channel */
+       *par= NULL;
        
        
-       getmouseco_areawin (mval);
+       if (act == NULL) {
+               *ret_type= ACTTYPE_NONE;
+               return NULL;
+       }
+       
+       /* wsize is the greatest possible height (in pixels) that would be
+        * needed to draw all of the action channels, ipo-curve channels and constraint
+        * channels.
+        */
+       wsize =  count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP);
+       wsize += CHANNELHEIGHT/2;
 
 
+    areamouseco_to_ipoco(G.v2d, mval, &x, &y);
+    clickmin = (int) ((wsize - y) / (CHANNELHEIGHT+CHANNELSKIP));
+       clickmax = clickmin;
+       
        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);
 
        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);
 
-       ymax = count_action_levels(act) * (CHANNELHEIGHT + CHANNELSKIP);
-       ymax += CHANNELHEIGHT/2;
-       
        /* if action is mapped in NLA, it returns a correction */
        if (G.saction->pin==0 && OBACT) {
                xmin= get_action_frame(OBACT, rectf.xmin);
        /* if action is mapped in NLA, it returns a correction */
        if (G.saction->pin==0 && OBACT) {
                xmin= get_action_frame(OBACT, rectf.xmin);
@@ -275,80 +343,99 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel,
                xmax= rectf.xmax;
        }
        
                xmax= rectf.xmax;
        }
        
-       *sel=0;
-
-       for (achan=act->chanbase.first; achan; achan= achan->next) {
-               if (VISIBLE_ACHAN(achan)) {
-                       /* Check action channel */
-                       ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
-                       if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)) && achan->ipo) {
-                               for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
-                                       for (i=0; i<icu->totvert; i++) {
-                                               if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] <= xmax ) {
-                                                       if (!firstchan) {
-                                                               firstchan=achan;
-                                                               firstvert=icu->bezt[i].vec[1][0];
-                                                               *sel = icu->bezt[i].f2 & 1;     
-                                                       }
-                                                       
-                                                       if (icu->bezt[i].f2 & 1) { 
-                                                               if (!foundsel) {
-                                                                       foundsel=1;
-                                                                       foundx = icu->bezt[i].vec[1][0];
-                                                               }
-                                                       }
-                                                       else if (foundsel && icu->bezt[i].vec[1][0] != foundx) {
-                                                               *index=icu->bezt[i].vec[1][0];
-                                                               *sel = 0;
-                                                               return achan;
-                                                       }
-                                               }
+       if (clickmax < 0) {
+               *ret_type= ACTTYPE_NONE;
+               return NULL;
+       }
+       
+       /* try in action channels */
+       for (achan = act->chanbase.first; achan; achan=achan->next) {
+               if(VISIBLE_ACHAN(achan)) {
+                       if (clickmax < 0) 
+                               break;
+                       if (clickmin <= 0) {
+                               /* found level - action channel */
+                               icu= get_nearest_icu_key(achan->ipo->curve.first, selx, sel, &xmin);
+                               
+                               *ret_type= ACTTYPE_ACHAN;
+                               return achan;
+                       }
+                       --clickmin;
+                       --clickmax;
+               }
+               else
+                       continue;
+               
+               if (EXPANDED_ACHAN(achan) == 0)
+                       continue;
+               
+               /* try in ipo curves */
+               if (achan->ipo) {
+                       /* check header first */
+                       if (clickmax < 0) 
+                               break;
+                       if (clickmin <= 0) {
+                               /* found level - ipo-curves show/hide */
+                               *ret_type= ACTTYPE_NONE;
+                               return NULL; 
+                       }
+                       --clickmin;
+                       --clickmax;
+                       
+                       /* now the ipo-curve channels if they are exposed  */
+                       if (FILTER_IPO_ACHAN(achan)) {
+                               for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
+                                       if (clickmax < 0) 
+                                               break;
+                                       if (clickmin <= 0) {
+                                               /* found level - ipo-curve channel */
+                                               icu= get_nearest_icu_key (icu, selx, sel, &xmin);
+                               
+                                               *ret_type= ACTTYPE_ICU;
+                                               *par= achan;
+                                               return icu; 
                                        }
                                        }
+                                       --clickmin;
+                                       --clickmax;
                                }
                        }
                                }
                        }
-                       ymax=ymin;
+               }
+               
+               /* try in constaint channels */
+               if (achan->constraintChannels.first) {
+                       /* check header first */
+                       if (clickmax < 0) 
+                               break;
+                       if (clickmin <= 0) {
+                               /* found match - constraints show/hide */
+                               *ret_type= ACTTYPE_NONE;
+                               return NULL;
+                       }
+                       --clickmin;
+                       --clickmax;
                        
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
-                               continue;
-                               
-                       /* Check constraint channels */
-                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                               ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
-                               if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)) && conchan->ipo) {
-                                       for (icu=conchan->ipo->curve.first; icu; icu=icu->next){
-                                               for (i=0; i<icu->totvert; i++) {
-                                                       if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] <= xmax ) {
-                                                               if (!firstchan) {
-                                                                       firstchan= achan;
-                                                                       firstconchan= conchan;
-                                                                       firstvert= icu->bezt[i].vec[1][0];
-                                                                       *sel = icu->bezt[i].f2 & 1;     
-                                                               }
-                                                               
-                                                               if (icu->bezt[i].f2 & 1) { 
-                                                                       if (!foundsel) {
-                                                                               foundsel=1;
-                                                                               foundx = icu->bezt[i].vec[1][0];
-                                                                       }
-                                                               }
-                                                               else if (foundsel && icu->bezt[i].vec[1][0] != foundx) {
-                                                                       *index=icu->bezt[i].vec[1][0];
-                                                                       *sel = 0;
-                                                                       *rchan = conchan;
-                                                                       return achan;
-                                                               }
-                                                       }
-                                               }
+                       /* now the constraint channels if they are exposed  */
+                       if (FILTER_CON_ACHAN(achan)) {
+                               for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                       if (clickmax < 0) 
+                                               break;
+                                       if (clickmin <= 0) {
+                                               /* found match - constraint channel */
+                                               icu= get_nearest_icu_key(conchan->ipo->curve.first, selx, sel, &xmin);
+                                               
+                                               *ret_type= ACTTYPE_CONCHAN;
+                                               *par= achan;
+                                               return conchan;
                                        }
                                        }
+                                       --clickmin;
+                                       --clickmax;
                                }
                                }
-                               ymax=ymin;
                        }
                }
                        }
                }
-       }       
+       }
        
        
-       *rchan = firstconchan;
-       *index=firstvert;
-       return firstchan;
+       *ret_type= ACTTYPE_NONE;
+       return NULL;
 }
 
 static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
 }
 
 static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
@@ -383,13 +470,10 @@ static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
        ybase += CHANNELHEIGHT/2;
     *sel=0;
 
        ybase += CHANNELHEIGHT/2;
     *sel=0;
 
-    /* lets loop through the IpoCurves trying to find the closest
-     * bezier
-     */
+    /* lets loop through the IpoCurves trying to find the closest bezier */
        if (!key->ipo) return NULL;
     for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
        if (!key->ipo) return NULL;
     for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
-        /* lets not deal with the "speed" Ipo
-         */
+        /* lets not deal with the "speed" Ipo */
         if (!icu->adrcode) continue;
 
         ymax = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
         if (!icu->adrcode) continue;
 
         ymax = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
@@ -400,12 +484,10 @@ static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
          */
         if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
                        
          */
         if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
                        
-            /* loop through the beziers in the curve
-             */
+            /* loop through the beziers in the curve */
             for (i=0; i<icu->totvert; i++) {
 
             for (i=0; i<icu->totvert; i++) {
 
-                /* Is this bezier in the right area?
-                 */
+                /* 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 (icu->bezt[i].vec[1][0] > rectf.xmin && 
                     icu->bezt[i].vec[1][0] <= rectf.xmax ) {
 
@@ -421,22 +503,19 @@ static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
 
                     /* if the bezier is selected ... */
                     if (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 we haven't found a selected one yet ... */
                         if (!foundsel){
                         if (!foundsel){
-                            /* record the found x value
-                             */
+                            /* record the found x value */
                             foundsel=1;
                             foundx = icu->bezt[i].vec[1][0];
                         }
                     }
 
                             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 ...
-                     */
+                                       /* 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){
                     else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
-                        /* lets return this found curve/bezier
-                         */
+                        /* lets return this found curve/bezier */
                         *index=icu->bezt[i].vec[1][0];
                         *sel = 0;
                         return icu;
                         *index=icu->bezt[i].vec[1][0];
                         *sel = 0;
                         return icu;
@@ -539,11 +618,11 @@ void column_select_actionkeys(bAction *act, int mode)
        switch (mode) {
                case 1:
                        /* create a list of all selected keys */
        switch (mode) {
                case 1:
                        /* create a list of all selected keys */
-                       for (achan=act->chanbase.first; achan; achan=achan->next){
+                       for (achan=act->chanbase.first; achan; achan=achan->next) {
                                if(VISIBLE_ACHAN(achan)) {
                                        if (achan->ipo)
                                                make_sel_cfra_list(achan->ipo, &elems);
                                if(VISIBLE_ACHAN(achan)) {
                                        if (achan->ipo)
                                                make_sel_cfra_list(achan->ipo, &elems);
-                                       if (EXPANDED_ACHAN(achan)) {
+                                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                                        if (conchan->ipo)
                                                                make_sel_cfra_list(conchan->ipo, &elems);
                                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                                        if (conchan->ipo)
                                                                make_sel_cfra_list(conchan->ipo, &elems);
@@ -587,7 +666,7 @@ void column_select_actionkeys(bAction *act, int mode)
                                }
                        }
                        
                                }
                        }
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
+                       if (EXPANDED_ACHAN(achan) == 0 || (FILTER_CON_ACHAN(achan)))
                                continue;
                        
                        for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                continue;
                        
                        for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
@@ -619,21 +698,32 @@ static void mouse_action(int selectmode)
 {
        bAction *act;
        bActionChannel *achan;
 {
        bAction *act;
        bActionChannel *achan;
-       bConstraintChannel *conchan;
+       bConstraintChannel *conchan= NULL;
+       IpoCurve *icu= NULL;
        TimeMarker *marker;
        TimeMarker *marker;
-       short mval[2], sel;
+       void *act_channel;
+       short sel, act_type;
        float   selx;
        
        act=G.saction->action;
        if (!act)
                return;
 
        float   selx;
        
        act=G.saction->action;
        if (!act)
                return;
 
-       getmouseco_areawin (mval);
-
-       achan=get_nearest_actionchannel_key(&selx, &sel, &conchan);
+       act_channel= get_nearest_actionchannel_key(&selx, &sel, &act_type, &achan);
        marker=find_nearest_marker(1);
        marker=find_nearest_marker(1);
-       
-       if (achan) {
+               
+       if (act_channel) {
+               switch (act_type) {
+                       case ACTTYPE_ICU:
+                               icu= (IpoCurve *)act_channel;
+                               break;
+                       case ACTTYPE_CONCHAN:
+                               conchan= (bConstraintChannel *)act_channel;
+                               break;
+                       default:
+                               achan= (bActionChannel *)act_channel;
+               }
+               
                if (selectmode == SELECT_REPLACE) {
                        selectmode = SELECT_ADD;
                        
                if (selectmode == SELECT_REPLACE) {
                        selectmode = SELECT_ADD;
                        
@@ -645,11 +735,12 @@ static void mouse_action(int selectmode)
                        select_poseelement_by_name(achan->name, 2);     /* 2 is activate */
                }
                
                        select_poseelement_by_name(achan->name, 2);     /* 2 is activate */
                }
                
-               if (conchan)
+               if (icu)
+                       select_icu_key(icu, selx, selectmode);
+               else if (conchan)
                        select_ipo_key(conchan->ipo, selx, selectmode);
                else
                        select_ipo_key(achan->ipo, selx, selectmode);
                        select_ipo_key(conchan->ipo, selx, selectmode);
                else
                        select_ipo_key(achan->ipo, selx, selectmode);
-
                
                std_rmouse_transform(transform_actionchannel_keys);
                
                
                std_rmouse_transform(transform_actionchannel_keys);
                
@@ -714,7 +805,7 @@ static void mouse_mesh_action(int selectmode, Key *key)
     getmouseco_areawin (mval);
     icu = get_nearest_meshchannel_key(&selx, &sel);
 
     getmouseco_areawin (mval);
     icu = get_nearest_meshchannel_key(&selx, &sel);
 
-    if (icu){
+    if (icu) {
         if (selectmode == SELECT_REPLACE) {
                        /* if we had planned to replace the
                         * selection, then we will first deselect
         if (selectmode == SELECT_REPLACE) {
                        /* if we had planned to replace the
                         * selection, then we will first deselect
@@ -777,23 +868,29 @@ void borderselect_action(void)
 { 
        rcti rect;
        rctf rectf;
 { 
        rcti rect;
        rctf rectf;
-       int val, selectmode;            
-       short   mval[2];
+       bAction *act;
        bActionChannel *achan;
        bConstraintChannel *conchan;
        bActionChannel *achan;
        bConstraintChannel *conchan;
-       bAction *act;
+       IpoCurve *icu;
+       int val, selectmode;
+       int (*select_function)(BezTriple *);
+       short   mval[2];
        float   ymin, ymax;
        float   ymin, ymax;
-
+       
        act=G.saction->action;
 
        if (!act)
                return;
 
        if ( (val = get_border(&rect, 3)) ) {
        act=G.saction->action;
 
        if (!act)
                return;
 
        if ( (val = get_border(&rect, 3)) ) {
-               if (val == LEFTMOUSE)
+               if (val == LEFTMOUSE) {
                        selectmode = SELECT_ADD;
                        selectmode = SELECT_ADD;
-               else
+                       select_function = select_bezier_add;
+               }
+               else {
                        selectmode = SELECT_SUBTRACT;
                        selectmode = SELECT_SUBTRACT;
+                       select_function = select_bezier_subtract;
+               }
                        
                mval[0]= rect.xmin;
                mval[1]= rect.ymin+2;
                        
                mval[0]= rect.xmin;
                mval[1]= rect.ymin+2;
@@ -813,20 +910,49 @@ void borderselect_action(void)
                
                for (achan=act->chanbase.first; achan; achan= achan->next) {
                        if(VISIBLE_ACHAN(achan)) {
                
                for (achan=act->chanbase.first; achan; achan= achan->next) {
                        if(VISIBLE_ACHAN(achan)) {
-                               /* Check action */
+                               /* Check action channel */
                                ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
                                if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
                                        borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
                                ymax=ymin;
                                        
                                if (EXPANDED_ACHAN(achan)) {
                                ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
                                if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
                                        borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
                                ymax=ymin;
                                        
                                if (EXPANDED_ACHAN(achan)) {
+                                       /* check ipo - although the action channel has already been checked, 
+                                        * selection may have started below that channel 
+                                        */
+                                        if (achan->ipo) {
+                                               /* skip the widget*/
+                                               ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
+                                               ymax= ymin;
+                                               
+                                               if (FILTER_IPO_ACHAN(achan)) {
+                                                       /* check ipo-curve channels */
+                                                       for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+                                                               ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
+                                                               if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
+                                                                       borderselect_icu_key(icu, rectf.xmin, rectf.xmax, select_function);
+                                                               
+                                                               ymax=ymin;
+                                                       }       
+                                               }
+                                        }
+                                       
                                        /* Check constraints */
                                        /* Check constraints */
-                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                       if (achan->constraintChannels.first) {
+                                               /* skip the widget*/
                                                ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
                                                ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
-                                               if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
-                                                       borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
+                                               ymax= ymin;
                                                
                                                
-                                               ymax=ymin;
+                                               /* check constraint channels */
+                                               if (FILTER_CON_ACHAN(achan)) {
+                                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                                               ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
+                                                               if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
+                                                                       borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
+                                                               
+                                                               ymax=ymin;
+                                                       }
+                                               }
                                        }
                                }
                        }
                                        }
                                }
                        }
@@ -848,8 +974,7 @@ void borderselect_mesh(Key *key)
        int      selectmode;
        int      (*select_function)(BezTriple *);
        IpoCurve *icu;
        int      selectmode;
        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
        if ( (val = get_border(&rect, 3)) ){
                /* set the selection function based on what
                 * mouse button had been used in the border
@@ -863,7 +988,7 @@ void borderselect_mesh(Key *key)
                        selectmode = SELECT_SUBTRACT;
                        select_function = select_bezier_subtract;
                }       
                        selectmode = SELECT_SUBTRACT;
                        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
                /* get the minimum and maximum adrcode numbers
                 * for the IpoCurves (this is the number that
                 * relates an IpoCurve to the keyblock it
@@ -980,7 +1105,7 @@ void transform_actionchannel_keys(int mode, int dummy)
                if (EDITABLE_ACHAN(achan)) {
                        tvtot+=fullselect_ipo_keys(achan->ipo);
 
                if (EDITABLE_ACHAN(achan)) {
                        tvtot+=fullselect_ipo_keys(achan->ipo);
 
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                tvtot+=fullselect_ipo_keys(conchan->ipo);
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                tvtot+=fullselect_ipo_keys(conchan->ipo);
@@ -1002,7 +1127,7 @@ void transform_actionchannel_keys(int mode, int dummy)
                if(EDITABLE_ACHAN(achan)) {
                        tvtot = add_trans_ipo_keys(achan->ipo, tv, tvtot);
                        
                if(EDITABLE_ACHAN(achan)) {
                        tvtot = add_trans_ipo_keys(achan->ipo, tv, tvtot);
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot);
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot);
@@ -1506,12 +1631,12 @@ void deselect_actionchannel_keys (bAction *act, int test, int sel)
                                        break;
                                }
 
                                        break;
                                }
 
-                               if (EXPANDED_ACHAN(achan) == 0)
+                               if ((EXPANDED_ACHAN(achan) == 0) || (FILTER_CON_ACHAN(achan)==0))
                                        continue;
                                
                                /* Test the constraint ipos */
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
                                        continue;
                                
                                /* Test the constraint ipos */
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
-                                       if (is_ipo_key_selected(conchan->ipo)){
+                                       if (is_ipo_key_selected(conchan->ipo)) {
                                                sel = 0;
                                                break;
                                        }
                                                sel = 0;
                                                break;
                                        }
@@ -1524,11 +1649,11 @@ void deselect_actionchannel_keys (bAction *act, int test, int sel)
        }
        
        /* Set the flags */
        }
        
        /* Set the flags */
-       for (achan= act->chanbase.first; achan; achan= achan->next){
+       for (achan= act->chanbase.first; achan; achan= achan->next) {
                if(VISIBLE_ACHAN(achan)) {
                        set_ipo_key_selection(achan->ipo, sel);
                        
                if(VISIBLE_ACHAN(achan)) {
                        set_ipo_key_selection(achan->ipo, sel);
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
                                        set_ipo_key_selection(conchan->ipo, sel);
                        }
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
                                        set_ipo_key_selection(conchan->ipo, sel);
                        }
@@ -1556,6 +1681,7 @@ void deselect_actionchannels (bAction *act, int test)
 {
        bActionChannel *achan;
        bConstraintChannel *conchan;
 {
        bActionChannel *achan;
        bConstraintChannel *conchan;
+       IpoCurve *icu;
        int sel= 1;     
 
        if (!act)
        int sel= 1;     
 
        if (!act)
@@ -1574,10 +1700,21 @@ void deselect_actionchannels (bAction *act, int test)
                                }
                                if (sel) {
                                        if (EXPANDED_ACHAN(achan)) {
                                }
                                if (sel) {
                                        if (EXPANDED_ACHAN(achan)) {
-                                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                                       if (SEL_CONCHAN(conchan)) {
-                                                               sel= 0;
-                                                               break;
+                                               if (FILTER_IPO_ACHAN(achan)) {
+                                                       for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+                                                               if (SEL_ICU(icu)) {
+                                                                       sel= 0;
+                                                                       break;
+                                                               }
+                                                       }
+
+                                               }
+                                               if (FILTER_CON_ACHAN(achan)) {
+                                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                                               if (SEL_CONCHAN(conchan)) {
+                                                                       sel= 0;
+                                                                       break;
+                                                               }
                                                        }
                                                }
                                        }
                                                        }
                                                }
                                        }
@@ -1599,11 +1736,21 @@ void deselect_actionchannels (bAction *act, int test)
                                achan->flag &= ~ACHAN_SELECTED;
 
                        if (EXPANDED_ACHAN(achan)) {
                                achan->flag &= ~ACHAN_SELECTED;
 
                        if (EXPANDED_ACHAN(achan)) {
-                               for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                       if (sel)
-                                               conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
-                                       else
-                                               conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
+                               if (FILTER_IPO_ACHAN(achan)) {
+                                       for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
+                                               if (sel)
+                                                       icu->flag |= IPO_SELECT;
+                                               else
+                                                       icu->flag &= ~IPO_SELECT;
+                                       }
+                               }
+                               if (FILTER_CON_ACHAN(achan)) {
+                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                               if (sel)
+                                                       conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
+                                               else
+                                                       conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
+                                       }
                                }
                        }
                }
                                }
                        }
                }
@@ -1636,8 +1783,7 @@ static void hilight_channel (bAction *act, bActionChannel *achan, short select)
 /* apparently within active object context */
 int select_channel(bAction *act, bActionChannel *achan, int selectmode) 
 {
 /* apparently within active object context */
 int select_channel(bAction *act, bActionChannel *achan, int selectmode) 
 {
-       /* Select the channel based on the selection mode
-        */
+       /* Select the channel based on the selection mode */
        int flag;
 
        switch (selectmode) {
        int flag;
 
        switch (selectmode) {
@@ -1662,8 +1808,7 @@ int select_channel(bAction *act, bActionChannel *achan, int selectmode)
 static int select_constraint_channel(bAction *act, 
                                      bConstraintChannel *conchan, 
                                      int selectmode) {
 static int select_constraint_channel(bAction *act, 
                                      bConstraintChannel *conchan, 
                                      int selectmode) {
-       /* Select the constraint channel based on the selection mode
-        */
+       /* Select the constraint channel based on the selection mode */
        int flag;
 
        switch (selectmode) {
        int flag;
 
        switch (selectmode) {
@@ -1682,6 +1827,26 @@ static int select_constraint_channel(bAction *act,
        return flag;
 }
 
        return flag;
 }
 
+int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode) 
+{
+       /* Select the channel based on the selection mode */
+       int flag;
+
+       switch (selectmode) {
+       case SELECT_ADD:
+               icu->flag |= IPO_SELECT;
+               break;
+       case SELECT_SUBTRACT:
+               icu->flag &= ~IPO_SELECT;
+               break;
+       case SELECT_INVERT:
+               icu->flag ^= IPO_SELECT;
+               break;
+       }
+       flag = (icu->flag & IPO_SELECT) ? 1 : 0;
+       return flag;
+}
+
 static void borderselect_actionchannels(bAction *act, short *mval,
                                  short *mvalo, int selectmode) 
 {
 static void borderselect_actionchannels(bAction *act, short *mval,
                                  short *mvalo, int selectmode) 
 {
@@ -1694,6 +1859,7 @@ static void borderselect_actionchannels(bAction *act, short *mval,
         */
        bActionChannel *achan;
        bConstraintChannel *conchan;
         */
        bActionChannel *achan;
        bConstraintChannel *conchan;
+       IpoCurve *icu;
        float click, x,y;
        int   clickmin, clickmax;
        int       wsize;
        float click, x,y;
        int   clickmin, clickmax;
        int       wsize;
@@ -1769,21 +1935,47 @@ static void borderselect_actionchannels(bAction *act, short *mval,
                }
                
                if (EXPANDED_ACHAN(achan) == 0) {
                }
                
                if (EXPANDED_ACHAN(achan) == 0) {
-                       /* cannot search constaint channels */
+                       /* cannot search IPO/constaint channels */
                        continue;
                }
                
                        continue;
                }
                
-               /* try in constaint channels */
-               for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
+               if (achan->ipo) {
+                       /* widget */
                        if (clickmax < 0) break;
                        if (clickmax < 0) break;
+                       --clickmin;
+                       --clickmax;
                        
                        
-                       if (clickmin <= 0) {
-                               /* constraint channel */
-                               select_constraint_channel(act, conchan, selectmode);
+                       for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
+                               if (clickmax < 0) break;
+                               
+                               if (clickmin <= 0) {
+                                       /* constraint channel */
+                                       select_icu_channel(act, icu, selectmode);
+                               }
+                               
+                               --clickmin;
+                               --clickmax;
                        }
                        }
-                       
+               }
+               
+               if (achan->constraintChannels.first) {
+                       /* widget */
+                       if (clickmax < 0) break;
                        --clickmin;
                        --clickmax;
                        --clickmin;
                        --clickmax;
+                       
+                       /* try in constaint channels */
+                       for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                               if (clickmax < 0) break;
+                               
+                               if (clickmin <= 0) {
+                                       /* constraint channel */
+                                       select_constraint_channel(act, conchan, selectmode);
+                               }
+                               
+                               --clickmin;
+                               --clickmax;
+                       }
                }
        }
        
                }
        }
        
@@ -1817,8 +2009,7 @@ static void mouse_actionchannels (short mval[])
                                }
                                else if (mval[0] <= 17) {
                                        /* toggle expand */
                                }
                                else if (mval[0] <= 17) {
                                        /* toggle expand */
-                                       if (achan->constraintChannels.first)
-                                               achan->flag ^= ACHAN_EXPANDED;
+                                       achan->flag ^= ACHAN_EXPANDED;
                                }                               
                                else {
                                        /* select/deselect achan */             
                                }                               
                                else {
                                        /* select/deselect achan */             
@@ -1835,6 +2026,32 @@ static void mouse_actionchannels (short mval[])
                                }
                        }
                                break;
                                }
                        }
                                break;
+               case ACTTYPE_FILLIPO:
+                       {
+                               bActionChannel *achan= (bActionChannel *)act_channel;
+                               achan->flag ^= ACHAN_SHOWIPO;
+                       }
+                       break;
+               case ACTTYPE_FILLCON:
+                       {
+                               bActionChannel *achan= (bActionChannel *)act_channel;
+                               achan->flag ^= ACHAN_SHOWCONS;
+                       }
+                       break;
+               case ACTTYPE_ICU: 
+                       {
+                               IpoCurve *icu= (IpoCurve *)act_channel;
+                               
+                               if (mval[0] >= (NAMEWIDTH-16)) {
+                                       /* toggle protection */
+                                       icu->flag ^= IPO_PROTECT;
+                               }
+                               else {
+                                       /* select/deselect */
+                                       select_icu_channel(act, icu, SELECT_INVERT);
+                               }
+                       }
+                       break;
                case ACTTYPE_CONCHAN:
                        {
                                bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
                case ACTTYPE_CONCHAN:
                        {
                                bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
@@ -1888,7 +2105,7 @@ void delete_actionchannel_keys(void)
                        /* Check action channel keys*/
                        delete_ipo_keys(achan->ipo);
                        
                        /* Check action channel keys*/
                        delete_ipo_keys(achan->ipo);
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                /* Delete constraint channel keys */
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan)) 
                                /* Delete constraint channel keys */
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan)) 
@@ -2020,12 +2237,22 @@ void clean_actionchannels(bAction *act)
                        if (SEL_ACHAN(achan)) {
                                ipo= achan->ipo;
                                if (ipo) {
                        if (SEL_ACHAN(achan)) {
                                ipo= achan->ipo;
                                if (ipo) {
-                                       for (icu= ipo->curve.first; icu; icu= icu->next) 
-                                               clean_ipo_curve(icu);
+                                       if (EXPANDED_ACHAN(achan) && FILTER_IPO_ACHAN(achan)) {
+                                               /* only clean selected ipo-curves */
+                                               for (icu= ipo->curve.first; icu; icu= icu->next) {
+                                                       if (SEL_ICU(icu) && EDITABLE_ICU(icu)) 
+                                                               clean_ipo_curve(icu);
+                                               }
+                                       }
+                                       else {
+                                               /* clean all ipo-curves for action channel */
+                                               for (icu= ipo->curve.first; icu; icu= icu->next) 
+                                                       clean_ipo_curve(icu);
+                                       }
                                }
                        }
                        
                                }
                        }
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                /* clean action channel's constraint channels */
                                for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan)) {
                                /* clean action channel's constraint channels */
                                for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan)) {
@@ -2075,7 +2302,7 @@ void sethandles_actionchannel_keys(int code)
                if (EDITABLE_ACHAN(achan)) {
                        sethandles_ipo_keys(achan->ipo, code);
                        
                if (EDITABLE_ACHAN(achan)) {
                        sethandles_ipo_keys(achan->ipo, code);
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                sethandles_ipo_keys(conchan->ipo, code);
                                for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan))
                                                sethandles_ipo_keys(conchan->ipo, code);
@@ -2130,7 +2357,7 @@ void set_ipotype_actionchannels(int ipotype)
                                        setipotype_ipo(achan->ipo, ipotype);
                        }
                
                                        setipotype_ipo(achan->ipo, ipotype);
                        }
                
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                /* constraint channels */
                                for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan)) {
                                /* constraint channels */
                                for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
                                        if (EDITABLE_CONCHAN(conchan)) {
@@ -2205,7 +2432,7 @@ void set_extendtype_actionchannels(int extendtype)
                                }
                        }
                        
                                }
                        }
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
+                       if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
                                continue;
                        
                        /* constraint channels */
                                continue;
                        
                        /* constraint channels */
@@ -2263,7 +2490,7 @@ static void set_snap_actionchannels(bAction *act, short snaptype)
                                }
                        }
                        
                                }
                        }
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
+                       if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
                                continue;
                        
                        /* constraint channels */
                                continue;
                        
                        /* constraint channels */
@@ -2363,7 +2590,7 @@ static void mirror_actionchannels(bAction *act, short mirror_mode)
                                }
                        }
                        
                                }
                        }
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
+                       if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
                                continue;
                        
                        /* constraint channels */
                                continue;
                        
                        /* constraint channels */
@@ -2510,7 +2737,7 @@ static void select_all_keys_frames(bAction *act, short *mval,
                if (VISIBLE_ACHAN(achan)) {
                        borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
                        
                if (VISIBLE_ACHAN(achan)) {
                        borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
                        
-                       if (EXPANDED_ACHAN(achan)) {
+                       if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
                                }
                                for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
                                        borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
                                }
@@ -2598,7 +2825,7 @@ static void select_all_keys_channels(bAction *act, short *mval,
                        --clickmin;
                        --clickmax;
                        
                        --clickmin;
                        --clickmax;
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
+                       if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
                                continue;
                                
                        /* Check for click in a constraint */
                                continue;
                                
                        /* Check for click in a constraint */
@@ -2717,10 +2944,12 @@ static void clever_achannel_names(short *mval)
        void *act_channel;
        bActionChannel *achan= NULL;
        bConstraintChannel *conchan= NULL;
        void *act_channel;
        bActionChannel *achan= NULL;
        bConstraintChannel *conchan= NULL;
+       IpoCurve *icu= NULL;
        
        int but=0;
     char str[64];
        short expand, protect, chantype;
        
        int but=0;
     char str[64];
        short expand, protect, chantype;
+       //float slidermin, slidermax;
        
        /* figure out what is under cursor */
        act_channel= get_nearest_act_channel(mval, &chantype);
        
        /* figure out what is under cursor */
        act_channel= get_nearest_act_channel(mval, &chantype);
@@ -2735,6 +2964,7 @@ static void clever_achannel_names(short *mval)
                
                add_numbut(but++, TEX, "ActChan: ", 0, 24, str, "Name of Action Channel");
                add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
                
                add_numbut(but++, TEX, "ActChan: ", 0, 24, str, "Name of Action Channel");
                add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
+               add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
        }
        else if (chantype == ACTTYPE_CONCHAN) {
                conchan= (bConstraintChannel *)act_channel;
        }
        else if (chantype == ACTTYPE_CONCHAN) {
                conchan= (bConstraintChannel *)act_channel;
@@ -2743,17 +2973,41 @@ static void clever_achannel_names(short *mval)
                protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
                
                add_numbut(but++, TEX, "ConChan: ", 0, 24, str, "Name of Constraint Channel");
                protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
                
                add_numbut(but++, TEX, "ConChan: ", 0, 24, str, "Name of Constraint Channel");
+               add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
        }
        }
+#if 0 /* tempolarily disabled until there is actually something to display  */
+       else if (chantype == ACTTYPE_ICU) {
+               icu= (IpoCurve *)act_channel;
+               
+               strcpy(str, getname_ipocurve(icu));
+               slidermin= icu->ymin; /* ugly hack :) */
+               slidermax= icu->ymax; /* ugly hack :) */
+               protect= (icu->flag & IPO_PROTECT);
+               
+               add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
+               add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
+               add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+       }
+#endif
        else {
                /* nothing under-cursor */
                return;
        }
        else {
                /* nothing under-cursor */
                return;
        }
-       add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+       
        
        /* draw clever-numbut */
     if (do_clever_numbuts(str, but, REDRAW)) {
                /* restore settings based on type */
        
        /* draw clever-numbut */
     if (do_clever_numbuts(str, but, REDRAW)) {
                /* restore settings based on type */
-               if (conchan) {
+#if 0 /* tempolarily disabled until further notice */
+               if (icu) {
+                       icu->ymin= slidermin; /* ugly hack :) */
+                       icu->ymax= slidermax; /* ugly hack :) */
+                       
+                       if (protect) icu->flag |= IPO_PROTECT;
+                       else icu->flag &= ~IPO_PROTECT;
+               }
+#endif
+               /*else */if (conchan) {
                        strcpy(conchan->name, str);
                        
                        if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
                        strcpy(conchan->name, str);
                        
                        if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
@@ -3320,6 +3574,7 @@ void *get_nearest_act_channel(short mval[], short *ret_type)
        bAction *act= G.saction->action;
        bActionChannel *achan;
        bConstraintChannel *conchan;
        bAction *act= G.saction->action;
        bActionChannel *achan;
        bConstraintChannel *conchan;
+       IpoCurve *icu;
        
        float   x,y;
        int   clickmin, clickmax;
        
        float   x,y;
        int   clickmin, clickmax;
@@ -3349,14 +3604,13 @@ void *get_nearest_act_channel(short mval[], short *ret_type)
        /* try in action channels */
        for (achan = act->chanbase.first; achan; achan=achan->next) {
                if(VISIBLE_ACHAN(achan)) {
        /* try in action channels */
        for (achan = act->chanbase.first; achan; achan=achan->next) {
                if(VISIBLE_ACHAN(achan)) {
-                       if (clickmax < 0) break;
-
+                       if (clickmax < 0) 
+                               break;
                        if (clickmin <= 0) {
                                /* found match - action channel */
                                *ret_type= ACTTYPE_ACHAN;
                                return achan;
                        }
                        if (clickmin <= 0) {
                                /* found match - action channel */
                                *ret_type= ACTTYPE_ACHAN;
                                return achan;
                        }
-                       
                        --clickmin;
                        --clickmax;
                }
                        --clickmin;
                        --clickmax;
                }
@@ -3366,18 +3620,62 @@ void *get_nearest_act_channel(short mval[], short *ret_type)
                if (EXPANDED_ACHAN(achan) == 0)
                        continue;
                
                if (EXPANDED_ACHAN(achan) == 0)
                        continue;
                
-               /* try in constaint channels */
-               for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                       if (clickmax < 0) break;
-                       
+               /* try in ipo curves */
+               if (achan->ipo) {
+                       /* check header first */
+                       if (clickmax < 0) 
+                               break;
                        if (clickmin <= 0) {
                        if (clickmin <= 0) {
-                               /* found match - constraint channel */
-                               *ret_type= ACTTYPE_CONCHAN;
-                               return conchan;
+                               /* found match - ipo-curves show/hide */
+                               *ret_type= ACTTYPE_FILLIPO;
+                               return achan; /* pointer to action-channel is returned in this case */
                        }
                        }
+                       --clickmin;
+                       --clickmax;
                        
                        
+                       /* now the ipo-curve channels if they are exposed  */
+                       if (FILTER_IPO_ACHAN(achan)) {
+                               for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
+                                       if (clickmax < 0) 
+                                               break;
+                                       if (clickmin <= 0) {
+                                               /* found match - ipo-curve channel */
+                                               *ret_type= ACTTYPE_ICU;
+                                               return icu; 
+                                       }
+                                       --clickmin;
+                                       --clickmax;
+                               }
+                       }
+               }
+               
+               /* try in constaint channels */
+               if (achan->constraintChannels.first) {
+                       /* check header first */
+                       if (clickmax < 0) 
+                               break;
+                       if (clickmin <= 0) {
+                               /* found match - constraints show/hide */
+                               *ret_type= ACTTYPE_FILLCON;
+                               return achan; /* pointer to action-channel is returned in this case */
+                       }
                        --clickmin;
                        --clickmax;
                        --clickmin;
                        --clickmax;
+                       
+                       /* now the constraint channels if they are exposed  */
+                       if (FILTER_CON_ACHAN(achan)) {
+                               for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
+                                       if (clickmax < 0) 
+                                               break;
+                                       if (clickmin <= 0) {
+                                               /* found match - constraint channel */
+                                               *ret_type= ACTTYPE_CONCHAN;
+                                               return conchan;
+                                       }
+                                       --clickmin;
+                                       --clickmax;
+                               }
+                       }
                }
        }
        
                }
        }
        
@@ -3424,7 +3722,7 @@ void markers_selectkeys_between(void)
                                }
                        }
                        
                                }
                        }
                        
-                       if (EXPANDED_ACHAN(achan) == 0)
+                       if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
                                continue;
                        
                        for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
                                continue;
                        
                        for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
@@ -3784,7 +4082,7 @@ bAction* bake_obIPO_to_action (Object *ob)
        return result;  
 }
 
        return result;  
 }
 
-bActionbake_everything_to_action (Object *ob)
+bAction *bake_everything_to_action (Object *ob)
 {
        bArmature               *arm;
        bAction                 *result=NULL;
 {
        bArmature               *arm;
        bAction                 *result=NULL;
@@ -3800,7 +4098,6 @@ bAction* bake_everything_to_action (Object *ob)
        arm = get_armature(ob);
        
        if (arm) {      
        arm = get_armature(ob);
        
        if (arm) {      
-       
                oldframe = CFRA;
                result = add_empty_action("Action");
                id = (ID *)ob;
                oldframe = CFRA;
                result = add_empty_action("Action");
                id = (ID *)ob;
index f32e1816b2d085eaa7e9239369e6129c56b9ff40..8707e5dd12cf019af3a0de572ef882f81b63e242 100644 (file)
@@ -40,6 +40,8 @@
 #include "BKE_ipo.h"
 #include "BKE_utildefines.h"
 
 #include "BKE_ipo.h"
 #include "BKE_utildefines.h"
 
+#include "BIF_resources.h"
+
 #include "BSE_edit.h"
 #include "BSE_editipo_types.h"
 #include "BSE_editipo.h"
 #include "BSE_edit.h"
 #include "BSE_editipo_types.h"
 #include "BSE_editipo.h"
@@ -95,6 +97,51 @@ char *ac_ic_names[AC_TOTNAM] = {"LocX", "LocY", "LocZ", "ScaleX", "ScaleY",
 char *ic_name_empty[1] ={ "" };
 char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time",  "GravX","GravY","GravZ",  "VelX","VelY","VelZ", "Active"  };
 
 char *ic_name_empty[1] ={ "" };
 char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time",  "GravX","GravY","GravZ",  "VelX","VelY","VelZ", "Active"  };
 
+/* gets the appropriate icon for the given blocktype */
+int geticon_ipo_blocktype(short blocktype)
+{
+       switch (blocktype) {
+               case ID_OB:
+                       return ICON_OBJECT;
+               case ID_PO:
+                       return ICON_POSE_HLT;
+               case ID_KE:
+                       return ICON_EDIT;
+               case ID_MA:
+                       return ICON_MATERIAL;
+               case ID_WO:
+                       return ICON_WORLD;
+               case ID_CU:
+                       return ICON_CURVE;
+               case ID_CA:
+                       return ICON_CAMERA;
+               case ID_LA:
+                       return ICON_LAMP;
+               case ID_TE:
+                       return ICON_TEXTURE;
+               case ID_CO:
+                       return ICON_CONSTRAINT;
+               case ID_FLUIDSIM:
+                       return ICON_WORLD; // uggh
+               default:
+                       return 0; // what about blank icon?
+       }
+}
+
+/* get name of ipo-curve (icu should be valid pointer) */
+char *getname_ipocurve(IpoCurve *icu)
+{
+       switch (icu->blocktype) {
+               case ID_OB:
+                       return getname_ob_ei(icu->adrcode, 0); /* dummy 2nd arg */
+               case ID_PO:
+                       return getname_ac_ei(icu->adrcode);
+                       
+               default: /* fixme - add all of the other types! */
+                       return NULL;
+       }
+}
+
 char *getname_ac_ei(int nr) 
 {
        switch(nr) {
 char *getname_ac_ei(int nr) 
 {
        switch(nr) {
index f55e4278533aaf1fa5bc3e220939a6846954ae8f..4555853cc62b4935305dad6b2f6a9db1487f76a9 100644 (file)
@@ -1117,7 +1117,7 @@ int fullselect_ipo_keys(Ipo *ipo)
        if (!ipo)
                return tvtot;
        
        if (!ipo)
                return tvtot;
        
-       for (icu=ipo->curve.first; icu; icu=icu->next){
+       for (icu=ipo->curve.first; icu; icu=icu->next) {
                for (i=0; i<icu->totvert; i++){
                        if (icu->bezt[i].f2 & 1){
                                tvtot+=3;
                for (i=0; i<icu->totvert; i++){
                        if (icu->bezt[i].f2 & 1){
                                tvtot+=3;