diff options
-rw-r--r-- | release/scripts/ui/space_dopesheet.py | 4 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_intern.h | 6 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_ops.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_select.c | 199 |
4 files changed, 156 insertions, 66 deletions
diff --git a/release/scripts/ui/space_dopesheet.py b/release/scripts/ui/space_dopesheet.py index 9a1acfd76b8..3a3f3f4033e 100644 --- a/release/scripts/ui/space_dopesheet.py +++ b/release/scripts/ui/space_dopesheet.py @@ -187,6 +187,10 @@ class DOPESHEET_MT_select(bpy.types.Menu): layout.operator("action.select_column", text="Columns on Selected Markers").mode = 'MARKERS_COLUMN' layout.operator("action.select_column", text="Between Selected Markers").mode = 'MARKERS_BETWEEN' + layout.separator() + layout.operator("action.select_leftright", text="Before Current Frame").mode = 'LEFT' + layout.operator("action.select_leftright", text="After Current Frame").mode = 'RIGHT' + # FIXME: grease pencil mode isn't supported for these yet, so skip for that mode only if context.space_data.mode != 'GPENCIL': layout.separator() diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index cc363b76479..b483a3edbdc 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -59,14 +59,14 @@ void ACTION_OT_select_column(struct wmOperatorType *ot); void ACTION_OT_select_linked(struct wmOperatorType *ot); void ACTION_OT_select_more(struct wmOperatorType *ot); void ACTION_OT_select_less(struct wmOperatorType *ot); +void ACTION_OT_select_leftright(struct wmOperatorType *ot); void ACTION_OT_clickselect(struct wmOperatorType *ot); /* defines for left-right select tool */ enum { - ACTKEYS_LRSEL_TEST = -1, - ACTKEYS_LRSEL_NONE, + ACTKEYS_LRSEL_TEST = 0, ACTKEYS_LRSEL_LEFT, - ACTKEYS_LRSEL_RIGHT, + ACTKEYS_LRSEL_RIGHT } eActKeys_LeftRightSelect_Mode; /* defines for column-select mode */ diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index ea36ce98ecb..3b448becf8b 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -58,6 +58,7 @@ void action_operatortypes(void) WM_operatortype_append(ACTION_OT_select_linked); WM_operatortype_append(ACTION_OT_select_more); WM_operatortype_append(ACTION_OT_select_less); + WM_operatortype_append(ACTION_OT_select_leftright); /* editing */ WM_operatortype_append(ACTION_OT_snap); @@ -96,8 +97,16 @@ static void action_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap) kmi= WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT|KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "extend", 1); RNA_boolean_set(kmi->ptr, "column", 1); - kmi= WM_keymap_add_item(keymap, "ACTION_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "left_right", ACTKEYS_LRSEL_TEST); + + /* select left/right */ + WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + kmi= WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", 1); + + kmi= WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", LEFTBRACKETKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_LEFT); + kmi= WM_keymap_add_item(keymap, "ACTION_OT_select_leftright", RIGHTBRACKETKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", ACTKEYS_LRSEL_RIGHT); /* deselect all */ WM_keymap_add_item(keymap, "ACTION_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 365c17d45c0..4e12833f8b8 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -705,53 +705,20 @@ void ACTION_OT_select_less (wmOperatorType *ot) 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 - * - 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 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)); - - KeyframeEditData ked= {{0}}; - 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, 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; @@ -773,13 +740,16 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short /* set callbacks and editing data */ ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE); select_cb= ANIM_editkeyframes_select(select_mode); - + + /* NOTE: we used to include FRAME_CLICK_THRESH in the tolerance for the current frame, + * but this has now been remove, since it is not so relevant anymore + */ if (leftright == ACTKEYS_LRSEL_LEFT) { ked.f1 = MINAFRAMEF; - ked.f2 = (float)(CFRA + FRAME_CLICK_THRESH); + ked.f2 = (float)(CFRA); } else { - ked.f1 = (float)(CFRA - FRAME_CLICK_THRESH); + ked.f1 = (float)(CFRA); ked.f2 = MAXFRAMEF; } @@ -790,7 +760,7 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short filter= (ANIMFILTER_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); @@ -806,7 +776,7 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short } /* Sync marker support */ - if ((select_mode==SELECT_ADD) && ELEM(leftright, ACTKEYS_LRSEL_LEFT, ACTKEYS_LRSEL_RIGHT)) { + if (select_mode==SELECT_ADD) { SpaceAction *saction= ac->sa->spacedata.first; if ((saction) && (saction->flag & SACTION_MARKERS_MOVE)) { @@ -830,6 +800,130 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short 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; + + short mval[2]; + float x; + + /* get mouse coordinates (in region coordinates) */ + mval[0]= (event->x - ar->winrct.xmin); + mval[1]= (event->y - ar->winrct.ymin); + + /* determine which side of the current frame mouse is on */ + UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, NULL); + if (x < CFRA) + RNA_int_set(op->ptr, "mode", ACTKEYS_LRSEL_LEFT); + else + RNA_int_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 keyframe "; + + /* 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) +{ + bDopeSheet *ads= (ac->datatype == ANIMCONT_DOPESHEET) ? ac->data : NULL; + int ds_filter = ((ads) ? (ads->filterflag) : (0)); + + KeyframeEditData ked= {{0}}; + 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, 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) */ +/* (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) { @@ -1089,23 +1183,8 @@ 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, mval, selectmode, column); /* set notifier that keyframe selection (and channels too) have changed */ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|ND_ANIMCHAN|NA_SELECTED, NULL); @@ -1129,8 +1208,6 @@ void ACTION_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 } |