diff options
-rw-r--r-- | source/blender/src/editaction.c | 126 | ||||
-rw-r--r-- | source/blender/src/header_action.c | 12 |
2 files changed, 133 insertions, 5 deletions
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 42720dbc7c9..fc7c12a2db5 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -555,6 +555,112 @@ static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel) return firsticu; } +/* This function makes a list of the selected keyframes + * in the ipo curves it has been passed + */ +static void make_sel_cfra_list(Ipo *ipo, ListBase *elems) +{ + IpoCurve *icu; + BezTriple *bezt; + int a; + + for(icu= ipo->curve.first; icu; icu= icu->next) { + + bezt= icu->bezt; + if(bezt) { + a= icu->totvert; + while(a--) { + if(bezt->f2 & 1) { + add_to_cfra_elem(elems, bezt); + } + bezt++; + } + } + } +} + +/* This function selects all key frames in the same column(s) as a already selected key(s) + * this version only works for Shape Keys, Key should be not NULL + */ +static void select_frames_by_sel_frameskey(Key *key) +{ + + if(key->ipo) { + IpoCurve *icu; + ListBase elems= {NULL, NULL}; + CfraElem *ce; + + /* create a list of all selected keys */ + make_sel_cfra_list(key->ipo, &elems); + + /* loop through all of the keys and select additional keyframes + * based on the keys found to be selected above + */ + for(ce= elems.first; ce; ce= ce->next) { + for (icu = key->ipo->curve.first; icu ; icu = icu->next) { + BezTriple *bezt= icu->bezt; + if(bezt) { + int verts = icu->totvert; + while(verts--) { + if( ((int)ce->cfra) == ((int)bezt->vec[1][0]) ) { + bezt->f2 |= 1; + } + bezt++; + } + } + } + } + + BLI_freelistN(&elems); + } +} + +/* This function selects all key frames in the same column(s) as a already selected key(s) + * this version only works for on Action. *act should be not NULL + */ +static void select_frames_by_sel_framesaction(bAction *act) +{ + IpoCurve *icu; + BezTriple *bezt; + ListBase elems= {NULL, NULL}; + CfraElem *ce; + bActionChannel *chan; + + /* create a list of all selected keys */ + for (chan=act->chanbase.first; chan; chan=chan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { + if (chan->ipo) + make_sel_cfra_list(chan->ipo, &elems); + } + } + + /* loop through all of the keys and select additional keyframes + * based on the keys found to be selected above + */ + for (chan=act->chanbase.first; chan; chan=chan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { + if (chan->ipo) { + for(ce= elems.first; ce; ce= ce->next) { + for (icu = chan->ipo->curve.first; icu; icu = icu->next){ + bezt= icu->bezt; + if(bezt) { + int verts = icu->totvert; + while(verts--) { + + if( ((int)ce->cfra) == ((int)bezt->vec[1][0]) ) { + bezt->f2 |= 1; + } + bezt++; + } + } + } + } + } + } + } + BLI_freelistN(&elems); +} + /* apparently within active object context */ static void mouse_action(int selectmode) { @@ -677,10 +783,10 @@ void borderselect_action(void) return; if ( (val = get_border(&rect, 3)) ){ - if (val == LEFTMOUSE) - selectmode = SELECT_ADD; - else - selectmode = SELECT_SUBTRACT; + if (val == LEFTMOUSE) + selectmode = SELECT_ADD; + else + selectmode = SELECT_SUBTRACT; mval[0]= rect.xmin; mval[1]= rect.ymin+2; @@ -2359,6 +2465,18 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } break; + case KKEY: + if(key) + select_frames_by_sel_frameskey(key); + else if(act) + select_frames_by_sel_framesaction(act); + + allqueue(REDRAWIPO, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + break; + case NKEY: if(G.qual==0) { numbuts_action(); diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index e6b4442bdd5..e5fc8335721 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -87,6 +87,7 @@ #define ACTMENU_SEL_BORDER 0 #define ACTMENU_SEL_ALL_KEYS 1 #define ACTMENU_SEL_ALL_CHAN 2 +#define ACTMENU_SEL_COLLUMN 3 #define ACTMENU_KEY_DUPLICATE 0 #define ACTMENU_KEY_DELETE 1 @@ -356,6 +357,10 @@ static void do_action_selectmenu(void *arg, int event) allqueue(REDRAWNLA, 0); allqueue (REDRAWIPO, 0); break; + + case ACTMENU_SEL_COLLUMN: + addqueue (curarea->win, KKEY, 1); + break; } } @@ -382,7 +387,12 @@ static uiBlock *action_selectmenu(void *arg_unused) "Select/Deselect All Channels", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, ACTMENU_SEL_ALL_CHAN, ""); - + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Select Collumn|K", 0, yco-=20, + menuwidth, 19, NULL, 0.0, 0.0, 0, + ACTMENU_SEL_COLLUMN, ""); + + if(curarea->headertype==HEADERTOP) { uiBlockSetDirection(block, UI_DOWN); } |