2.5 - Action Editor

* Started porting back keyframe editing tools for the Action Editor/Dopesheet. Currently, only Snap (Shift-S) and Mirror (Shift-M) are functional.

* Added keyframe-editing API method for ensuring that all IPO-curves are left in a valid state after modifiying the values of their keyframes.

* Added operator-register flags for most of the operators. Only mouse-select doesn't have it for now (as there's not much useful info stored, and no exec callback).
This commit is contained in:
2008-12-27 11:44:00 +00:00
parent 032adf70d9
commit 86886cbc55
7 changed files with 476 additions and 201 deletions

View File

@@ -144,6 +144,34 @@ short animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEd
return 0;
}
/* ************************************************************************** */
/* Keyframe Integrity Tools */
/* Rearrange keyframes if some are out of order */
// used to be recalc_*_ipos() where * was object or action
void ANIM_editkeyframes_refresh(bAnimContext *ac)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
/* filter animation data */
filter= ANIMFILTER_ONLYICU;
ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
/* loop over ipo-curves that are likely to have been edited, and check them */
for (ale= anim_data.first; ale; ale= ale->next) {
IpoCurve *icu= ale->key_data;
/* make sure keyframes in IPO-curve are all in order, and handles are in valid positions */
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
}
/* free temp data */
BLI_freelistN(&anim_data);
}
/* ************************************************************************** */
/* BezTriple Validation Callbacks */
@@ -286,44 +314,10 @@ static short mirror_bezier_xaxis(BeztEditData *bed, BezTriple *bezt)
static short mirror_bezier_marker(BeztEditData *bed, BezTriple *bezt)
{
static TimeMarker *marker;
static short initialised = 0;
const Scene *scene= bed->scene;
/* 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)) {
const float 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= scene->markers.first; marker; marker=marker->next) {
if (marker->flag & SELECT) {
initialised = 1;
break;
}
}
if (initialised == 0)
marker = NULL;
}
/* mirroring time stored in f1 */
if (bezt->f2 & SELECT) {
const float diff= (bed->f1 - bezt->vec[1][0]);
bezt->vec[1][0]= (bed->f1 + diff);
}
return 0;
@@ -334,20 +328,22 @@ static short mirror_bezier_marker(BeztEditData *bed, BezTriple *bezt)
BeztEditFunc ANIM_editkeyframes_mirror(short type)
{
switch (type) {
case 1: /* mirror over current frame */
case MIRROR_KEYS_CURFRAME: /* mirror over current frame */
return mirror_bezier_cframe;
case 2: /* mirror over frame 0 */
case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */
return mirror_bezier_yaxis;
case 3: /* mirror over value 0 */
case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
return mirror_bezier_xaxis;
case 4: /* mirror over marker */
return mirror_bezier_marker; // XXX in past, this func was called before/after with NULL, probably will need globals instead
case MIRROR_KEYS_MARKER: /* mirror over marker */
return mirror_bezier_marker;
default: /* just in case */
return mirror_bezier_yaxis;
break;
}
}
/* --------- */
/* This function is called to calculate the average location of the
* selected keyframes, and place the current frame at that location.
*
@@ -654,6 +650,7 @@ short is_ipo_key_selected(Ipo *ipo)
return 0;
}
// XXX although this is still needed, it should be removed!
void set_ipo_key_selection(Ipo *ipo, short sel)
{
IpoCurve *icu;
@@ -678,6 +675,7 @@ void set_ipo_key_selection(Ipo *ipo, short sel)
}
}
// XXX port this over to the new system!
// err... this is this still used?
int fullselect_ipo_keys(Ipo *ipo)
{
@@ -701,134 +699,3 @@ int fullselect_ipo_keys(Ipo *ipo)
return tvtot;
}
void borderselect_icu_key(IpoCurve *icu, float xmin, float xmax, BeztEditFunc select_cb)
{
/* Selects all bezier triples in the Ipocurve
* between times xmin and xmax, using the selection
* function.
*/
BezTriple *bezt;
int i;
/* loop through all of the bezier triples in
* the Ipocurve -- if the triple occurs between
* times xmin and xmax then select it using the selection
* function
*/
for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
if ((bezt->vec[1][0] > xmin) && (bezt->vec[1][0] < xmax)) {
/* scene is NULL (irrelevant here) */
select_cb(NULL, bezt);
}
}
}
void borderselect_ipo_key(Ipo *ipo, float xmin, float xmax, short selectmode)
{
/* Selects all bezier triples in each Ipocurve of the
* Ipo between times xmin and xmax, using the selection mode.
*/
IpoCurve *icu;
BeztEditFunc select_cb;
/* If the ipo is no good then return */
if (ipo == NULL)
return;
/* Set the selection function based on the
* selection mode.
*/
select_cb= ANIM_editkeyframes_select(selectmode);
if (select_cb == NULL)
return;
/* loop through all of the bezier triples in all
* of the Ipocurves -- if the triple occurs between
* times xmin and xmax then select it using the selection
* function
*/
for (icu=ipo->curve.first; icu; icu=icu->next) {
borderselect_icu_key(icu, xmin, xmax, select_cb);
}
}
void select_icu_key(BeztEditData *bed, IpoCurve *icu, float selx, short selectmode)
{
/* Selects all bezier triples in the Ipocurve
* at time selx, using the selection mode.
* This is kind of sloppy the obvious similarities
* with the above function, forgive me ...
*/
BeztEditFunc select_cb;
BezTriple *bezt;
int i;
/* If the icu is no good then return */
if (icu == NULL)
return;
/* Set the selection function based on the selection mode. */
switch (selectmode) {
case SELECT_ADD:
select_cb = select_bezier_add;
break;
case SELECT_SUBTRACT:
select_cb = select_bezier_subtract;
break;
case SELECT_INVERT:
select_cb = select_bezier_invert;
break;
default:
return;
}
/* loop through all of the bezier triples in
* the Ipocurve -- if the triple occurs at
* time selx then select it using the selection
* function
*/
for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
if (bezt->vec[1][0] == selx) {
select_cb(bed, bezt);
}
}
}
void select_ipo_key(BeztEditData *bed, Ipo *ipo, float selx, short selectmode)
{
/* Selects all bezier triples in each Ipocurve of the
* Ipo at time selx, using the selection mode.
*/
IpoCurve *icu;
BezTriple *bezt;
BeztEditFunc select_cb;
int i;
/* If the ipo is no good then return */
if (ipo == NULL)
return;
/* Set the selection function based on the
* selection mode.
*/
select_cb= ANIM_editkeyframes_select(selectmode);
if (select_cb == NULL)
return;
/* loop through all of the bezier triples in all
* of the Ipocurves -- if the triple occurs at
* time selx then select it using the selection
* function
*/
for (icu=ipo->curve.first; icu; icu=icu->next) {
for (i=0, bezt=icu->bezt; i<icu->totvert; i++, bezt++) {
if (bezt->vec[1][0] == selx) {
select_cb(bed, bezt);
}
}
}
}

