Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_action')
-rw-r--r--source/blender/editors/space_action/action_edit_keyframes.c257
-rw-r--r--source/blender/editors/space_action/action_header.c157
-rw-r--r--source/blender/editors/space_action/action_intern.h4
-rw-r--r--source/blender/editors/space_action/action_ops.c10
-rw-r--r--source/blender/editors/space_action/action_select.c40
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,