From 20fb4e3367a4a544e15fa7c556868a37966356de Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 7 Feb 2010 11:50:03 +0000 Subject: DopeSheet and Graph Editors: Select More/Less Operators This commit introduces the Select More/Less Operators (Ctrl +/-) for keyframes. This works like the ones for curves, by only selecting/deselecting keyframes lying in the same F-Curve. Inter F-Curve selection is not done by this operator. That is the job for another one. This is especially useful for F-Curves set in the 0-1-0 pattern (i.e. 3 keyframes forming localised peaks), where the peaks can be selected by clicking on them individually, and immediately surrounding '0' values are selected too using "Select More". --- .../blender/editors/space_action/action_intern.h | 2 + source/blender/editors/space_action/action_ops.c | 7 ++ .../blender/editors/space_action/action_select.c | 112 +++++++++++++++++++++ 3 files changed, 121 insertions(+) (limited to 'source/blender/editors/space_action') diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index 166004a5742..cf708bb7140 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -56,6 +56,8 @@ void action_header_buttons(const struct bContext *C, struct ARegion *ar); void ACTION_OT_select_all_toggle(struct wmOperatorType *ot); void ACTION_OT_select_border(struct wmOperatorType *ot); void ACTION_OT_select_column(struct wmOperatorType *ot); +void ACTION_OT_select_more(struct wmOperatorType *ot); +void ACTION_OT_select_less(struct wmOperatorType *ot); void ACTION_OT_clickselect(struct wmOperatorType *ot); /* defines for left-right select tool */ diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index 7792247fe81..a36021553c8 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -67,6 +67,8 @@ void action_operatortypes(void) WM_operatortype_append(ACTION_OT_select_all_toggle); WM_operatortype_append(ACTION_OT_select_border); WM_operatortype_append(ACTION_OT_select_column); + WM_operatortype_append(ACTION_OT_select_more); + WM_operatortype_append(ACTION_OT_select_less); /* editing */ WM_operatortype_append(ACTION_OT_snap); @@ -122,6 +124,11 @@ static void action_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap) RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_COLUMN); RNA_enum_set(WM_keymap_add_item(keymap, "ACTION_OT_select_column", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_BETWEEN); + /* select more/less */ + WM_keymap_add_item(keymap, "ACTION_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ACTION_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + + /* action_edit.c */ /* snap - current frame to selected keys */ // TODO: maybe since this is called jump, we're better to have it on -J? diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index be74da0718e..1939057b654 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -574,6 +574,118 @@ void ACTION_OT_select_column (wmOperatorType *ot) RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", ""); } +/* ******************** 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; + + BeztEditData bed; + BeztEditFunc build_cb; + + + /* init selmap building data */ + build_cb= ANIM_editkeyframes_buildselmap(mode); + memset(&bed, 0, sizeof(BeztEditData)); + + /* loop through all of the keys and select additional keyframes based on these */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY); + 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 */ + bed.data= MEM_callocN(fcu->totvert, "selmap actEdit more"); + ANIM_fcurve_keys_bezier_loop(&bed, fcu, NULL, build_cb, NULL); + + /* based on this map, adjust the selection status of the keyframes */ + ANIM_fcurve_keys_bezier_loop(&bed, fcu, NULL, bezt_selmap_flush, NULL); + + /* free the selmap used here */ + MEM_freeN(bed.data); + bed.data= NULL; + } + + /* Cleanup */ + BLI_freelistN(&anim_data); +} + +/* ----------------- */ + +static int actkeys_select_more_exec (bContext *C, wmOperator *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_SELECT, 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 *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_SELECT, 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*/; +} + /* ******************** Mouse-Click Select Operator *********************** */ /* This operator works in one of three ways: * - 1) keyframe under mouse - no special modifiers -- cgit v1.2.3