View File

@@ -29,6 +29,7 @@
#ifndef ED_KEYFRAMES_EDIT_H
#define ED_KEYFRAMES_EDIT_H
struct bAnimContext;
struct Ipo;
struct IpoCurve;
struct BezTriple;
@@ -67,16 +68,19 @@ typedef enum eEditKeyframes_Select {
/* snapping tools */
typedef enum eEditKeyframes_Snap {
SNAP_KEYS_NEARFRAME = 1,
SNAP_KEYS_CURFRAME,
SNAP_KEYS_NEARMARKER,
SNAP_KEYS_CURFRAME = 1,
SNAP_KEYS_NEARFRAME,
SNAP_KEYS_NEARSEC,
SNAP_KEYS_NEARMARKER,
} eEditKeyframes_Snap;
/* mirroring tools */
//typedef enum eEditKeyframes_Mirror {
//} eEditKeyframes_Mirror;
typedef enum eEditKeyframes_Mirror {
MIRROR_KEYS_CURFRAME = 1,
MIRROR_KEYS_YAXIS,
MIRROR_KEYS_XAXIS,
MIRROR_KEYS_MARKER,
} eEditKeyframes_Mirror;
/* ************************************************ */
/* Editing API */
@@ -92,19 +96,23 @@ typedef struct BeztEditData {
int i1, i2; /* storage of times/values as 'whole' numbers */
} BeztEditData;
/* ------- Function Pointer Typedefs --------------- */
/* ------- Function Pointer Typedefs ---------------- */
/* callback function that refreshes the IPO curve after use */
typedef void (*IcuEditFunc)(struct IpoCurve *icu);
/* callback function that operates on the given BezTriple */
typedef short (*BeztEditFunc)(BeztEditData *bed, struct BezTriple *bezt);
/* ------------- Looping API ------------------- */
/* ---------------- Looping API --------------------- */
/* functions for looping over keyframes */
short icu_keys_bezier_loop(BeztEditData *bed, struct IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb);
short ipo_keys_bezier_loop(BeztEditData *bed, struct Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb);
/* ------------ BezTriple Callback Getters --------------- */
/* functions for making sure all keyframes are in good order */
void ANIM_editkeyframes_refresh(struct bAnimContext *ac);
/* ----------- BezTriple Callback Getters ---------- */
/* accessories */
BeztEditFunc ANIM_editkeyframes_ok(short mode);
@@ -120,15 +128,9 @@ BeztEditFunc ANIM_editkeyframes_ipo(short mode);
// XXX all of these funcs will be depreceated!
void select_ipo_key(BeztEditData *bed, struct Ipo *ipo, float selx, short selectmode);
void select_icu_key(BeztEditData *bed, struct IpoCurve *icu, float selx, short selectmode);
short is_ipo_key_selected(struct Ipo *ipo);
void set_ipo_key_selection(struct Ipo *ipo, short sel);
void borderselect_ipo_key(struct Ipo *ipo, float xmin, float xmax, short selectmode);
void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax, BeztEditFunc select_cb);
/* ************************************************ */

