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/editors/space_graph | |
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/editors/space_graph')
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 35 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_draw.c | 73 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_select.c | 12 |
3 files changed, 92 insertions, 28 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 45c43a5853d..bbdca5280d4 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -235,40 +235,27 @@ static void graph_panel_properties(const bContext *C, Panel *panel) /* ******************* active Keyframe ************** */ /* get 'active' keyframe for panel editing */ -static bool get_active_fcurve_keyframe_edit(FCurve *fcu, +static bool get_active_fcurve_keyframe_edit(const FCurve *fcu, BezTriple **r_bezt, BezTriple **r_prevbezt) { - BezTriple *b; - int i; - /* zero the pointers */ *r_bezt = *r_prevbezt = NULL; - /* sanity checks */ - if ((fcu->bezt == NULL) || (fcu->totvert == 0)) { + const int active_keyframe_index = BKE_fcurve_active_keyframe_index(fcu); + if (active_keyframe_index == FCURVE_ACTIVE_KEYFRAME_NONE) { return false; } - /* find first selected keyframe for now, and call it the active one - * - this is a reasonable assumption, given that whenever anyone - * wants to edit numerically, there is likely to only be 1 vert selected - */ - for (i = 0, b = fcu->bezt; i < fcu->totvert; i++, b++) { - if (BEZT_ISSEL_ANY(b)) { - /* found - * - 'previous' is either the one before, of the keyframe itself (which is still fine) - * XXX: we can just make this null instead if needed - */ - *r_prevbezt = (i > 0) ? b - 1 : b; - *r_bezt = b; - - return true; - } - } + /* The active keyframe should be selected. */ + BLI_assert(BEZT_ISSEL_ANY(&fcu->bezt[active_keyframe_index])); + + *r_bezt = &fcu->bezt[active_keyframe_index]; + /* Previous is either one before the active, or the point itself if it's the first. */ + const int prev_index = max_ii(active_keyframe_index - 1, 0); + *r_prevbezt = &fcu->bezt[prev_index]; - /* not found */ - return false; + return true; } /* update callback for active keyframe properties - base updates stuff */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index af7a7d9a4de..c6acc8260b7 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -211,6 +211,32 @@ static void draw_fcurve_selected_keyframe_vertices( immEnd(); } +/** + * Draw the extra indicator for the active point. + */ +static void draw_fcurve_active_vertex(const FCurve *fcu, const View2D *v2d, const uint pos) +{ + const int active_keyframe_index = BKE_fcurve_active_keyframe_index(fcu); + if (!(fcu->flag & FCURVE_ACTIVE) || active_keyframe_index == FCURVE_ACTIVE_KEYFRAME_NONE) { + return; + } + + const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur); + const BezTriple *bezt = &fcu->bezt[active_keyframe_index]; + + if (!IN_RANGE(bezt->vec[1][0], (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) { + return; + } + if (!(bezt->f2 & SELECT)) { + return; + } + + immBegin(GPU_PRIM_POINTS, 1); + immUniformThemeColor(TH_VERTEX_ACTIVE); + immVertex2fv(pos, bezt->vec[1]); + immEnd(); +} + /* helper func - draw keyframe vertices only for an F-Curve */ static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, uint pos) { @@ -220,6 +246,7 @@ static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, u draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, false, pos); draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, true, pos); + draw_fcurve_active_vertex(fcu, v2d, pos); immUnbindProgram(); } @@ -270,6 +297,39 @@ static void draw_fcurve_selected_handle_vertices( immEnd(); } +/** + * Draw the extra handles for the active point. + */ +static void draw_fcurve_active_handle_vertices(const FCurve *fcu, + const bool sel_handle_only, + const uint pos) +{ + const int active_keyframe_index = BKE_fcurve_active_keyframe_index(fcu); + if (!(fcu->flag & FCURVE_ACTIVE) || active_keyframe_index == FCURVE_ACTIVE_KEYFRAME_NONE) { + return; + } + + const BezTriple *bezt = &fcu->bezt[active_keyframe_index]; + + if (sel_handle_only && !BEZT_ISSEL_ANY(bezt)) { + return; + } + + float active_col[4]; + UI_GetThemeColor4fv(TH_VERTEX_ACTIVE, active_col); + immUniform4fv("outlineColor", active_col); + immUniformColor3fvAlpha(active_col, 0.01f); /* Almost invisible - only keep for smoothness. */ + immBeginAtMost(GPU_PRIM_POINTS, 2); + + if ((bezt->f1 & SELECT)) { + immVertex2fv(pos, bezt->vec[0]); + } + if ((bezt->f3 & SELECT)) { + immVertex2fv(pos, bezt->vec[2]); + } + immEnd(); +} + /* helper func - draw handle vertices only for an F-Curve (if it is not protected) */ static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handle_only, uint pos) { @@ -282,6 +342,7 @@ static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handl draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos); draw_fcurve_selected_handle_vertices(fcu, v2d, true, sel_handle_only, pos); + draw_fcurve_active_handle_vertices(fcu, sel_handle_only, pos); immUnbindProgram(); } @@ -1224,10 +1285,22 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor * draw curve, then handle-lines, and finally vertices in this order so that * the data will be layered correctly */ + bAnimListElem *ale_active_fcurve = NULL; for (ale = anim_data.first; ale; ale = ale->next) { + const FCurve *fcu = (FCurve *)ale->key_data; + if (fcu->flag & FCURVE_ACTIVE) { + ale_active_fcurve = ale; + continue; + } draw_fcurve(ac, sipo, region, ale); } + /* Draw the active FCurve last so that it (especially the active keyframe) + * shows on top of the other curves. */ + if (ale_active_fcurve != NULL) { + draw_fcurve(ac, sipo, region, ale_active_fcurve); + } + /* free list of curves */ ANIM_animdata_freelist(&anim_data); } diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 0c05942ec4b..433d7d6774b 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -1485,7 +1485,6 @@ static int mouse_graph_keys(bAnimContext *ac, /* only if there's keyframe */ if (nvi->bezt) { bezt = nvi->bezt; /* Used to check `bezt` selection is set. */ - /* depends on selection mode */ if (select_mode == SELECT_INVERT) { if (nvi->hpoint == NEAREST_HANDLE_KEY) { bezt->f2 ^= SELECT; @@ -1510,6 +1509,10 @@ static int mouse_graph_keys(bAnimContext *ac, bezt->f3 |= SELECT; } } + + if (!run_modal && BEZT_ISSEL_ANY(bezt) && !already_selected) { + BKE_fcurve_active_keyframe_set(nvi->fcu, bezt); + } } else if (nvi->fpt) { // TODO: need to handle sample points @@ -1555,10 +1558,11 @@ static int mouse_graph_keys(bAnimContext *ac, } } - /* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */ - /* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) + /* Set active F-Curve, except when dragging the selected keys. + * needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) * otherwise the active flag won't be set T26452. */ - if (nvi->fcu->flag & FCURVE_SELECTED) { + if (!run_modal && nvi->fcu->flag & FCURVE_SELECTED) { + /* NOTE: Sync the filter flags with findnearest_fcurve_vert. */ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype); } |