Fix #95855: prioritize selecting keys on active fcurve
This addresses #95855 by prioritizing the selection of keys in the following order: 1. Keys on the active curve. 2. Keys on any selected curve. 3. Other keys. Additionally, this fixes an as-yet unreported issue where you couldn't select the main vertex of a key if it was overlapping with another one and one or more of its handle vertices were already selected. This was due to the selection status of a key and its handles not being properly considered separately. Pull Request: blender/blender#107223
This commit is contained in:
@@ -143,7 +143,8 @@ static void nearest_fcurve_vert_store(ListBase *matches,
|
||||
|
||||
nvi->frame = bezt->vec[1][0]; /* currently in global time... */
|
||||
|
||||
nvi->sel = BEZT_ISSEL_ANY(bezt); /* XXX... should this use the individual verts instead? */
|
||||
/* NOTE: `hpoint` is -1,0,1, but `BEZT_ISSEL_IDX` expects 0,1,2. */
|
||||
nvi->sel = BEZT_ISSEL_IDX(bezt, hpoint + 1);
|
||||
|
||||
/* add to list of matches if appropriate... */
|
||||
if (replace == 0) {
|
||||
@@ -259,9 +260,6 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
|
||||
/* helper for find_nearest_fcurve_vert() - get the best match to use */
|
||||
static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
|
||||
{
|
||||
tNearestVertInfo *nvi = NULL;
|
||||
short found = 0;
|
||||
|
||||
/* abort if list is empty */
|
||||
if (BLI_listbase_is_empty(matches)) {
|
||||
return NULL;
|
||||
@@ -273,27 +271,49 @@ static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
|
||||
return BLI_pophead(matches);
|
||||
}
|
||||
|
||||
/* try to find the first selected F-Curve vert, then take the one after it */
|
||||
for (nvi = matches->first; nvi; nvi = nvi->next) {
|
||||
/* which mode of search are we in: find first selected, or find vert? */
|
||||
if (found) {
|
||||
/* Just take this vert now that we've found the selected one
|
||||
* - We'll need to remove this from the list
|
||||
* so that it can be returned to the original caller.
|
||||
*/
|
||||
BLI_remlink(matches, nvi);
|
||||
return nvi;
|
||||
}
|
||||
/* The goal of the remaining code below is to prioritize selecting verts on
|
||||
* selected fcurves, but to still cycle through the vertices in `matches` if
|
||||
* a selected-fcurve vertex is already selected. */
|
||||
|
||||
/* if vert is selected, we've got what we want... */
|
||||
/* Try to find the first selected vert in `matches`. Additionally, if
|
||||
* one exists, rotate `matches` to put it last in the list and the vert
|
||||
* following it first, since that's the order we'll want to scan in. */
|
||||
tNearestVertInfo *nvi_first_selected = NULL;
|
||||
LISTBASE_FOREACH (tNearestVertInfo *, nvi, matches) {
|
||||
if (nvi->sel) {
|
||||
found = 1;
|
||||
nvi_first_selected = nvi;
|
||||
BLI_listbase_rotate_last(matches, nvi_first_selected);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we're still here, this means that we failed to find anything appropriate in the first pass,
|
||||
* so just take the first item now...
|
||||
*/
|
||||
/* Try to find the next vert that's on the active fcurve, falling back
|
||||
* to the next vert on any selected fcurve if that's not found. */
|
||||
tNearestVertInfo *nvi_to_select = NULL;
|
||||
LISTBASE_FOREACH (tNearestVertInfo *, nvi, matches) {
|
||||
if (nvi == nvi_first_selected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nvi->fcu->flag & FCURVE_ACTIVE) {
|
||||
nvi_to_select = nvi;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nvi->fcu->flag & FCURVE_SELECTED && !nvi_to_select) {
|
||||
nvi_to_select = nvi;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we found a vert on a selected fcurve, return it. */
|
||||
if (nvi_to_select) {
|
||||
BLI_remlink(matches, nvi_to_select);
|
||||
return nvi_to_select;
|
||||
}
|
||||
|
||||
/* If we're still here, that means we didn't find any verts on selected
|
||||
* fcurves. So return the head (which is also the item following
|
||||
* `nvi_first_selected` if that was found). */
|
||||
return BLI_pophead(matches);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user