diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/animation/keyframes_general.c | 3 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 2 | ||||
-rw-r--r-- | source/blender/editors/include/UI_resources.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/resources.c | 3 | ||||
-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 |
7 files changed, 101 insertions, 28 deletions
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index ea032446fc6..0bec20c739e 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -117,6 +117,9 @@ bool delete_fcurve_keys(FCurve *fcu) /* Delete selected BezTriples */ for (int i = 0; i < fcu->totvert; i++) { if (fcu->bezt[i].f2 & SELECT) { + if (i == fcu->active_keyframe_index) { + BKE_fcurve_active_keyframe_set(fcu, NULL); + } memmove(&fcu->bezt[i], &fcu->bezt[i + 1], sizeof(BezTriple) * (fcu->totvert - i - 1)); fcu->totvert--; i--; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index ed3e236fed3..e4b73ea65a0 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -606,6 +606,8 @@ int insert_vert_fcurve( /* add temp beztriple to keyframes */ a = insert_bezt_fcurve(fcu, &beztr, flag); + fcu->active_keyframe_index = a; + /* what if 'a' is a negative index? * for now, just exit to prevent any segfaults */ diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 31cb62117c5..a7b87d38472 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -92,6 +92,7 @@ typedef enum ThemeColorID { TH_TRANSFORM, TH_VERTEX, TH_VERTEX_SELECT, + TH_VERTEX_ACTIVE, TH_VERTEX_UNREFERENCED, TH_VERTEX_SIZE, TH_OUTLINE_WIDTH, diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index ec6f99f167d..e55f84916b3 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -362,6 +362,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) case TH_VERTEX_SELECT: cp = ts->vertex_select; break; + case TH_VERTEX_ACTIVE: + cp = ts->vertex_active; + break; case TH_VERTEX_BEVEL: cp = ts->vertex_bevel; break; 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); } |