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:
authorAmélie Fondevilla <afonde>2022-06-30 16:16:05 +0300
committerSybren A. Stüvel <sybren@blender.org>2022-06-30 16:20:18 +0300
commit92d7f9ac56e0ff1e65c364487542dfb7c32a0a67 (patch)
tree3ebfbcd3dea61891613409cccdb6b996096b1203 /source/blender/editors/space_action
parent416aef4e13ccc30e82ecaa691f26af54dbd5ee7e (diff)
Animation: Add GP layers in regular Dopesheet
Grease Pencil animation channels are now also shown in the Dopesheet mode of the Dopesheet editor and in the Timeline. Grease pencil related events are now listened not only by container `SACTCONT_GPENCIL` (Grease Pencil Dopesheet), but also `SACTCONT_DOPESHEET` (main Dopesheet), and `SACTCONT_TIMELINE` (timeline). A new Animation Filter flag was added: `ANIMFILTER_FCURVESONLY`. For now this only filters out Grease Pencil Layer channels. **Implemented:** - Preview range set: now only considers selected Grease Pencil keyframes when `onlySel` parameter is true. Not only this allows the operator to work with grease pencil keyframes in main dopesheet, but it also fixes the operator in the Grease Pencil dopesheet. - Translation: allocation (and freeing) of specific memory for translation of Grease Pencil keyframes. - Copy/Paste: call to both Fcurve and GPencil operators, to allow for mixed selection. Errors are only reported when both the FCurve and GPencil functions fail to paste anything. - Keyframe Type change and Insert Keyframe: removed some code here to unify Grease Pencil dopesheet and main dopesheet code. - Jump, Snap, Mirror, Select all/box/lasso/circle, Select left/right, Clickselect: account for Grease Pencil channels within the channels loop, no need for `ANIMFILTER_FCURVESONLY` there. **Not Implemented:** - Graph-related operators. The filter `ANIMFILTER_FCURVESONLY` is naively added to all graph-related operators, meaning more-or-less all operators that used `ANIMFILTER_CURVE_VISIBLE`. - Select linked: is for F-curves channel only - Select more/less: not yet implemented for grease pencil layers. - Clean Keys, Sample, Extrapolation, Interpolation, Easing, and Handle type change: work on Fcurve-channels only, so the `ANIMFILTER_FCURVESONLY` filter is activated Graying out these operators (when no fcurve keyframe is selected) can be done with custom poll functions BUT may affect performance. This is NOT done in this patch. **Dopesheet Summary Selection:** The main summary of the dopesheet now also takes into account Grease Pencil keyframes, using some nasty copy/pasting of code, as explained [on devtalk](https://devtalk.blender.org/t/gpencil-layers-integration-in-main-dopesheet-selection-issue/24527). It works, but may be improved, providing some deeper changes. Reviewed By: mendio, pepeland, sybren Maniphest Tasks: T97477 Differential Revision: https://developer.blender.org/D15003
Diffstat (limited to 'source/blender/editors/space_action')
-rw-r--r--source/blender/editors/space_action/action_edit.c376
-rw-r--r--source/blender/editors/space_action/action_select.c222
-rw-r--r--source/blender/editors/space_action/space_action.c4
3 files changed, 310 insertions, 292 deletions
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 87a271543d1..2ac10736eea 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -158,8 +158,7 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const
/* get data to filter, from Action or Dopesheet */
/* XXX: what is sel doing here?!
* Commented it, was breaking things (eg. the "auto preview range" tool). */
- filter = (ANIMFILTER_DATA_VISIBLE |
- ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL */ /*| ANIMFILTER_CURVESONLY*/ |
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL */ |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -178,10 +177,12 @@ static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const
/* Find gp-frame which is less than or equal to current-frame. */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
- const float framenum = (float)gpf->framenum;
- *min = min_ff(*min, framenum);
- *max = max_ff(*max, framenum);
- found = true;
+ if (!onlySel || (gpf->flag & GP_FRAME_SELECT)) {
+ const float framenum = (float)gpf->framenum;
+ *min = min_ff(*min, framenum);
+ *max = max_ff(*max, framenum);
+ found = true;
+ }
}
}
else if (ale->datatype == ALE_MASKLAY) {
@@ -498,7 +499,7 @@ static short copy_action_keys(bAnimContext *ac)
ANIM_fcurves_copybuf_free();
/* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FCURVESONLY |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -511,13 +512,13 @@ static short copy_action_keys(bAnimContext *ac)
return ok;
}
-static short paste_action_keys(bAnimContext *ac,
- const eKeyPasteOffset offset_mode,
- const eKeyMergeMode merge_mode,
- bool flip)
+static eKeyPasteError paste_action_keys(bAnimContext *ac,
+ const eKeyPasteOffset offset_mode,
+ const eKeyMergeMode merge_mode,
+ bool flip)
{
ListBase anim_data = {NULL, NULL};
- int filter, ok = 0;
+ int filter;
/* filter data
* - First time we try to filter more strictly, allowing only selected channels
@@ -525,15 +526,15 @@ static short paste_action_keys(bAnimContext *ac,
* - Second time, we loosen things up if nothing was found the first time, allowing
* users to just paste keyframes back into the original curve again T31670.
*/
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) {
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
}
/* paste keyframes */
- ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
+ const eKeyPasteError ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
/* clean up */
ANIM_animdata_freelist(&anim_data);
@@ -555,7 +556,8 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op)
/* copy keyframes */
if (ac.datatype == ANIMCONT_GPENCIL) {
if (ED_gpencil_anim_copybuf_copy(&ac) == false) {
- /* Nothing got copied - An error about this should be been logged already */
+ /* check if anything ended up in the buffer */
+ BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
return OPERATOR_CANCELLED;
}
}
@@ -565,7 +567,11 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- if (copy_action_keys(&ac)) {
+ /* Both copy function needs to be evaluated to account for mixed selection */
+ const short kf_empty = copy_action_keys(&ac);
+ const bool gpf_ok = ED_gpencil_anim_copybuf_copy(&ac);
+
+ if (kf_empty && !gpf_ok) {
BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
return OPERATOR_CANCELLED;
}
@@ -597,6 +603,8 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
const bool flipped = RNA_boolean_get(op->ptr, "flipped");
+ bool gpframes_inbuf = false;
+
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0) {
return OPERATOR_CANCELLED;
@@ -608,7 +616,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
/* paste keyframes */
if (ac.datatype == ANIMCONT_GPENCIL) {
if (ED_gpencil_anim_copybuf_paste(&ac, offset_mode) == false) {
- /* An error occurred - Reports should have been fired already */
+ BKE_report(op->reports, RPT_ERROR, "No data in buffer to paste");
return OPERATOR_CANCELLED;
}
}
@@ -620,14 +628,31 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
+ /* Both paste function needs to be evaluated to account for mixed selection */
+ const eKeyPasteError kf_empty = paste_action_keys(&ac, offset_mode, merge_mode, flipped);
/* non-zero return means an error occurred while trying to paste */
- if (paste_action_keys(&ac, offset_mode, merge_mode, flipped)) {
- return OPERATOR_CANCELLED;
+ gpframes_inbuf = ED_gpencil_anim_copybuf_paste(&ac, offset_mode);
+
+ /* Only report an error if nothing was pasted, i.e. when both FCurve and GPencil failed. */
+ if (!gpframes_inbuf) {
+ switch (kf_empty) {
+ case KEYFRAME_PASTE_OK:
+ /* FCurve paste was ok, so it's all good. */
+ break;
+
+ case KEYFRAME_PASTE_NOWHERE_TO_PASTE:
+ BKE_report(op->reports, RPT_ERROR, "No selected F-Curves to paste into");
+ return OPERATOR_CANCELLED;
+
+ case KEYFRAME_PASTE_NOTHING_TO_PASTE:
+ BKE_report(op->reports, RPT_ERROR, "No data in buffer to paste");
+ return OPERATOR_CANCELLED;
+ }
}
}
/* Grease Pencil needs extra update to refresh the added keyframes. */
- if (ac.datatype == ANIMCONT_GPENCIL) {
+ if (ac.datatype == ANIMCONT_GPENCIL || gpframes_inbuf) {
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
}
/* set notifier that keyframes have changed */
@@ -697,94 +722,86 @@ static const EnumPropertyItem prop_actkeys_insertkey_types[] = {
{0, NULL, 0, NULL, NULL},
};
-/* this function is responsible for inserting new keyframes */
-static void insert_action_keys(bAnimContext *ac, short mode)
+static void insert_gpencil_key(bAnimContext *ac,
+ bAnimListElem *ale,
+ const eGP_GetFrame_Mode add_frame_mode,
+ bGPdata **gpd_old)
{
- ListBase anim_data = {NULL, NULL};
- ListBase nla_cache = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ Scene *scene = ac->scene;
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode);
+ /* Check if the gpd changes to tag only once. */
+ if (gpd != *gpd_old) {
+ BKE_gpencil_tag(gpd);
+ *gpd_old = gpd;
+ }
+}
+
+static void insert_fcurve_key(bAnimContext *ac,
+ bAnimListElem *ale,
+ const AnimationEvalContext anim_eval_context,
+ eInsertKeyFlags flag,
+ ListBase *nla_cache)
+{
+ FCurve *fcu = (FCurve *)ale->key_data;
ReportList *reports = ac->reports;
Scene *scene = ac->scene;
ToolSettings *ts = scene->toolsettings;
- eInsertKeyFlags flag;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- if (mode == 2) {
- filter |= ANIMFILTER_SEL;
- }
- else if (mode == 3) {
- filter |= ANIMFILTER_ACTGROUPED;
+ /* Read value from property the F-Curve represents, or from the curve only?
+ * - ale->id != NULL:
+ * Typically, this means that we have enough info to try resolving the path.
+ *
+ * - ale->owner != NULL:
+ * If this is set, then the path may not be resolvable from the ID alone,
+ * so it's easier for now to just read the F-Curve directly.
+ * (TODO: add the full-blown PointerRNA relative parsing case here...)
+ */
+ if (ale->id && !ale->owner) {
+ insert_keyframe(ac->bmain,
+ reports,
+ ale->id,
+ NULL,
+ ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path,
+ fcu->array_index,
+ &anim_eval_context,
+ ts->keyframe_type,
+ nla_cache,
+ flag);
}
+ else {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* Init keyframing flag. */
- flag = ANIM_get_keyframing_flags(scene, true);
-
- /* insert keyframes */
- const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph,
- (float)CFRA);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
-
- /* Read value from property the F-Curve represents, or from the curve only?
- * - ale->id != NULL:
- * Typically, this means that we have enough info to try resolving the path.
- *
- * - ale->owner != NULL:
- * If this is set, then the path may not be resolvable from the ID alone,
- * so it's easier for now to just read the F-Curve directly.
- * (TODO: add the full-blown PointerRNA relative parsing case here...)
- */
- if (ale->id && !ale->owner) {
- insert_keyframe(ac->bmain,
- reports,
- ale->id,
- NULL,
- ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path,
- fcu->array_index,
- &anim_eval_context,
- ts->keyframe_type,
- &nla_cache,
- flag);
- }
- else {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* adjust current frame for NLA-scaling */
- float cfra = anim_eval_context.eval_time;
- if (adt) {
- cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
- }
-
- const float curval = evaluate_fcurve(fcu, cfra);
- insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
+ /* adjust current frame for NLA-scaling */
+ float cfra = anim_eval_context.eval_time;
+ if (adt) {
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
- ale->update |= ANIM_UPDATE_DEFAULT;
+ const float curval = evaluate_fcurve(fcu, cfra);
+ insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
}
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ale->update |= ANIM_UPDATE_DEFAULT;
}
-/* this function is for inserting new grease pencil frames */
-static void insert_gpencil_keys(bAnimContext *ac, short mode)
+/* this function is responsible for inserting new keyframes */
+static void insert_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
+ ListBase nla_cache = {NULL, NULL};
bAnimListElem *ale;
int filter;
Scene *scene = ac->scene;
ToolSettings *ts = scene->toolsettings;
+ eInsertKeyFlags flag;
+
eGP_GetFrame_Mode add_frame_mode;
+ bGPdata *gpd_old = NULL;
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
@@ -792,30 +809,43 @@ static void insert_gpencil_keys(bAnimContext *ac, short mode)
if (mode == 2) {
filter |= ANIMFILTER_SEL;
}
+ else if (mode == 3) {
+ filter |= ANIMFILTER_ACTGROUPED;
+ }
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* add a copy or a blank frame? */
+ /* Init keyframing flag. */
+ flag = ANIM_get_keyframing_flags(scene, true);
+
+ /* GPLayers specific flags */
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
- add_frame_mode = GP_GETFRAME_ADD_COPY; /* XXX: actframe may not be what we want? */
+ add_frame_mode = GP_GETFRAME_ADD_COPY;
}
else {
add_frame_mode = GP_GETFRAME_ADD_NEW;
}
- /* Insert gp frames. */
- bGPdata *gpd_old = NULL;
+ /* insert keyframes */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph,
+ (float)CFRA);
for (ale = anim_data.first; ale; ale = ale->next) {
- bGPdata *gpd = (bGPdata *)ale->id;
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
- BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode);
- /* Check if the gpd changes to tag only once. */
- if (gpd != gpd_old) {
- BKE_gpencil_tag(gpd);
- gpd_old = gpd;
+ switch (ale->type) {
+ case ANIMTYPE_GPLAYER:
+ insert_gpencil_key(ac, ale, add_frame_mode, &gpd_old);
+ break;
+
+ case ANIMTYPE_FCURVE:
+ insert_fcurve_key(ac, ale, anim_eval_context, flag, &nla_cache);
+ break;
+
+ default:
+ BLI_assert_msg(false, "Keys cannot be inserted into this animation type.");
}
}
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
+
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
@@ -841,12 +871,7 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
mode = RNA_enum_get(op->ptr, "type");
/* insert keyframes */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- insert_gpencil_keys(&ac, mode);
- }
- else {
- insert_action_keys(&ac, mode);
- }
+ insert_action_keys(&ac, mode);
/* set notifier that keyframes have changed */
if (ac.datatype == ANIMCONT_GPENCIL) {
@@ -886,14 +911,8 @@ static bool duplicate_action_keys(bAnimContext *ac)
bool changed = false;
/* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and delete selected keys */
@@ -968,14 +987,8 @@ static bool delete_action_keys(bAnimContext *ac)
bool changed_final = false;
/* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and delete selected keys */
@@ -1063,7 +1076,7 @@ static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan)
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIMFILTER_SEL | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through filtered data and clean curves */
@@ -1139,8 +1152,8 @@ static void sample_action_keys(bAnimContext *ac)
int filter;
/* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through filtered data and add keys between selected keyframes on every frame. */
@@ -1238,7 +1251,7 @@ static void setexpo_action_keys(bAnimContext *ac, short mode)
/* filter data */
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ ANIMFILTER_SEL | ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through setting mode per F-Curve */
@@ -1352,7 +1365,8 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op)
/* set handle type */
ANIM_animdata_keyframe_callback(&ac,
(ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE |
- ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS),
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS |
+ ANIMFILTER_FCURVESONLY),
ANIM_editkeyframes_ipo(mode));
/* set notifier that keyframe properties have changed */
@@ -1401,7 +1415,8 @@ static int actkeys_easing_exec(bContext *C, wmOperator *op)
/* set handle type */
ANIM_animdata_keyframe_callback(&ac,
(ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE |
- ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS),
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS |
+ ANIMFILTER_FCURVESONLY),
ANIM_editkeyframes_easing(mode));
/* set notifier that keyframe properties have changed */
@@ -1444,8 +1459,8 @@ static void sethandles_action_keys(bAnimContext *ac, short mode)
KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
/* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_FCURVESONLY | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting flags for handles
@@ -1527,8 +1542,8 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode)
KeyframeEditFunc set_cb = ANIM_editkeyframes_keytype(mode);
/* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Loop through setting BezTriple interpolation
@@ -1536,32 +1551,19 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode)
* Currently that's not necessary here.
*/
for (ale = anim_data.first; ale; ale = ale->next) {
- ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL);
-
- ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
-}
-
-/* this function is responsible for setting the keyframe type for Grease Pencil frames */
-static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ switch (ale->type) {
+ case ANIMTYPE_GPLAYER:
+ ED_gpencil_layer_frames_keytype_set(ale->data, mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ case ANIMTYPE_FCURVE:
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL);
+ ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES;
+ break;
- /* loop through each layer */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_layer_frames_keytype_set(ale->data, mode);
- ale->update |= ANIM_UPDATE_DEPS;
+ default:
+ BLI_assert_msg(false, "Keytype cannot be set into this animation type.");
}
}
@@ -1590,12 +1592,7 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op)
mode = RNA_enum_get(op->ptr, "type");
/* set handle type */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- setkeytype_gpencil_keys(&ac, mode);
- }
- else {
- setkeytype_action_keys(&ac, mode);
- }
+ setkeytype_action_keys(&ac, mode);
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
@@ -1653,19 +1650,44 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
/* init edit data */
/* loop over action data, averaging values */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ 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) {
- AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
+ switch (ale->datatype) {
+ case ALE_GPFRAME: {
+ bGPDlayer *gpl = ale->data;
+ bGPDframe *gpf;
+
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ /* only if selected */
+ if (!(gpf->flag & GP_FRAME_SELECT)) {
+ continue;
+ }
+ /* store average time in float 1 (only do rounding at last step) */
+ ked.f1 += gpf->framenum;
+
+ /* increment number of items */
+ ked.i1++;
+ }
+ break;
+ }
+
+ case ALE_FCURVE: {
+ AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
+ }
+ break;
+ }
+
+ default:
+ BLI_assert_msg(false, "Cannot jump to keyframe into this animation type.");
}
}
@@ -1742,8 +1764,8 @@ static void snap_action_keys(bAnimContext *ac, short mode)
filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT);
}
else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
}
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -1876,14 +1898,8 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
}
/* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE |
- ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* mirror keyframes */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index aff888818e0..f5dc2104d66 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -235,13 +235,7 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
KeyframeEditFunc test_cb, sel_cb;
/* determine type-based settings */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
- ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
/* filter data */
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -416,7 +410,7 @@ static void box_select_elem(
break;
}
- if (ale->type == ANIMTYPE_SUMMARY && ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ if (ale->type == ANIMTYPE_SUMMARY) {
ListBase anim_data = {NULL, NULL};
ANIM_animdata_filter(ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac->data, ac->datatype);
@@ -428,8 +422,10 @@ static void box_select_elem(
ANIM_animdata_freelist(&anim_data);
}
- ANIM_animchannel_keyframes_loop(
- &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ ANIM_animchannel_keyframes_loop(
+ &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ }
}
}
}
@@ -658,7 +654,7 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
break;
}
- if (ale->type == ANIMTYPE_SUMMARY && ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ if (ale->type == ANIMTYPE_SUMMARY) {
ListBase anim_data = {NULL, NULL};
ANIM_animdata_filter(ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac->data, ac->datatype);
@@ -670,8 +666,10 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
ANIM_animdata_freelist(&anim_data);
}
- ANIM_animchannel_keyframes_loop(
- &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ ANIM_animchannel_keyframes_loop(
+ &sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
+ }
}
}
}
@@ -946,28 +944,36 @@ static void markers_selectkeys_between(bAnimContext *ac)
ked.f2 = max;
/* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | 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);
+ switch (ale->type) {
+ case ANIMTYPE_GPLAYER:
+ ED_gpencil_layer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- 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) {
- ED_gpencil_layer_frames_select_box(ale->data, min, max, SELECT_ADD);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frames_select_box(ale->data, min, max, SELECT_ADD);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ case ANIMTYPE_MASKLAYER:
+ ED_masklayer_frames_select_box(ale->data, min, max, SELECT_ADD);
+ break;
+
+ case ANIMTYPE_FCURVE: {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ 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 {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ break;
+ }
+
+ default:
+ BLI_assert_msg(false, "Keys cannot be selected into this animation type.");
}
}
@@ -1000,11 +1006,16 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
}
}
else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
+ 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) {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+ if (ale->datatype == ALE_GPFRAME) {
+ ED_gpencil_layer_make_cfra_list(ale->data, &ked.list, 1);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+ }
}
}
ANIM_animdata_freelist(&anim_data);
@@ -1033,12 +1044,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode)
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/);
- }
+ 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) {
@@ -1144,7 +1150,7 @@ static int actkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
}
/* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FCURVESONLY |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
@@ -1200,7 +1206,7 @@ static void select_moreless_action_keys(bAnimContext *ac, short mode)
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*/ |
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FCURVESONLY |
ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
@@ -1354,33 +1360,36 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
}
/* filter data */
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
- ANIMFILTER_NODUPLIS);
- }
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* select keys */
for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ switch (ale->type) {
+ case ANIMTYPE_GPLAYER:
+ ED_gpencil_layer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ break;
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- 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) {
- ED_gpencil_layer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
- }
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_masklayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ case ANIMTYPE_MASKLAYER:
+ ED_masklayer_frames_select_box(ale->data, ked.f1, ked.f2, select_mode);
+ break;
+
+ case ANIMTYPE_FCURVE: {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ 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 {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ break;
+ }
+
+ default:
+ BLI_assert_msg(false, "Keys cannot be selected into this animation type.");
}
}
@@ -1539,29 +1548,29 @@ static void actkeys_mselect_single(bAnimContext *ac,
ED_mask_select_frame(ale->data, selx, select_mode);
}
else {
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
- (ale->datatype == ALE_ALL)) {
+ if (ale->type == ANIMTYPE_SUMMARY && ale->datatype == ALE_ALL) {
ListBase anim_data = {NULL, NULL};
int filter;
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ 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) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->data, selx, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
+ /* Loop over all keys that are represented by this summary key. */
+ LISTBASE_FOREACH (bAnimListElem *, ale2, &anim_data) {
+ if (ale2->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frame(ale2->data, selx, select_mode);
+ ale2->update |= ANIM_UPDATE_DEPS;
}
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->data, selx, select_mode);
+ else if (ale2->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frame(ale2->data, selx, select_mode);
}
}
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
- else {
+
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
}
}
@@ -1588,35 +1597,29 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
- }
- else {
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- }
+ 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) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* set frame for validation callback to refer to */
- if (adt) {
- ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
- }
- else {
- ked.f1 = selx;
- }
-
/* select elements with frame number matching cfra */
if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frame(ale->key_data, selx, select_mode);
+ ED_gpencil_select_frame(ale->data, selx, select_mode);
ale->update |= ANIM_UPDATE_DEPS;
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frame(ale->key_data, selx, select_mode);
+ ED_mask_select_frame(ale->data, selx, select_mode);
}
else {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* set frame for validation callback to refer to */
+ if (adt) {
+ ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
+ }
+ else {
+ ked.f1 = selx;
+ }
+
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
}
}
@@ -1645,29 +1648,28 @@ static void actkeys_mselect_channel_only(bAnimContext *ac, bAnimListElem *ale, s
ED_mask_select_frames(ale->data, select_mode);
}
else {
- if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
- (ale->datatype == ALE_ALL)) {
+ if (ale->type == ANIMTYPE_SUMMARY && ale->datatype == ALE_ALL) {
ListBase anim_data = {NULL, NULL};
int filter;
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
- ANIMFILTER_NODUPLIS);
+ 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) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- ED_gpencil_select_frames(ale->data, select_mode);
- ale->update |= ANIM_UPDATE_DEPS;
+ LISTBASE_FOREACH (bAnimListElem *, ale2, &anim_data) {
+ if (ale2->type == ANIMTYPE_GPLAYER) {
+ ED_gpencil_select_frames(ale2->data, select_mode);
+ ale2->update |= ANIM_UPDATE_DEPS;
}
- else if (ale->type == ANIMTYPE_MASKLAYER) {
- ED_mask_select_frames(ale->data, select_mode);
+ else if (ale2->type == ANIMTYPE_MASKLAYER) {
+ ED_mask_select_frames(ale2->data, select_mode);
}
}
ANIM_animdata_update(ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
}
- else {
+
+ if (!ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
ANIM_animchannel_keyframes_loop(NULL, ac->ads, ale, NULL, select_cb, NULL);
}
}
@@ -1734,6 +1736,12 @@ static int mouse_action_keys(bAnimContext *ac,
fcu->flag |= FCURVE_SELECTED;
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
}
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = ale->data;
+
+ ED_gpencil_set_active_channel(gpd, gpl);
+ }
}
}
else if (ac->datatype == ANIMCONT_GPENCIL) {
@@ -1745,13 +1753,7 @@ static int mouse_action_keys(bAnimContext *ac,
bGPdata *gpd = (bGPdata *)ale->id;
bGPDlayer *gpl = ale->data;
- gpl->flag |= GP_LAYER_SELECT;
- /* Update other layer status. */
- if (BKE_gpencil_layer_active_get(gpd) != gpl) {
- BKE_gpencil_layer_active_set(gpd, gpl);
- BKE_gpencil_layer_autolock_set(gpd, false);
- WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
- }
+ ED_gpencil_set_active_channel(gpd, gpl);
}
}
else if (ac->datatype == ANIMCONT_MASK) {
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 09163842587..3e3905e5263 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -506,8 +506,8 @@ static void action_listener(const wmSpaceTypeListenerParams *params)
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- /* only handle these events in GPencil mode for performance considerations */
- if (saction->mode == SACTCONT_GPENCIL) {
+ /* only handle these events for containers in which GPencil frames are displayed */
+ if (ELEM(saction->mode, SACTCONT_GPENCIL, SACTCONT_DOPESHEET, SACTCONT_TIMELINE)) {
if (wmn->action == NA_EDITED) {
ED_area_tag_redraw(area);
}