diff options
Diffstat (limited to 'source/blender/editors/space_action')
-rw-r--r-- | source/blender/editors/space_action/action_edit_keyframes.c | 257 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_header.c | 157 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_ops.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_select.c | 40 |
5 files changed, 436 insertions, 32 deletions
diff --git a/source/blender/editors/space_action/action_edit_keyframes.c b/source/blender/editors/space_action/action_edit_keyframes.c index 4975a2cd6de..df62de9bd83 100644 --- a/source/blender/editors/space_action/action_edit_keyframes.c +++ b/source/blender/editors/space_action/action_edit_keyframes.c @@ -89,18 +89,265 @@ /* GENERAL STUFF */ // TODO: -// - clean -// - sample // - delete // - insert key // - copy/paste +/* ******************** Delete Keyframes Operator ************************* */ + +static void delete_action_keys (bAnimContext *ac) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* 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); + + /* loop through filtered data and delete selected keys */ + for (ale= anim_data.first; ale; ale= ale->next) { + //if (ale->type == ANIMTYPE_GPLAYER) + // delete_gplayer_frames((bGPDlayer *)ale->data); + //else + delete_ipo_keys((Ipo *)ale->key_data); + } + + /* free filtered list */ + BLI_freelistN(&anim_data); +} + +/* ------------------- */ + +static int actkeys_delete_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* delete keyframes */ + delete_action_keys(&ac); + + /* 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_delete (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Keyframes"; + ot->idname= "ACT_OT_keyframes_delete"; + + /* api callbacks */ + ot->exec= actkeys_delete_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; +} + +/* ******************** Clean Keyframes Operator ************************* */ + +static void clean_action_keys (bAnimContext *ac, float thresh) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_ONLYICU); + ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); + + /* loop through filtered data and clean curves */ + for (ale= anim_data.first; ale; ale= ale->next) + clean_ipo_curve((IpoCurve *)ale->key_data, thresh); + + /* free temp data */ + BLI_freelistN(&anim_data); +} + +/* ------------------- */ + +static int actkeys_clean_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + float thresh; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + if (ac.datatype == ANIMCONT_GPENCIL) + return OPERATOR_PASS_THROUGH; + + /* get cleaning threshold */ + thresh= RNA_float_get(op->ptr, "threshold"); + + /* clean keyframes */ + clean_action_keys(&ac, thresh); + + /* 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_clean (wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Clean Keyframes"; + ot->idname= "ACT_OT_keyframes_clean"; + + /* api callbacks */ + //ot->invoke= // XXX we need that number popup for this! + ot->exec= actkeys_clean_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; + + /* properties */ + prop= RNA_def_property(ot->srna, "threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_default(prop, 0.001f); +} + +/* ******************** Sample Keyframes Operator *********************** */ + +/* little cache for values... */ +typedef struct tempFrameValCache { + float frame, val; +} tempFrameValCache; + +/* Evaluates the curves between each selected keyframe on each frame, and keys the value */ +static void sample_action_keys (bAnimContext *ac) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* filter data */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU); + ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); + + /* loop through filtered data and add keys between selected keyframes on every frame */ + for (ale= anim_data.first; ale; ale= ale->next) { + IpoCurve *icu= (IpoCurve *)ale->key_data; + BezTriple *bezt, *start=NULL, *end=NULL; + tempFrameValCache *value_cache, *fp; + int sfra, range; + int i, n; + + /* find selected keyframes... once pair has been found, add keyframes */ + for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) { + /* check if selected, and which end this is */ + if (BEZSELECTED(bezt)) { + if (start) { + /* set end */ + end= bezt; + + /* cache values then add keyframes using these values, as adding + * keyframes while sampling will affect the outcome... + */ + range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) ); + sfra= (int)( floor(start->vec[1][0]) ); + + if (range) { + value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache"); + + /* sample values */ + for (n=0, fp=value_cache; n<range && fp; n++, fp++) { + fp->frame= (float)(sfra + n); + fp->val= eval_icu(icu, fp->frame); + } + + /* add keyframes with these */ + for (n=0, fp=value_cache; n<range && fp; n++, fp++) { + insert_vert_icu(icu, fp->frame, fp->val, 1); + } + + /* free temp cache */ + MEM_freeN(value_cache); + + /* as we added keyframes, we need to compensate so that bezt is at the right place */ + bezt = icu->bezt + i + range - 1; + i += (range - 1); + } + + /* bezt was selected, so it now marks the start of a whole new chain to search */ + start= bezt; + end= NULL; + } + else { + /* just set start keyframe */ + start= bezt; + end= NULL; + } + } + } + + /* recalculate channel's handles? */ + calchandles_ipocurve(icu); + } + + /* admin and redraws */ + BLI_freelistN(&anim_data); +} + +/* ------------------- */ + +static int actkeys_sample_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + if (ac.datatype == ANIMCONT_GPENCIL) + return OPERATOR_PASS_THROUGH; + + /* sample keyframes */ + sample_action_keys(&ac); + + /* 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_sample (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Sample Keyframes"; + ot->idname= "ACT_OT_keyframes_sample"; + + /* api callbacks */ + ot->exec= actkeys_sample_exec; + ot->poll= ED_operator_areaactive; + + /* flags */ + ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/; +} + /* ************************************************************************** */ /* SETTINGS STUFF */ -// TODO: -// - wkey stuff - /* ******************** Set Extrapolation-Type Operator *********************** */ /* defines for set ipo-type for selected keyframes tool */ diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c index 04958aede0f..d04ffd0935d 100644 --- a/source/blender/editors/space_action/action_header.c +++ b/source/blender/editors/space_action/action_header.c @@ -62,14 +62,165 @@ /* ********************************************************* */ /* Menu Defines... */ -// XXX button events +/* button events */ enum { B_REDR = 0, B_ACTCOPYKEYS, B_ACTPASTEKEYS, } eActHeader_ButEvents; -// ---------------- menus +/* ------------------------------- */ +/* enums declaring constants that are used as menu event codes */ + +enum { + ACTMENU_VIEW_CENTERVIEW= 0, + ACTMENU_VIEW_AUTOUPDATE, + ACTMENU_VIEW_PLAY3D, + ACTMENU_VIEW_PLAYALL, + ACTMENU_VIEW_ALL, + ACTMENU_VIEW_MAXIMIZE, + ACTMENU_VIEW_LOCK, + ACTMENU_VIEW_SLIDERS, + ACTMENU_VIEW_NEXTMARKER, + ACTMENU_VIEW_PREVMARKER, + ACTMENU_VIEW_NEXTKEYFRAME, + ACTMENU_VIEW_PREVKEYFRAME, + ACTMENU_VIEW_TIME, + ACTMENU_VIEW_NOHIDE, + ACTMENU_VIEW_FRANUM, + ACTMENU_VIEW_TRANSDELDUPS, + ACTMENU_VIEW_HORIZOPTIMISE, + ACTMENU_VIEW_GCOLORS, + ACTMENU_VIEW_PREVRANGESET, + ACTMENU_VIEW_PREVRANGECLEAR, + ACTMENU_VIEW_PREVRANGEAUTO +}; + +enum { + ACTMENU_SEL_BORDER = 0, + ACTMENU_SEL_BORDERC, + ACTMENU_SEL_BORDERM, + ACTMENU_SEL_ALL_KEYS, + ACTMENU_SEL_ALL_CHAN, + ACTMENU_SEL_ALL_MARKERS, + ACTMENU_SEL_INVERSE_KEYS, + ACTMENU_SEL_INVERSE_MARKERS, + ACTMENU_SEL_INVERSE_CHANNELS, + ACTMENU_SEL_LEFTKEYS, + ACTMENU_SEL_RIGHTKEYS +}; + +enum { + ACTMENU_SEL_COLUMN_KEYS = 1, + ACTMENU_SEL_COLUMN_CFRA, + ACTMENU_SEL_COLUMN_MARKERSCOLUMN, + ACTMENU_SEL_COLUMN_MARKERSBETWEEN +}; + +enum { + ACTMENU_CHANNELS_OPENLEVELS = 0, + ACTMENU_CHANNELS_CLOSELEVELS, + ACTMENU_CHANNELS_EXPANDALL, + ACTMENU_CHANNELS_SHOWACHANS, + ACTMENU_CHANNELS_DELETE +}; + +enum { + ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP = 0, + ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN, + ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP, + ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM +}; + +enum { + ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE = 0, + ACTMENU_CHANNELS_GROUP_ADD_TONEW, + ACTMENU_CHANNELS_GROUP_REMOVE, + ACTMENU_CHANNELS_GROUP_SYNCPOSE +}; + +enum { + ACTMENU_CHANNELS_SETTINGS_TOGGLE = 0, + ACTMENU_CHANNELS_SETTINGS_ENABLE, + ACTMENU_CHANNELS_SETTINGS_DISABLE, +}; + +enum { + ACTMENU_KEY_DUPLICATE = 0, + ACTMENU_KEY_DELETE, + ACTMENU_KEY_CLEAN, + ACTMENU_KEY_SAMPLEKEYS, + ACTMENU_KEY_INSERTKEY +}; + +enum { + ACTMENU_KEY_TRANSFORM_MOVE = 0, + ACTMENU_KEY_TRANSFORM_SCALE, + ACTMENU_KEY_TRANSFORM_SLIDE, + ACTMENU_KEY_TRANSFORM_EXTEND +}; + +enum { + ACTMENU_KEY_HANDLE_AUTO = 0, + ACTMENU_KEY_HANDLE_ALIGN, + ACTMENU_KEY_HANDLE_FREE, + ACTMENU_KEY_HANDLE_VECTOR +}; + +enum { + ACTMENU_KEY_INTERP_CONST = 0, + ACTMENU_KEY_INTERP_LINEAR, + ACTMENU_KEY_INTERP_BEZIER +}; + +enum { + ACTMENU_KEY_EXTEND_CONST = 0, + ACTMENU_KEY_EXTEND_EXTRAPOLATION, + ACTMENU_KEY_EXTEND_CYCLIC, + ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION +}; + +enum { + ACTMENU_KEY_SNAP_NEARFRAME = 1, + ACTMENU_KEY_SNAP_CURFRAME, + ACTMENU_KEY_SNAP_NEARMARK, + ACTMENU_KEY_SNAP_NEARTIME, + ACTMENU_KEY_SNAP_CFRA2KEY, +}; + +enum { + ACTMENU_KEY_MIRROR_CURFRAME = 1, + ACTMENU_KEY_MIRROR_YAXIS, + ACTMENU_KEY_MIRROR_XAXIS, + ACTMENU_KEY_MIRROR_MARKER +}; + +enum { + ACTMENU_MARKERS_ADD = 0, + ACTMENU_MARKERS_DUPLICATE, + ACTMENU_MARKERS_DELETE, + ACTMENU_MARKERS_NAME, + ACTMENU_MARKERS_MOVE, + ACTMENU_MARKERS_LOCALADD, + ACTMENU_MARKERS_LOCALRENAME, + ACTMENU_MARKERS_LOCALDELETE, + ACTMENU_MARKERS_LOCALMOVE +}; + +/* ------------------------------- */ +/* macros for easier state testing (only for use here) */ + +/* test if active action editor is showing any markers */ +#if 0 + #define G_SACTION_HASMARKERS \ + ((G.saction->action && G.saction->action->markers.first) \ + || (G.scene->markers.first)) +#endif + +/* ------------------------------- */ + +/* *************************************************************** */ +/* menus */ /* Key menu --------------------------- */ @@ -288,7 +439,7 @@ static uiBlock *action_viewmenu(bContext *C, uiMenuBlockHandle *handle, void *ar uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); - if(curarea->headertype==HEADERTOP) { + if (curarea->headertype==HEADERTOP) { uiBlockSetDirection(block, UI_DOWN); } else { diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h index 6f51ce49888..6f0b5c9899d 100644 --- a/source/blender/editors/space_action/action_intern.h +++ b/source/blender/editors/space_action/action_intern.h @@ -73,6 +73,10 @@ enum { /* ***************************************** */ /* action_edit_keyframes.c */ +void ACT_OT_keyframes_delete(struct wmOperatorType *ot); +void ACT_OT_keyframes_clean(struct wmOperatorType *ot); +void ACT_OT_keyframes_sample(struct wmOperatorType *ot); + void ACT_OT_keyframes_handletype(struct wmOperatorType *ot); void ACT_OT_keyframes_ipotype(struct wmOperatorType *ot); void ACT_OT_keyframes_expotype(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index d6a7fda2704..cd9be252fa8 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -75,6 +75,9 @@ void action_operatortypes(void) WM_operatortype_append(ACT_OT_keyframes_handletype); WM_operatortype_append(ACT_OT_keyframes_ipotype); WM_operatortype_append(ACT_OT_keyframes_expotype); + WM_operatortype_append(ACT_OT_keyframes_sample); + WM_operatortype_append(ACT_OT_keyframes_clean); + WM_operatortype_append(ACT_OT_keyframes_delete); } /* ************************** registration - keymaps **********************************/ @@ -114,6 +117,13 @@ static void action_keymap_keyframes (ListBase *keymap) WM_keymap_add_item(keymap, "ACT_OT_keyframes_handletype", HKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ACT_OT_keyframes_ipotype", TKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "ACT_OT_keyframes_expotype", EKEY, KM_PRESS, KM_SHIFT, 0); // temp... + + /* destructive */ + WM_keymap_add_item(keymap, "ACT_OT_keyframes_clean", OKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ACT_OT_keyframes_sample", OKEY, KM_PRESS, KM_SHIFT, 0); + + WM_keymap_add_item(keymap, "ACT_OT_keyframes_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "ACT_OT_keyframes_delete", DELKEY, 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 46bf2549087..d356d7a7f42 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -88,31 +88,23 @@ /* ************************************************************************** */ /* GENERAL STUFF */ -#if 0 /* this function finds the channel that mouse is floating over */ -void *get_nearest_act_channel (short mval[], short *ret_type, void **owner) +void *get_nearest_act_channel (bAnimContext *ac, int mval[2], short *ret_type, void **owner) { - ListBase act_data = {NULL, NULL}; - bActListElem *ale; - void *data; - short datatype; + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; int filter; + View2D *v2d= &ac->ar->v2d; int clickmin, clickmax; - float x,y; + float x, y; + void *data= NULL; /* init 'owner' return val */ *owner= NULL; - /* determine what type of data we are operating on */ - data = get_action_context(&datatype); - if (data == NULL) { - *ret_type= ACTTYPE_NONE; - return NULL; - } - - areamouseco_to_ipoco(G.v2d, mval, &x, &y); - clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP)); + UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y); + clickmin = (int) ((ACHANNEL_HEIGHT_HALF - y) / (ACHANNEL_STEP)); clickmax = clickmin; if (clickmax < 0) { @@ -121,10 +113,10 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner) } /* filter data */ - filter= (ACTFILTER_FORDRAWING | ACTFILTER_VISIBLE | ACTFILTER_CHANNELS); - actdata_filter(&act_data, filter, data, datatype); + filter= (ANIMFILTER_FORDRAWING | ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS); + ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype); - for (ale= act_data.first; ale; ale= ale->next) { + for (ale= anim_data.first; ale; ale= ale->next) { if (clickmax < 0) break; if (clickmin <= 0) { @@ -133,7 +125,7 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner) data= ale->data; /* if an 'ID' has been set, this takes presidence as owner (for dopesheet) */ - if (datatype == ACTCONT_DOPESHEET) { + if (ac->datatype == ANIMCONT_DOPESHEET) { /* return pointer to ID as owner instead */ if (ale->id) *owner= ale->id; @@ -145,7 +137,7 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner) *owner= ale->owner; } - BLI_freelistN(&act_data); + BLI_freelistN(&anim_data); return data; } @@ -154,12 +146,12 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner) } /* cleanup */ - BLI_freelistN(&act_data); + BLI_freelistN(&anim_data); - *ret_type= ACTTYPE_NONE; + *ret_type= ANIMTYPE_NONE; return NULL; } -#endif + /* used only by mouse_action. It is used to find the location of the nearest * keyframe to where the mouse clicked, |