== Action Editor ==
Final tweaks to Snapping and Mirroring tools: * Snap To Nearest Marker * Mirror Values of Horizontal Axis * Mirror Over Selected Marker
This commit is contained in:
@@ -49,6 +49,7 @@ struct TimeMarker *find_nearest_marker(int clip_y);
|
||||
|
||||
void nextprev_marker(short dir);
|
||||
void get_minmax_markers(short sel, float *first, float *last);
|
||||
int find_nearest_marker_time(float dx);
|
||||
|
||||
void add_marker_to_cfra_elem(struct ListBase *lb, struct TimeMarker *marker, short only_sel);
|
||||
void make_marker_cfra_list(struct ListBase *lb, short only_sel);
|
||||
|
@@ -2320,6 +2320,9 @@ void snap_keys_to_frame(int snap_mode)
|
||||
case 2:
|
||||
strcpy(str, "Snap Keys To Current Frame");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(str, "Snap Keys To Nearest Marker");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -2415,6 +2418,12 @@ void mirror_action_keys(short mirror_mode)
|
||||
case 2:
|
||||
strcpy(str, "Mirror Keys Over Y-Axis");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(str, "Mirror Keys Over X-Axis");
|
||||
break;
|
||||
case 4:
|
||||
strcpy(str, "Mirror Keys Over Marker");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -2946,7 +2955,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case MKEY:
|
||||
if (G.qual & LR_SHIFTKEY) {
|
||||
/* mirror keyframes */
|
||||
val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2");
|
||||
val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
|
||||
mirror_action_keys(val);
|
||||
}
|
||||
else {
|
||||
@@ -2985,7 +2994,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case SKEY:
|
||||
if (mval[0]>=ACTWIDTH) {
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2");
|
||||
val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2|Nearest Marker %x3");
|
||||
snap_keys_to_frame(val);
|
||||
}
|
||||
else {
|
||||
|
@@ -564,6 +564,14 @@ static int snap_bezier_cframe(BezTriple *bezt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snap_bezier_nearmarker(BezTriple *bezt)
|
||||
{
|
||||
if(bezt->f2 & SELECT)
|
||||
bezt->vec[1][0]= (float)find_nearest_marker_time(bezt->vec[1][0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snap_ipo_keys(Ipo *ipo, short snaptype)
|
||||
{
|
||||
switch (snaptype) {
|
||||
@@ -573,6 +581,9 @@ void snap_ipo_keys(Ipo *ipo, short snaptype)
|
||||
case 2: /* snap to current frame */
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier_cframe, calchandles_ipocurve);
|
||||
break;
|
||||
case 3: /* snap to nearest marker */
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier_nearmarker, calchandles_ipocurve);
|
||||
break;
|
||||
default: /* just in case */
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
|
||||
break;
|
||||
@@ -603,15 +614,80 @@ static int mirror_bezier_yaxis(BezTriple *bezt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mirror_bezier_xaxis(BezTriple *bezt)
|
||||
{
|
||||
float diff;
|
||||
|
||||
if(bezt->f2 & SELECT) {
|
||||
diff= (0.0f - bezt->vec[1][1]);
|
||||
bezt->vec[1][1]= (0.0f + diff);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mirror_bezier_marker(BezTriple *bezt)
|
||||
{
|
||||
static TimeMarker *marker;
|
||||
static short initialised = 0;
|
||||
float diff;
|
||||
|
||||
/* In order for this mirror function to work without
|
||||
* any extra arguments being added, we use the case
|
||||
* of bezt==NULL to denote that we should find the
|
||||
* marker to mirror over. The static pointer is safe
|
||||
* to use this way, as it will be set to null after
|
||||
* each cycle in which this is called.
|
||||
*/
|
||||
|
||||
if (bezt) {
|
||||
/* mirroring time */
|
||||
if((bezt->f2 & SELECT) && (marker)) {
|
||||
diff= (marker->frame - bezt->vec[1][0]);
|
||||
bezt->vec[1][0]= (marker->frame + diff);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* initialisation time */
|
||||
if (initialised) {
|
||||
/* reset everything for safety */
|
||||
marker = NULL;
|
||||
initialised = 0;
|
||||
}
|
||||
else {
|
||||
/* try to find a marker */
|
||||
for (marker= G.scene->markers.first; marker; marker=marker->next) {
|
||||
if (marker->flag & SELECT) {
|
||||
initialised = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (initialised == 0)
|
||||
marker = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mirror_ipo_keys(Ipo *ipo, short mirror_type)
|
||||
{
|
||||
switch (mirror_type) {
|
||||
case 1: /* mirror over current frame */
|
||||
ipo_keys_bezier_loop(ipo, mirror_bezier_cframe, calchandles_ipocurve);
|
||||
break;
|
||||
case 2: /* snap over frame 0 */
|
||||
case 2: /* mirror over frame 0 */
|
||||
ipo_keys_bezier_loop(ipo, mirror_bezier_yaxis, calchandles_ipocurve);
|
||||
break;
|
||||
case 3: /* mirror over value 0 */
|
||||
ipo_keys_bezier_loop(ipo, mirror_bezier_xaxis, calchandles_ipocurve);
|
||||
break;
|
||||
case 4: /* mirror over marker */
|
||||
mirror_bezier_marker(NULL);
|
||||
ipo_keys_bezier_loop(ipo, mirror_bezier_marker, calchandles_ipocurve);
|
||||
mirror_bezier_marker(NULL);
|
||||
break;
|
||||
default: /* just in case */
|
||||
ipo_keys_bezier_loop(ipo, mirror_bezier_yaxis, calchandles_ipocurve);
|
||||
break;
|
||||
|
@@ -537,9 +537,7 @@ void make_marker_cfra_list(ListBase *lb, short only_sel)
|
||||
}
|
||||
}
|
||||
|
||||
/* *********** End Markers - Markers API *************** */
|
||||
|
||||
static int find_nearest_timeline_marker(float dx)
|
||||
int find_nearest_marker_time(float dx)
|
||||
{
|
||||
TimeMarker *marker, *nearest= NULL;
|
||||
float dist, min_dist= 1000000;
|
||||
@@ -556,6 +554,7 @@ static int find_nearest_timeline_marker(float dx)
|
||||
else return (int)floor(dx);
|
||||
}
|
||||
|
||||
/* *********** End Markers - Markers API *************** */
|
||||
/* select/deselect TimeMarker at current frame */
|
||||
static void select_timeline_marker_frame(int frame, unsigned char shift)
|
||||
{
|
||||
@@ -799,7 +798,7 @@ void winqreadtimespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
getmouseco_areawin(mval);
|
||||
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
|
||||
|
||||
cfra= find_nearest_timeline_marker(dx);
|
||||
cfra= find_nearest_marker_time(dx);
|
||||
|
||||
if (G.qual && LR_SHIFTKEY)
|
||||
select_timeline_marker_frame(cfra, 1);
|
||||
|
@@ -131,9 +131,12 @@
|
||||
|
||||
#define ACTMENU_KEY_SNAP_NEARFRAME 1
|
||||
#define ACTMENU_KEY_SNAP_CURFRAME 2
|
||||
#define ACTMENU_KEY_SNAP_NEARMARK 3
|
||||
|
||||
#define ACTMENU_KEY_MIRROR_CURFRAME 1
|
||||
#define ACTMENU_KEY_MIRROR_YAXIS 2
|
||||
#define ACTMENU_KEY_MIRROR_XAXIS 3
|
||||
#define ACTMENU_KEY_MIRROR_MARKER 4
|
||||
|
||||
#define ACTMENU_MARKERS_ADD 0
|
||||
#define ACTMENU_MARKERS_DUPLICATE 1
|
||||
@@ -906,6 +909,7 @@ static void do_action_keymenu_snapmenu(void *arg, int event)
|
||||
{
|
||||
case ACTMENU_KEY_SNAP_NEARFRAME:
|
||||
case ACTMENU_KEY_SNAP_CURFRAME:
|
||||
case ACTMENU_KEY_SNAP_NEARMARK:
|
||||
snap_keys_to_frame(event);
|
||||
break;
|
||||
}
|
||||
@@ -930,6 +934,10 @@ static uiBlock *action_keymenu_snapmenu(void *arg_unused)
|
||||
"Current Frame|Shift S, 2", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_CURFRAME, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Nearest Marker|Shift S, 3", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_NEARMARK, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
@@ -967,6 +975,14 @@ static uiBlock *action_keymenu_mirrormenu(void *arg_unused)
|
||||
"Vertical Axis|Shift M, 2", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_MIRROR_YAXIS, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Horizontal Axis|Shift M, 3", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_MIRROR_XAXIS, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Selected Marker|Shift M, 4", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_MIRROR_MARKER, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
|
Reference in New Issue
Block a user