View File

@@ -1525,9 +1525,9 @@ void ED_keymap_screen(wmWindowManager *wm)
WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_CTRL, 0);
/* tests */
RNA_enum_set(WM_keymap_add_item(keymap, "SCREEN_OT_region_split", SKEY, KM_PRESS, 0, 0)->ptr, "dir", 'h');
RNA_enum_set(WM_keymap_add_item(keymap, "SCREEN_OT_region_split", SKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "dir", 'v');
RNA_enum_set(WM_keymap_add_item(keymap, "SCREEN_OT_region_split", SKEY, KM_PRESS, KM_CTRL|KM_ALT, 0)->ptr, "dir", 'h');
RNA_enum_set(WM_keymap_add_item(keymap, "SCREEN_OT_region_split", SKEY, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0)->ptr, "dir", 'v');
/*frame offsets*/
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", TIMER0, KM_ANY, KM_ANY, 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_frame_offset", UPARROWKEY, KM_PRESS, 0, 0)->ptr, "delta", 10);

View File

@@ -0,0 +1,352 @@
/**
* $Id: editaction.c 17746 2008-12-08 11:19:44Z aligorith $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Joshua Leung
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "DNA_listBase.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_constraint_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_userdef_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "BKE_action.h"
#include "BKE_depsgraph.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_material.h"
#include "BKE_object.h"
#include "BKE_context.h"
#include "BKE_utildefines.h"
#include "UI_view2d.h"
#include "ED_anim_api.h"
#include "ED_keyframing.h"
#include "ED_keyframes_draw.h"
#include "ED_keyframes_edit.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "WM_api.h"
#include "WM_types.h"
#include "action_intern.h"
/* ************************************************************************** */
/* GENERAL STUFF */
/* ************************************************************************** */
/* SETTINGS STUFF */
/* ************************************************************************** */
/* TRANSFORM STUFF */
/* ***************** Snap Current Frame Operator *********************** */
/* snap current-frame indicator to 'average time' of selected keyframe */
static int actkeys_cfrasnap_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
//ListBase anim_data= {NULL, NULL};
//bAnimListElem *ale;
//int filter;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
// FIXME... to be coded
/* set notifier tha things have changed */
ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
return OPERATOR_FINISHED;
}
void ACT_OT_keyframes_cfrasnap (wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name= "Current Frame Snap to Keys";
ot->idname= "ACT_OT_keyframes_cfrasnap";
/* api callbacks */
ot->exec= actkeys_cfrasnap_exec;
ot->poll= ED_operator_areaactive;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
}
/* ******************** Snap Keyframes Operator *********************** */
/* defines for snap keyframes tool */
EnumPropertyItem prop_actkeys_snap_types[] = {
{ACTKEYS_SNAP_CFRA, "CFRA", "Current frame", ""},
{ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", "Nearest Frame", ""}, // XXX as single entry?
{ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", "Nearest Second", ""}, // XXX as single entry?
{ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", "Nearest Marker", ""},
{0, NULL, NULL, NULL}
};
/* this function is responsible for snapping keyframes to frame-times */
static void snap_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
BeztEditData bed;
BeztEditFunc edit_cb;
/* filter data */
if (ac->datatype == ANIMCONT_GPENCIL)
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
else
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS);
ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
/* get beztriple editing callbacks */
edit_cb= ANIM_editkeyframes_snap(mode);
memset(&bed, 0, sizeof(BeztEditData));
bed.scene= ac->scene;
/* snap keyframes */
for (ale= anim_data.first; ale; ale= ale->next) {
Object *nob= ANIM_nla_mapping_get(ac, ale);
if (nob) {
ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1);
ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve);
ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1);
}
//else if (ale->type == ACTTYPE_GPLAYER)
// snap_gplayer_frames(ale->data, mode);
else
ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve);
}
BLI_freelistN(&anim_data);
}
/* ------------------- */
static int actkeys_snap_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
/* get snapping mode */
mode= RNA_enum_get(op->ptr, "type");
/* snap keyframes */
snap_action_keys(&ac, mode);
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
/* set notifier tha things have changed */
ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
return OPERATOR_FINISHED;
}
void ACT_OT_keyframes_snap (wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name= "Snap Keys";
ot->idname= "ACT_OT_keyframes_snap";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= actkeys_snap_exec;
ot->poll= ED_operator_areaactive;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
/* id-props */
prop= RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_actkeys_snap_types);
}
/* ******************** Mirror Keyframes Operator *********************** */
/* defines for snap keyframes tool */
EnumPropertyItem prop_actkeys_mirror_types[] = {
{ACTKEYS_MIRROR_CFRA, "CFRA", "Current frame", ""},
{ACTKEYS_MIRROR_YAXIS, "YAXIS", "Vertical Axis", ""},
{ACTKEYS_MIRROR_XAXIS, "XAXIS", "Horizontal Axis", ""},
{ACTKEYS_MIRROR_MARKER, "MARKER", "First Selected Marker", ""},
{0, NULL, NULL, NULL}
};
/* this function is responsible for snapping keyframes to frame-times */
static void mirror_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
BeztEditData bed;
BeztEditFunc edit_cb;
/* get beztriple editing callbacks */
edit_cb= ANIM_editkeyframes_mirror(mode);
memset(&bed, 0, sizeof(BeztEditData));
bed.scene= ac->scene;
/* for 'first selected marker' mode, need to find first selected marker first! */
// XXX should this be made into a helper func in the API?
if (mode == ACTKEYS_MIRROR_MARKER) {
Scene *scene= ac->scene;
TimeMarker *marker= NULL;
/* find first selected marker */
for (marker= scene->markers.first; marker; marker=marker->next) {
if (marker->flag & SELECT) {
break;
}
}
/* store marker's time (if available) */
if (marker)
bed.f1= marker->frame;
else
return;
}
/* filter data */
if (ac->datatype == ANIMCONT_GPENCIL)
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
else
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS);
ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
/* mirror keyframes */
for (ale= anim_data.first; ale; ale= ale->next) {
Object *nob= ANIM_nla_mapping_get(ac, ale);
if (nob) {
ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1);
ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve);
ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1);
}
//else if (ale->type == ACTTYPE_GPLAYER)
// snap_gplayer_frames(ale->data, mode);
else
ipo_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_ipocurve);
}
BLI_freelistN(&anim_data);
}
/* ------------------- */
static int actkeys_mirror_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
short mode;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
/* get snapping mode */
mode= RNA_enum_get(op->ptr, "type");
/* mirror keyframes */
mirror_action_keys(&ac, mode);
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
/* set notifier tha things have changed */
ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
return OPERATOR_FINISHED;
}
void ACT_OT_keyframes_mirror (wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name= "Mirror Keys";
ot->idname= "ACT_OT_keyframes_mirror";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= actkeys_mirror_exec;
ot->poll= ED_operator_areaactive;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
/* id-props */
prop= RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_actkeys_mirror_types);
}
/* ************************************************************************** */

