X-Git-Url: https://git.blender.org/gitweb/gitweb.cgi/blender.git/blobdiff_plain/fa8e44556d83c2fdfd6d1e10e8611465eaf2ad59..daab78bc614fdf19d1e56558972347121e82e06e:/source/blender/editors/space_action/action_select.c diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index e358f559b14..68dd0a8c256 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -15,7 +15,7 @@ * * 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. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2008 Blender Foundation * @@ -24,67 +24,50 @@ * ***** END GPL LICENSE BLOCK ***** */ +/** \file blender/editors/space_action/action_select.c + * \ingroup spaction + */ + + #include #include #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_arithb.h" +#include "BLI_math.h" #include "BLI_dlrbTree.h" +#include "BLI_utildefines.h" #include "DNA_anim_types.h" -#include "DNA_action_types.h" -#include "DNA_armature_types.h" -#include "DNA_camera_types.h" -#include "DNA_curve_types.h" +#include "DNA_gpencil_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 "DNA_world_types.h" #include "RNA_access.h" #include "RNA_define.h" -#include "BKE_action.h" -#include "BKE_depsgraph.h" #include "BKE_fcurve.h" -#include "BKE_key.h" -#include "BKE_material.h" #include "BKE_nla.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_gpencil.h" #include "ED_keyframes_draw.h" #include "ED_keyframes_edit.h" #include "ED_markers.h" #include "ED_screen.h" -#include "ED_space_api.h" #include "WM_api.h" #include "WM_types.h" #include "action_intern.h" + /* ************************************************************************** */ /* KEYFRAMES STUFF */ @@ -99,10 +82,7 @@ * - This is called by the deselect all operator, as well as other ones! * * - test: check if select or deselect all - * - sel: how to select keyframes - * 0 = deselect - * 1 = select - * 2 = invert + * - sel: how to select keyframes (SELECT_*) */ static void deselect_action_keys (bAnimContext *ac, short test, short sel) { @@ -110,33 +90,32 @@ static void deselect_action_keys (bAnimContext *ac, short test, short sel) bAnimListElem *ale; int filter; - BeztEditData bed; - BeztEditFunc test_cb, sel_cb; + KeyframeEditData ked= {{NULL}}; + KeyframeEditFunc test_cb, sel_cb; /* determine type-based settings */ if (ac->datatype == ANIMCONT_GPENCIL) - filter= (ANIMFILTER_VISIBLE); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); /* filter data */ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* init BezTriple looping data */ - memset(&bed, 0, sizeof(BeztEditData)); test_cb= ANIM_editkeyframes_ok(BEZT_OK_SELECTED); /* See if we should be selecting or deselecting */ if (test) { for (ale= anim_data.first; ale; ale= ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { - //if (is_gplayer_frame_selected(ale->data)) { - // sel= 0; - // break; - //} + if (is_gplayer_frame_selected(ale->data)) { + sel= SELECT_SUBTRACT; + break; + } } else { - if (ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, test_cb, NULL)) { + if (ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, test_cb, NULL)) { sel= SELECT_SUBTRACT; break; } @@ -149,10 +128,10 @@ static void deselect_action_keys (bAnimContext *ac, short test, short sel) /* Now set the flags */ for (ale= anim_data.first; ale; ale= ale->next) { - //if (ale->type == ACTTYPE_GPLAYER) - // set_gplayer_frame_selection(ale->data, sel); - //else - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, sel_cb, NULL); + if (ale->type == ANIMTYPE_GPLAYER) + set_gplayer_frame_selection(ale->data, sel); + else + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL); } /* Cleanup */ @@ -176,17 +155,17 @@ static int actkeys_deselectall_exec(bContext *C, wmOperator *op) deselect_action_keys(&ac, 1, SELECT_ADD); /* set notifier that keyframe selection have changed */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT, NULL); + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); return OPERATOR_FINISHED; } -void ACT_OT_select_all_toggle (wmOperatorType *ot) +void ACTION_OT_select_all_toggle (wmOperatorType *ot) { /* identifiers */ ot->name= "Select All"; - ot->idname= "ACT_OT_select_all_toggle"; - ot->description= "Toggle selection of all keyframes."; + ot->idname= "ACTION_OT_select_all_toggle"; + ot->description= "Toggle selection of all keyframes"; /* api callbacks */ ot->exec= actkeys_deselectall_exec; @@ -196,7 +175,7 @@ void ACT_OT_select_all_toggle (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_boolean(ot->srna, "invert", 0, "Invert", ""); + ot->prop= RNA_def_boolean(ot->srna, "invert", 0, "Invert", ""); } /* ******************** Border Select Operator **************************** */ @@ -212,7 +191,7 @@ enum { ACTKEYS_BORDERSEL_ALLKEYS = 0, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_CHANNELS, -} eActKeys_BorderSelect_Mode; +} /*eActKeys_BorderSelect_Mode*/; static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short selectmode) @@ -221,8 +200,8 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short bAnimListElem *ale; int filter; - BeztEditData bed; - BeztEditFunc ok_cb, select_cb; + KeyframeEditData ked; + KeyframeEditFunc ok_cb, select_cb; View2D *v2d= &ac->ar->v2d; rctf rectf; float ymin=0, ymax=(float)(-ACHANNEL_HEIGHT_HALF); @@ -232,7 +211,7 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax-2, &rectf.xmax, &rectf.ymax); /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* get beztriple editing/validation funcs */ @@ -244,7 +223,7 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short ok_cb= NULL; /* init editing data */ - memset(&bed, 0, sizeof(BeztEditData)); + memset(&ked, 0, sizeof(KeyframeEditData)); /* loop over data, doing border select */ for (ale= anim_data.first; ale; ale= ale->next) { @@ -257,12 +236,12 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) { /* if channel is mapped in NLA, apply correction */ if (adt) { - bed.f1= BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP); - bed.f2= BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP); + ked.f1= BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP); + ked.f2= BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP); } else { - bed.f1= rectf.xmin; - bed.f2= rectf.xmax; + ked.f1= rectf.xmin; + ked.f2= rectf.xmax; } } @@ -271,20 +250,10 @@ static void borderselect_action (bAnimContext *ac, rcti rect, short mode, short !((ymax < rectf.ymin) || (ymin > rectf.ymax)) ) { /* loop over data selecting */ - if (ale->key_data) { - if (ale->datatype == ALE_FCURVE) - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - } - else if (ale->type == ANIMTYPE_GROUP) { - bActionGroup *agrp= ale->data; - FCurve *fcu; - - for (fcu= agrp->channels.first; fcu && fcu->grp==agrp; fcu= fcu->next) - ANIM_fcurve_keys_bezier_loop(&bed, fcu, ok_cb, select_cb, NULL); - } - //else if (ale->type == ANIMTYPE_GPLAYER) { - // borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode); - //} + if (ale->type == ANIMTYPE_GPLAYER) + borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode); + else + ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL); } /* set minimum extent to be the maximum of the next channel */ @@ -302,7 +271,7 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op) bAnimContext ac; rcti rect; short mode=0, selectmode=0; - int event; + int gesture_mode; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) @@ -314,8 +283,8 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op) rect.xmax= RNA_int_get(op->ptr, "xmax"); rect.ymax= RNA_int_get(op->ptr, "ymax"); - event= RNA_int_get(op->ptr, "event_type"); - if (event == LEFTMOUSE) // FIXME... hardcoded + gesture_mode= RNA_int_get(op->ptr, "gesture_mode"); + if (gesture_mode == GESTURE_MODAL_SELECT) selectmode = SELECT_ADD; else selectmode = SELECT_SUBTRACT; @@ -339,22 +308,23 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op) borderselect_action(&ac, rect, mode, selectmode); /* set notifier that keyframe selection have changed */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT, NULL); + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); return OPERATOR_FINISHED; } -void ACT_OT_select_border(wmOperatorType *ot) +void ACTION_OT_select_border(wmOperatorType *ot) { /* identifiers */ ot->name= "Border Select"; - ot->idname= "ACT_OT_select_border"; - ot->description= "Select all keyframes within the specified region."; + ot->idname= "ACTION_OT_select_border"; + ot->description= "Select all keyframes within the specified region"; /* api callbacks */ ot->invoke= WM_border_select_invoke; ot->exec= actkeys_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_action_active; @@ -362,13 +332,9 @@ void ACT_OT_select_border(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* rna */ - RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "xmin", 0, INT_MIN, INT_MAX, "X Min", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "xmax", 0, INT_MIN, INT_MAX, "X Max", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX); + WM_operator_properties_gesture_border(ot, FALSE); - RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", ""); + ot->prop= RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", ""); } /* ******************** Column Select Operator **************************** */ @@ -397,8 +363,8 @@ static void markers_selectkeys_between (bAnimContext *ac) bAnimListElem *ale; int filter; - BeztEditFunc ok_cb, select_cb; - BeztEditData bed; + KeyframeEditFunc ok_cb, select_cb; + KeyframeEditData ked= {{NULL}}; float min, max; /* get extreme markers */ @@ -409,26 +375,28 @@ static void markers_selectkeys_between (bAnimContext *ac) /* get editing funcs + data */ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE); select_cb= ANIM_editkeyframes_select(SELECT_ADD); - - memset(&bed, 0, sizeof(BeztEditData)); - bed.f1= min; - bed.f2= max; + + ked.f1= min; + ked.f2= max; /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* select keys in-between */ for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(ac, ale); - if (adt) { + if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } + else if (ale->type == ANIMTYPE_GPLAYER) { + borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD); + } else { - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } } @@ -446,28 +414,27 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) Scene *scene= ac->scene; CfraElem *ce; - BeztEditFunc select_cb, ok_cb; - BeztEditData bed; + KeyframeEditFunc select_cb, ok_cb; + KeyframeEditData ked= {{NULL}}; /* initialise keyframe editing data */ - memset(&bed, 0, sizeof(BeztEditData)); /* build list of columns */ switch (mode) { case ACTKEYS_COLUMNSEL_KEYS: /* list of selected keys */ if (ac->datatype == ANIMCONT_GPENCIL) { - filter= (ANIMFILTER_VISIBLE); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - //for (ale= anim_data.first; ale; ale= ale->next) - // gplayer_make_cfra_list(ale->data, &elems, 1); + for (ale= anim_data.first; ale; ale= ale->next) + gplayer_make_cfra_list(ale->data, &ked.list, 1); } else { - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale= anim_data.first; ale; ale= ale->next) - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_to_cfraelem, NULL); + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL); } BLI_freelistN(&anim_data); break; @@ -475,13 +442,13 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) case ACTKEYS_COLUMNSEL_CFRA: /* current frame */ /* make a single CfraElem for storing this */ ce= MEM_callocN(sizeof(CfraElem), "cfraElem"); - BLI_addtail(&bed.list, ce); + BLI_addtail(&ked.list, ce); ce->cfra= (float)CFRA; break; case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */ - ED_markers_make_cfra_list(ac->markers, &bed.list, 1); + ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT); break; default: /* invalid option */ @@ -496,44 +463,34 @@ static void columnselect_action_keys (bAnimContext *ac, short mode) * based on the keys found to be selected above */ if (ac->datatype == ANIMCONT_GPENCIL) - filter= (ANIMFILTER_VISIBLE); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(ac, ale); - /* loop over cfraelems (stored in the BeztEditData->list) + /* loop over cfraelems (stored in the KeyframeEditData->list) * - we need to do this here, as we can apply fewer NLA-mapping conversions */ - for (ce= bed.list.first; ce; ce= ce->next) { + for (ce= ked.list.first; ce; ce= ce->next) { /* set frame for validation callback to refer to */ if (adt) - bed.f1= BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP); + ked.f1= BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP); else - bed.f1= ce->cfra; + ked.f1= ce->cfra; /* select elements with frame number matching cfraelem */ - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - -#if 0 // XXX reenable when Grease Pencil stuff is back - if (ale->type == ANIMTYPE_GPLAYER) { - bGPDlayer *gpl= (bGPDlayer *)ale->data; - bGPDframe *gpf; - - for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { - if (ecfra == gpf->framenum) - gpf->flag |= GP_FRAME_SELECT; - } - } - //else... -#endif // XXX reenable when Grease Pencil stuff is back + if (ale->type == ANIMTYPE_GPLAYER) + select_gpencil_frame(ale->data, ce->cfra, SELECT_ADD); + else + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } } /* free elements */ - BLI_freelistN(&bed.list); + BLI_freelistN(&ked.list); BLI_freelistN(&anim_data); } @@ -557,17 +514,17 @@ static int actkeys_columnselect_exec(bContext *C, wmOperator *op) columnselect_action_keys(&ac, mode); /* set notifier that keyframe selection have changed */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT, NULL); + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); return OPERATOR_FINISHED; } -void ACT_OT_select_column (wmOperatorType *ot) +void ACTION_OT_select_column (wmOperatorType *ot) { /* identifiers */ ot->name= "Select All"; - ot->idname= "ACT_OT_select_column"; - ot->description= "Select all keyframes on the specified frame(s)."; + ot->idname= "ACTION_OT_select_column"; + ot->description= "Select all keyframes on the specified frame(s)"; /* api callbacks */ ot->exec= actkeys_columnselect_exec; @@ -577,61 +534,196 @@ void ACT_OT_select_column (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", ""); + ot->prop= RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", ""); } -/* ******************** Mouse-Click Select Operator *********************** */ -/* This operator works in one of three ways: - * - 1) keyframe under mouse - no special modifiers - * - 2) all keyframes on the same side of current frame indicator as mouse - ALT modifier - * - 3) column select all keyframes in frame under mouse - CTRL modifier - * - * In addition to these basic options, the SHIFT modifier can be used to toggle the - * selection mode between replacing the selection (without) and inverting the selection (with). - */ +/* ******************** Select Linked Operator *********************** */ + +static int actkeys_select_linked_exec (bContext *C, wmOperator *UNUSED(op)) +{ + bAnimContext ac; + + ListBase anim_data= {NULL, NULL}; + bAnimListElem *ale; + int filter; + + KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED); + KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* loop through all of the keys and select additional keyframes based on these */ + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale= anim_data.first; ale; ale= ale->next) { + FCurve *fcu= (FCurve *)ale->key_data; + + /* check if anything selected? */ + if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) { + /* select every keyframe in this curve then */ + ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL); + } + } + + /* Cleanup */ + BLI_freelistN(&anim_data); + + /* set notifier that keyframe selection has changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void ACTION_OT_select_linked (wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked"; + ot->idname= "ACTION_OT_select_linked"; + ot->description = "Select keyframes occurring the same F-Curves as selected ones"; + + /* api callbacks */ + ot->exec= actkeys_select_linked_exec; + ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; +} + +/* ******************** Select More/Less Operators *********************** */ + +/* Common code to perform selection */ +static void select_moreless_action_keys (bAnimContext *ac, short mode) +{ + ListBase anim_data= {NULL, NULL}; + bAnimListElem *ale; + int filter; + + KeyframeEditData ked= {{NULL}}; + KeyframeEditFunc build_cb; + + + /* init selmap building data */ + build_cb= ANIM_editkeyframes_buildselmap(mode); + + /* loop through all of the keys and select additional keyframes based on these */ + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + for (ale= anim_data.first; ale; ale= ale->next) { + FCurve *fcu= (FCurve *)ale->key_data; + + /* only continue if F-Curve has keyframes */ + if (fcu->bezt == NULL) + continue; + + /* build up map of whether F-Curve's keyframes should be selected or not */ + ked.data= MEM_callocN(fcu->totvert, "selmap actEdit more"); + ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL); + + /* based on this map, adjust the selection status of the keyframes */ + ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL); + + /* free the selmap used here */ + MEM_freeN(ked.data); + ked.data= NULL; + } + + /* Cleanup */ + BLI_freelistN(&anim_data); +} + +/* ----------------- */ + +static int actkeys_select_more_exec (bContext *C, wmOperator *UNUSED(op)) +{ + bAnimContext ac; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* perform select changes */ + select_moreless_action_keys(&ac, SELMAP_MORE); + + /* set notifier that keyframe selection has changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void ACTION_OT_select_more (wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname= "ACTION_OT_select_more"; + ot->description = "Select keyframes beside already selected ones"; + + /* api callbacks */ + ot->exec= actkeys_select_more_exec; + ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; +} + +/* ----------------- */ + +static int actkeys_select_less_exec (bContext *C, wmOperator *UNUSED(op)) +{ + bAnimContext ac; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* perform select changes */ + select_moreless_action_keys(&ac, SELMAP_LESS); + + /* set notifier that keyframe selection has changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void ACTION_OT_select_less (wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname= "ACTION_OT_select_less"; + ot->description = "Deselect keyframes on ends of selection islands"; + + /* api callbacks */ + ot->exec= actkeys_select_less_exec; + ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; +} + +/* ******************** Select Left/Right Operator ************************* */ +/* Select keyframes left/right of the current frame indicator */ /* defines for left-right select tool */ static EnumPropertyItem prop_actkeys_leftright_select_types[] = { {ACTKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""}, - {ACTKEYS_LRSEL_NONE, "OFF", 0, "Don't select", ""}, {ACTKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""}, {ACTKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""}, {0, NULL, 0, NULL, NULL} }; -/* sensitivity factor for frame-selections */ -#define FRAME_CLICK_THRESH 0.1f - -/* ------------------- */ - -/* option 1) select keyframe directly under mouse */ -static void actkeys_mselect_single (bAnimContext *ac, bAnimListElem *ale, short select_mode, float selx) -{ - bDopeSheet *ads= (ac->datatype == ANIMCONT_DOPESHEET) ? ac->data : NULL; - int ds_filter = ((ads) ? (ads->filterflag) : (0)); - - BeztEditData bed; - BeztEditFunc select_cb, ok_cb; - - /* get functions for selecting keyframes */ - select_cb= ANIM_editkeyframes_select(select_mode); - ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME); - memset(&bed, 0, sizeof(BeztEditData)); - bed.f1= selx; - - /* select the nominated keyframe on the given frame */ - ANIM_animchannel_keys_bezier_loop(&bed, ale, ok_cb, select_cb, NULL, ds_filter); -} +/* --------------------------------- */ -/* Option 2) Selects all the keyframes on either side of the current frame (depends on which side the mouse is on) */ -static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short select_mode) +static void actkeys_select_leftright (bAnimContext *ac, short leftright, short select_mode) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; - BeztEditFunc ok_cb, select_cb; - BeztEditData bed; + KeyframeEditFunc ok_cb, select_cb; + KeyframeEditData ked= {{NULL}}; Scene *scene= ac->scene; /* if select mode is replace, deselect all keyframes (and channels) first */ @@ -639,7 +731,7 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short select_mode= SELECT_ADD; /* deselect all other channels and keyframes */ - ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); deselect_action_keys(ac, 0, SELECT_SUBTRACT); } @@ -647,42 +739,177 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short 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) { - bed.f1 = MINAFRAMEF; - bed.f2 = (float)(CFRA + FRAME_CLICK_THRESH); + ked.f1 = MINAFRAMEF; + ked.f2 = (float)(CFRA + 0.1f); } else { - bed.f1 = (float)(CFRA - FRAME_CLICK_THRESH); - bed.f2 = MAXFRAMEF; + ked.f1 = (float)(CFRA - 0.1f); + ked.f2 = MAXFRAMEF; } /* filter data */ if (ac->datatype == ANIMCONT_GPENCIL) - filter= (ANIMFILTER_VISIBLE); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - /* select keys on the side where most data occurs */ + /* select keys */ for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } - //else if (ale->type == ANIMTYPE_GPLAYER) - // borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD); + else if (ale->type == ANIMTYPE_GPLAYER) + borderselect_gplayer_frames(ale->data, ked.f1, ked.f2, select_mode); else - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } + /* Sync marker support */ + if (select_mode==SELECT_ADD) { + SpaceAction *saction= (SpaceAction *)ac->sl; + + if ((saction) && (saction->flag & SACTION_MARKERS_MOVE)) { + ListBase *markers = ED_animcontext_get_markers(ac); + TimeMarker *marker; + + for (marker= markers->first; marker; marker= marker->next) { + if( ((leftright == ACTKEYS_LRSEL_LEFT) && (marker->frame < CFRA)) || + ((leftright == ACTKEYS_LRSEL_RIGHT) && (marker->frame >= CFRA)) ) + { + marker->flag |= SELECT; + } + else { + marker->flag &= ~SELECT; + } + } + } + } + /* Cleanup */ BLI_freelistN(&anim_data); } +/* ----------------- */ + +static int actkeys_select_leftright_exec (bContext *C, wmOperator *op) +{ + bAnimContext ac; + short leftright = RNA_enum_get(op->ptr, "mode"); + short selectmode; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* select mode is either replace (deselect all, then add) or add/extend */ + if (RNA_boolean_get(op->ptr, "extend")) + selectmode= SELECT_INVERT; + else + selectmode= SELECT_REPLACE; + + /* if "test" mode is set, we don't have any info to set this with */ + if (leftright == ACTKEYS_LRSEL_TEST) + return OPERATOR_CANCELLED; + + /* do the selecting now */ + actkeys_select_leftright(&ac, leftright, selectmode); + + /* set notifier that keyframe selection (and channels too) have changed */ + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|ND_ANIMCHAN|NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +static int actkeys_select_leftright_invoke (bContext *C, wmOperator *op, wmEvent *event) +{ + bAnimContext ac; + short leftright = RNA_enum_get(op->ptr, "mode"); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* handle mode-based testing */ + if (leftright == ACTKEYS_LRSEL_TEST) { + Scene *scene= ac.scene; + ARegion *ar= ac.ar; + View2D *v2d= &ar->v2d; + float x; + + /* determine which side of the current frame mouse is on */ + UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL); + if (x < CFRA) + RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_LEFT); + else + RNA_enum_set(op->ptr, "mode", ACTKEYS_LRSEL_RIGHT); + } + + /* perform selection */ + return actkeys_select_leftright_exec(C, op); +} + +void ACTION_OT_select_leftright (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select Left/Right"; + ot->idname= "ACTION_OT_select_leftright"; + ot->description= "Select keyframes to the left or the right of the current frame"; + + /* api callbacks */ + ot->invoke= actkeys_select_leftright_invoke; + ot->exec= actkeys_select_leftright_exec; + ot->poll= ED_operator_action_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* id-props */ + ot->prop= RNA_def_enum(ot->srna, "mode", prop_actkeys_leftright_select_types, ACTKEYS_LRSEL_TEST, "Mode", ""); + RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); +} + +/* ******************** Mouse-Click Select Operator *********************** */ +/* This operator works in one of three ways: + * - 1) keyframe under mouse - no special modifiers + * - 2) all keyframes on the same side of current frame indicator as mouse - ALT modifier + * - 3) column select all keyframes in frame under mouse - CTRL modifier + * + * In addition to these basic options, the SHIFT modifier can be used to toggle the + * selection mode between replacing the selection (without) and inverting the selection (with). + */ + +/* sensitivity factor for frame-selections */ +#define FRAME_CLICK_THRESH 0.1f + +/* ------------------- */ + +/* option 1) select keyframe directly under mouse */ +static void actkeys_mselect_single (bAnimContext *ac, bAnimListElem *ale, short select_mode, float selx) +{ + KeyframeEditData ked= {{NULL}}; + KeyframeEditFunc select_cb, ok_cb; + + /* get functions for selecting keyframes */ + select_cb= ANIM_editkeyframes_select(select_mode); + ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME); + ked.f1= selx; + + /* select the nominated keyframe on the given frame */ + if (ale->type == ANIMTYPE_GPLAYER) + select_gpencil_frame(ale->data, selx, select_mode); + else + ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL); +} + +/* Option 2) Selects all the keyframes on either side of the current frame (depends on which side the mouse is on) */ +/* (see actkeys_select_leftright) */ + /* Option 3) Selects all visible keyframes in the same frame as the mouse click */ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float selx) { @@ -690,11 +917,10 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se bAnimListElem *ale; int filter; - BeztEditFunc select_cb, ok_cb; - BeztEditData bed; + KeyframeEditFunc select_cb, ok_cb; + KeyframeEditData ked= {{NULL}}; /* initialise keyframe editing data */ - memset(&bed, 0, sizeof(BeztEditData)); /* set up BezTriple edit callbacks */ select_cb= ANIM_editkeyframes_select(select_mode); @@ -704,9 +930,9 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se * based on the keys found to be selected above */ if (ac->datatype == ANIMCONT_GPENCIL) - filter= (ANIMFILTER_VISIBLE); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS); else - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale= anim_data.first; ale; ale= ale->next) { @@ -714,35 +940,25 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se /* set frame for validation callback to refer to */ if (adt) - bed.f1= BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP); + ked.f1= BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP); else - bed.f1= selx; + ked.f1= selx; /* select elements with frame number matching cfra */ - ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - -#if 0 // XXX reenable when Grease Pencil stuff is back - if (ale->type == ANIMTYPE_GPLAYER) { - bGPDlayer *gpl= (bGPDlayer *)ale->data; - bGPDframe *gpf; - - for (gpf= gpl->frames.first; gpf; gpf= gpf->next) { - if (ecfra == gpf->framenum) - gpf->flag |= GP_FRAME_SELECT; - } - } - //else... -#endif // XXX reenable when Grease Pencil stuff is back + if (ale->type == ANIMTYPE_GPLAYER) + select_gpencil_frame(ale->key_data, selx, select_mode); + else + ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } /* free elements */ - BLI_freelistN(&bed.list); + BLI_freelistN(&ked.list); BLI_freelistN(&anim_data); } /* ------------------- */ -static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, short column) +static void mouse_action_keys (bAnimContext *ac, const int mval[2], short select_mode, short column) { ListBase anim_data = {NULL, NULL}; DLRBT_Tree anim_keys; @@ -770,7 +986,7 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, UI_view2d_region_to_view(v2d, mval[0]+7, mval[1], &rectf.xmax, &rectf.ymax); /* filter data */ - filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS); + filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* try to get channel */ @@ -787,11 +1003,16 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, ActKeyColumn *ak, *akn=NULL; /* make list of keyframes */ - // TODO: it would be great if we didn't have to apply this to all the keyframes to do this... BLI_dlrbTree_init(&anim_keys); if (ale->key_data) { switch (ale->datatype) { + case ALE_SCE: + { + Scene *scene= (Scene *)ale->key_data; + scene_to_keylist(ads, scene, &anim_keys, NULL); + } + break; case ALE_OB: { Object *ob= (Object *)ale->key_data; @@ -812,29 +1033,26 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, break; } } - else if (ale->type == ANIMTYPE_GROUP) { + else if (ale->type == ANIMTYPE_SUMMARY) { + /* dopesheet summary covers everything */ + summary_to_keylist(ac, &anim_keys, NULL); + } + else if (ale->type == ANIMTYPE_GROUP) { + // TODO: why don't we just give groups key_data too? bActionGroup *agrp= (bActionGroup *)ale->data; agroup_to_keylist(adt, agrp, &anim_keys, NULL); } - else if (ale->type == ANIMTYPE_GPDATABLOCK) { - /* cleanup */ - // FIXME:... - BLI_freelistN(&anim_data); - return; - } else if (ale->type == ANIMTYPE_GPLAYER) { - bGPDlayer *gpl= (bGPDlayer *)ale->data; - gpl_to_keylist(ads, gpl, &anim_keys, NULL); + // TODO: why don't we just give gplayers key_data too? + bGPDlayer *gpl = (bGPDlayer *)ale->data; + gpl_to_keylist(ads, gpl, &anim_keys); } - // the call below is not strictly necessary, since we have adjacency info anyway - //BLI_dlrbTree_linkedlist_sync(&anim_keys); - - /* loop through keyframes, finding one that was within the range clicked on */ + /* start from keyframe at root of BST, traversing until we find one within the range that was clicked on */ for (ak= anim_keys.root; ak; ak= akn) { if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) { /* set the frame to use, and apply inverse-correction for NLA-mapping - * so that the frame will get selected by the selection functiosn without + * so that the frame will get selected by the selection functions without * requiring to map each frame once again... */ selx= BKE_nla_tweakedit_remap(adt, ak->cfra, NLATIME_CONVERT_UNMAP); @@ -868,7 +1086,7 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, /* highlight channel clicked on */ if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET)) { /* deselect all other channels first */ - ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); /* Highlight Action-Group or F-Curve? */ if (ale && ale->data) { @@ -887,11 +1105,16 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, } } else if (ac->datatype == ANIMCONT_GPENCIL) { - ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + /* deselect all other channels first */ + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); - /* Highlight gpencil layer */ - //gpl->flag |= GP_LAYER_SELECT; - //gpencil_layer_setactive(gpd, gpl); + /* Highlight GPencil Layer */ + if ((ale && ale->data) && (ale->type == ANIMTYPE_GPLAYER)) { + bGPDlayer *gpl = ale->data; + + gpl->flag |= GP_LAYER_SELECT; + //gpencil_layer_setactive(gpd, gpl); + } } } @@ -899,11 +1122,7 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, if (ale) { if (found) { /* apply selection to keyframes */ - if (/*gpl*/0) { - /* grease pencil */ - //select_gpencil_frame(gpl, (int)selx, selectmode); - } - else if (column) { + if (column) { /* select all keyframes in the same frame as the one we hit on the active channel */ actkeys_mselect_column(ac, select_mode, selx); } @@ -922,25 +1141,16 @@ static void mouse_action_keys (bAnimContext *ac, int mval[2], short select_mode, static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event) { bAnimContext ac; - Scene *scene; ARegion *ar; - View2D *v2d; short selectmode, column; - int mval[2]; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; /* get useful pointers from animation context data */ - scene= ac.scene; ar= ac.ar; - v2d= &ar->v2d; - - /* get mouse coordinates (in region coordinates) */ - mval[0]= (event->x - ar->winrct.xmin); - mval[1]= (event->y - ar->winrct.ymin); - + /* select mode is either replace (deselect all, then add) or add/extend */ if (RNA_boolean_get(op->ptr, "extend")) selectmode= SELECT_INVERT; @@ -950,37 +1160,22 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even /* column selection */ column= RNA_boolean_get(op->ptr, "column"); - /* figure out action to take */ - if (RNA_enum_get(op->ptr, "left_right")) { - /* select all keys on same side of current frame as mouse */ - float x; - - UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, NULL); - if (x < CFRA) - RNA_int_set(op->ptr, "left_right", ACTKEYS_LRSEL_LEFT); - else - RNA_int_set(op->ptr, "left_right", ACTKEYS_LRSEL_RIGHT); - - actkeys_mselect_leftright(&ac, RNA_enum_get(op->ptr, "left_right"), selectmode); - } - else { - /* select keyframe(s) based upon mouse position*/ - mouse_action_keys(&ac, mval, selectmode, column); - } + /* select keyframe(s) based upon mouse position*/ + mouse_action_keys(&ac, event->mval, selectmode, column); /* set notifier that keyframe selection (and channels too) have changed */ - WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT|ND_ANIMCHAN_SELECT, NULL); + WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|ND_ANIMCHAN|NA_SELECTED, NULL); /* for tweak grab to work */ return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH; } -void ACT_OT_clickselect (wmOperatorType *ot) +void ACTION_OT_clickselect (wmOperatorType *ot) { /* identifiers */ ot->name= "Mouse Select Keys"; - ot->idname= "ACT_OT_clickselect"; - ot->description= "Select keyframes by clicking on them."; + ot->idname= "ACTION_OT_clickselect"; + ot->description= "Select keyframes by clicking on them"; /* api callbacks - absolutely no exec() this yet... */ ot->invoke= actkeys_clickselect_invoke; @@ -990,8 +1185,6 @@ void ACT_OT_clickselect (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* id-props */ - // XXX should we make this into separate operators? - RNA_def_enum(ot->srna, "left_right", prop_actkeys_leftright_select_types, 0, "Left Right", ""); // CTRLKEY RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY RNA_def_boolean(ot->srna, "column", 0, "Column Select", ""); // ALTKEY }