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:
authorHans Goudey <HooglyBoogly>2020-10-07 13:46:58 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-10-07 13:46:58 +0300
commite584bc320a9cf6be7a16fc159bb26b5ced5572fb (patch)
tree6275e5310ce070d469095dc79da26340423a66f8 /source/blender/editors
parent4bb15c8eecbf8186a8948ced9349d54c1a8c5e33 (diff)
Fix T76595: Indicate the Active Keyframe in Graph Editortemp-fcurve-active-keyframe-D7737
Currently there is a panel that says "Active Keyframe" for numerically editing one keyframe's values, but in the code there is no concept of the "active keyframe." This patch adds an "active keyframe index" to each FCurve, and displays it with a theme color for the active vertex (which didn't exist before) if the FCurve is active. {F8536092 size=full} The active keyframe is not currently set for select operations other than basic click-select, which mirrors the behavior in the 3D view. Reviewed By: Severin, looch Maniphest Tasks: T76595 Differential Revision: https://developer.blender.org/D7737
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/keyframes_general.c3
-rw-r--r--source/blender/editors/animation/keyframing.c2
-rw-r--r--source/blender/editors/include/UI_resources.h1
-rw-r--r--source/blender/editors/interface/resources.c3
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c35
-rw-r--r--source/blender/editors/space_graph/graph_draw.c76
-rw-r--r--source/blender/editors/space_graph/graph_select.c12
7 files changed, 104 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..97a950b1ed5 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -211,6 +211,35 @@ 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 bool edit,
+ 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 +249,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, edit, pos);
immUnbindProgram();
}
@@ -270,6 +300,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 +345,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 +1288,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);
}