View File

@@ -48,6 +48,7 @@ void action_header_buttons(const struct bContext *C, struct ARegion *ar);
/* ***************************************** */
/* action_select.c */
void ACT_OT_keyframes_deselectall(struct wmOperatorType *ot);
void ACT_OT_keyframes_borderselect(struct wmOperatorType *ot);
void ACT_OT_keyframes_columnselect(struct wmOperatorType *ot);
@@ -69,6 +70,32 @@ enum {
ACTKEYS_COLUMNSEL_MARKERS_BETWEEN,
} eActKeys_ColumnSelect_Mode;
/* ***************************************** */
/* action_edit_keyframes.c */
void ACT_OT_keyframes_snap(struct wmOperatorType *ot);
void ACT_OT_keyframes_mirror(struct wmOperatorType *ot);
/* defines for snap keyframes
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
*/
enum {
ACTKEYS_SNAP_CFRA = 1,
ACTKEYS_SNAP_NEAREST_FRAME,
ACTKEYS_SNAP_NEAREST_SECOND,
ACTKEYS_SNAP_NEAREST_MARKER,
} eActKeys_Snap_Mode;
/* defines for mirror keyframes
* NOTE: keep in sync with eEditKeyframes_Mirror (in ED_keyframes_edit.h)
*/
enum {
ACTKEYS_MIRROR_CFRA = 1,
ACTKEYS_MIRROR_YAXIS,
ACTKEYS_MIRROR_XAXIS,
ACTKEYS_MIRROR_MARKER,
} eActKeys_Mirror_Mode;
/* ***************************************** */
/* action_ops.c */
void action_operatortypes(void);

