diff options
author | Hans Goudey <h.goudey@me.com> | 2020-10-07 16:27:58 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2020-10-07 16:27:58 +0300 |
commit | 983ad4210b9e3dc6fe98553e686b213423e00fa1 (patch) | |
tree | 06361a54c87221515d112e94892078eced25e01f /source/blender/blenkernel | |
parent | ef235b0f172832403c5eaa2b2d510dd6f0dd8a14 (diff) |
Fix T76595: Indicate the Active Keyframe in Graph Editor
In the graph editor there is a panel that says "Active Keyframe" for
numerically editing a keyframe's values, but in the code there is no
concept of the "active keyframe." Since this is a useful concept to
have for some other features anyway, this commit adds an active
keyframe index value to FCurves. It also displays it with a theme
color for the active vertex (which didn't exist before) if the
FCurve is active.
The active keyframe in the graph editor is treated similarly to the
active vertex in the 3D view. It is the keyframe most recently selected
with a single click, and it is always selected.
For now, the only real functional change is that the active keyframe
appears in white and it should be more predictable which keyframe is
being edited in the sidebar panel.
Differential Revision: https://developer.blender.org/D7737
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_fcurve.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 32 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve_test.cc | 35 |
3 files changed, 70 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 9b6189612ba..e42d1cbbc78 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -244,6 +244,9 @@ bool BKE_fcurve_calc_bounds(struct FCurve *fcu, const bool do_sel_only, const bool include_handles); +void BKE_fcurve_active_keyframe_set(struct FCurve *fcu, const struct BezTriple *active_bezt); +int BKE_fcurve_active_keyframe_index(const struct FCurve *fcu); + /* .............. */ /* Are keyframes on F-Curve of any use (to final result, and to show in editors)? */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index d0f23221ed0..856e0e872b3 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -830,6 +830,38 @@ bool BKE_fcurve_calc_range( /** \} */ /* -------------------------------------------------------------------- */ +/** \name Active Keyframe + * \{ */ + +/** + * Set the index that stores the FCurve's active keyframe, assuming that \a active_bezt + * is already part of `fcu->bezt`. If NULL, set active keyframe index to "none." + */ +void BKE_fcurve_active_keyframe_set(FCurve *fcu, const BezTriple *active_bezt) +{ + fcu->active_keyframe_index = (active_bezt == NULL) ? FCURVE_ACTIVE_KEYFRAME_NONE : + active_bezt - fcu->bezt; +} + +/** + * Get the active keyframe index, with sanity checks for point bounds. + */ +int BKE_fcurve_active_keyframe_index(const FCurve *fcu) +{ + const int active_keyframe_index = fcu->active_keyframe_index; + + /* Sanity checks. */ + if ((fcu->bezt == NULL) || (active_keyframe_index >= fcu->totvert) || + (active_keyframe_index < 0)) { + return FCURVE_ACTIVE_KEYFRAME_NONE; + } + + return active_keyframe_index; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Status Checks * \{ */ diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc index dd672df744b..a58f519adfb 100644 --- a/source/blender/blenkernel/intern/fcurve_test.cc +++ b/source/blender/blenkernel/intern/fcurve_test.cc @@ -273,4 +273,39 @@ TEST(fcurve_subdivide, BKE_bezt_subdivide_handles) BKE_fcurve_free(fcu); } +TEST(fcurve_active_keyframe, ActiveKeyframe) +{ + FCurve *fcu = BKE_fcurve_create(); + + /* There should be no active keyframe with no points. */ + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), FCURVE_ACTIVE_KEYFRAME_NONE); + + /* Check that adding new points sets the active index. */ + EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 0); + EXPECT_EQ(insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 1); + EXPECT_EQ(insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 2); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 2); + + /* Check clearing the index. */ + BKE_fcurve_active_keyframe_set(fcu, NULL); + EXPECT_EQ(fcu->active_keyframe_index, FCURVE_ACTIVE_KEYFRAME_NONE); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), FCURVE_ACTIVE_KEYFRAME_NONE); + + /* Check a "normal" action. */ + BKE_fcurve_active_keyframe_set(fcu, &fcu->bezt[2]); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 2); + + /* Check out of bounds. */ + BKE_fcurve_active_keyframe_set(fcu, fcu->bezt - 20); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), FCURVE_ACTIVE_KEYFRAME_NONE); + + /* Check out of bounds again. */ + BKE_fcurve_active_keyframe_set(fcu, fcu->bezt + 4); + EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), FCURVE_ACTIVE_KEYFRAME_NONE); + + BKE_fcurve_free(fcu); +} + } // namespace blender::bke::tests |