Patch #5028. by Joshua Leung (aligorith)

Key snapping in Action Window, cleanup and added option to snap to
current frame.
This commit is contained in:
Ton Roosendaal 2006-11-07 18:34:32 +00:00
parent a221ddcf9b
commit 2e93510a6b
5 changed files with 94 additions and 26 deletions

@ -77,7 +77,9 @@ void transform_actionchannel_keys(int mode, int dummy);
void transform_meshchannel_keys(char mode, struct Key *key);
struct Key *get_action_mesh_key(void);
int get_nearest_key_num(struct Key *key, short *mval, float *x);
void set_snap_actionchannels(void);
void snap_keys_to_frame(void);
/* channel/strip operations */
void up_sel_action(void);
void down_sel_action(void);
void top_sel_action(void);

@ -135,7 +135,7 @@ void sampledata_to_ipocurve(float *data, int sfra, int efra, struct IpoCurve *ic
void ipo_record(void);
void sethandles_ipo_keys(struct Ipo *ipo, int code);
void snap_ipo_keys(struct Ipo *ipo);
void snap_ipo_keys(struct Ipo *ipo, short snaptype);
void setipotype_ipo(struct Ipo *ipo, int code);
void set_ipo_key_selection(struct Ipo *ipo, int sel);
int is_ipo_key_selected(struct Ipo *ipo);

@ -1997,41 +1997,91 @@ void set_extendtype_actionchannels(int extendtype)
allqueue(REDRAWNLA, 0);
}
void set_snap_actionchannels(void)
static void set_snap_actionchannels(bAction *act, short snaptype)
{
bAction *act;
/* snapping function for action channels*/
bActionChannel *chan;
bConstraintChannel *conchan;
/* Get the selected action, exit if none are selected
*/
act = G.saction->action;
if (!act)
return;
/* Loop through the channels */
for (chan = act->chanbase.first; chan; chan=chan->next){
if((chan->flag & ACHAN_HIDDEN)==0) {
if (chan->ipo) {
snap_ipo_keys(chan->ipo);
snap_ipo_keys(chan->ipo, snaptype);
}
/* constraint channels */
for (conchan=chan->constraintChannels.first; conchan; conchan= conchan->next) {
if (conchan->ipo) {
snap_ipo_keys(conchan->ipo);
snap_ipo_keys(conchan->ipo, snaptype);
}
}
}
}
}
static void set_snap_meshchannels(Key *key, short snaptype)
{
/* snapping function for mesh channels */
if(key->ipo) {
snap_ipo_keys(key->ipo, snaptype);
}
}
void snap_keys_to_frame()
{
/* This function is the generic entry-point for snapping keyframes
* to a frame(s). It passes the work off to sub-functions for the
* different types in the action editor.
*/
SpaceAction *saction;
bAction *act;
Key *key;
short event;
/* get data */
saction= curarea->spacedata.first;
if (!saction) return;
act = saction->action;
key = get_action_mesh_key();
/* Clean up and redraw stuff */
remake_action_ipos (act);
BIF_undo_push("Snap Ipo Action channel");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
/* find the type of snapping to do */
event = pupmenu("Snap Frames To%t|Nearest Frame%x1|Current Frame%x2");
/* handle events */
switch (event) {
case 1: /* snap to nearest frame */
if (act)
set_snap_actionchannels(act, event);
else
set_snap_meshchannels(key, event);
/* Clean up and redraw stuff */
remake_action_ipos (act);
BIF_undo_push("Snap To Nearest Frame");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
break;
case 2: /* snap to current frame */
if (act)
set_snap_actionchannels(act, event);
else
set_snap_meshchannels(key, event);
/* Clean up and redraw stuff */
remake_action_ipos (act);
BIF_undo_push("Snap To Current Frame");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
break;
}
}
@ -2517,8 +2567,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case SKEY:
if (mval[0]>=ACTWIDTH) {
if(G.qual & LR_SHIFTKEY) {
if(okee("Snap to frame"))
set_snap_actionchannels();
snap_keys_to_frame();
}
else {
if (key)

@ -555,16 +555,33 @@ void sethandles_ipo_keys(Ipo *ipo, int code)
}
}
static int snap_bezier(BezTriple *bezt)
static int snap_bezier_nearest(BezTriple *bezt)
{
if(bezt->f2 & SELECT)
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
return 0;
}
void snap_ipo_keys(Ipo *ipo)
static int snap_bezier_cframe(BezTriple *bezt)
{
ipo_keys_bezier_loop(ipo, snap_bezier, calchandles_ipocurve);
if(bezt->f2 & SELECT)
bezt->vec[1][0]= (float)CFRA;
return 0;
}
void snap_ipo_keys(Ipo *ipo, short snaptype)
{
switch (snaptype) {
case 1: /* snap to nearest */
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
break;
case 2: /* snap to current frame */
ipo_keys_bezier_loop(ipo, snap_bezier_cframe, calchandles_ipocurve);
break;
default: /* just in case */
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
break;
}
}
static void ipo_curves_auto_horiz(void)

@ -778,7 +778,7 @@ static void do_action_keymenu(void *arg, int event)
bake_action_with_client (G.saction->action, OBACT, 0.01);
break;
case ACTMENU_KEY_SNAP:
set_snap_actionchannels();
snap_keys_to_frame();
break;
}
}