View File

@@ -62,10 +62,15 @@ void action_operatortypes(void)
/* channels */
/* keyframes */
/* selection */
WM_operatortype_append(ACT_OT_keyframes_clickselect);
WM_operatortype_append(ACT_OT_keyframes_deselectall);
WM_operatortype_append(ACT_OT_keyframes_borderselect);
WM_operatortype_append(ACT_OT_keyframes_columnselect);
/* editing */
WM_operatortype_append(ACT_OT_keyframes_snap);
WM_operatortype_append(ACT_OT_keyframes_mirror);
}
/* ************************** registration - keymaps **********************************/
@@ -79,7 +84,6 @@ static void action_keymap_keyframes (ListBase *keymap)
RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend_select", 1);
RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "left_right", ACTKEYS_LRSEL_TEST);
/* deselect all */
WM_keymap_add_item(keymap, "ACT_OT_keyframes_deselectall", AKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_deselectall", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
@@ -93,6 +97,11 @@ static void action_keymap_keyframes (ListBase *keymap)
RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_CFRA);
RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_COLUMN);
RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_BETWEEN);
/* action_edit_keyframes.c */
/* menu+1-step transform */
WM_keymap_add_item(keymap, "ACT_OT_keyframes_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ACT_OT_keyframes_mirror", MKEY, KM_PRESS, KM_SHIFT, 0);
}
/* --------------- */

View File

@@ -411,6 +411,9 @@ void ACT_OT_keyframes_deselectall (wmOperatorType *ot)
ot->exec= actkeys_deselectall_exec;
ot->poll= ED_operator_areaactive;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
/* props */
RNA_def_property(ot->srna, "invert", PROP_BOOLEAN, PROP_NONE);
}
@@ -577,6 +580,10 @@ void ACT_OT_keyframes_borderselect(wmOperatorType *ot)
ot->poll= ED_operator_areaactive;
/* flags */
// XXX er...
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
/* rna */
RNA_def_property(ot->srna, "event_type", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmin", PROP_INT, PROP_NONE);
@@ -809,6 +816,9 @@ void ACT_OT_keyframes_columnselect (wmOperatorType *ot)
ot->exec= actkeys_columnselect_exec;
ot->poll= ED_operator_areaactive;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
/* props */
prop= RNA_def_property(ot->srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_column_select_types);
@@ -1007,21 +1017,29 @@ static void selectkeys_leftright (bAnimContext *ac, short leftright, short selec
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
Scene *scene= ac->scene;
float min, max;
BeztEditFunc ok_cb, select_cb;
BeztEditData bed;
Scene *scene= ac->scene;
/* if select mode is replace, deselect all keyframes first */
if (select_mode==SELECT_REPLACE) {
select_mode=SELECT_ADD;
deselect_action_keys(ac, 0, 0);
}
/* set callbacks and editing data */
ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
select_cb= ANIM_editkeyframes_select(select_mode);
memset(&bed, 0, sizeof(BeztEditFunc));
if (leftright == ACTKEYS_LRSEL_LEFT) {
min = -MAXFRAMEF;
max = (float)(CFRA + 0.1f);
bed.f1 = -MAXFRAMEF;
bed.f2 = (float)(CFRA + 0.1f);
}
else {
min = (float)(CFRA - 0.1f);
max = MAXFRAMEF;
bed.f1 = (float)(CFRA - 0.1f);
bed.f2 = MAXFRAMEF;
}
/* filter data */
@@ -1037,13 +1055,13 @@ static void selectkeys_leftright (bAnimContext *ac, short leftright, short selec
if (nob) {
ANIM_nla_mapping_apply(nob, ale->key_data, 0, 1);
borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
ANIM_nla_mapping_apply(nob, ale->key_data, 1, 1);
}
//else if (ale->type == ANIMTYPE_GPLAYER)
// borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD);
else
borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
ipo_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
}
/* Cleanup */