[Bf-blender-cvs] [970be7e65ae] blender-v3.4-release: Fix T100491: Mouse selection is inaccurate in NLA Editor

Richard Antalik noreply at git.blender.org
Mon Nov 14 20:08:27 CET 2022


Commit: 970be7e65ae7fce9d58839c3c0bd65bd6dced74b
Author: Richard Antalik
Date:   Mon Nov 14 19:57:42 2022 +0100
Branches: blender-v3.4-release
https://developer.blender.org/rB970be7e65ae7fce9d58839c3c0bd65bd6dced74b

Fix T100491: Mouse selection is inaccurate in NLA Editor

Selection range is +/-7 pixels to actual clicked position, but strip selection
was biased towards rightmost strip.

To make selection more intuitive, select closest strip to clicked position, and
stop iterating when strip intersects clicked pixel.

Reviewed By: sybren

Differential Revision: https://developer.blender.org/D15728

===================================================================

M	source/blender/blenkernel/BKE_nla.h
M	source/blender/blenkernel/intern/nla.c
M	source/blender/editors/space_nla/nla_select.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 2913beee759..41980999a18 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -279,6 +279,11 @@ void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
  * Does the given NLA-strip fall within the given bounds (times)?.
  */
 bool BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
+/**
+ * Return the distance from the given frame to the NLA strip, measured in frames.
+ * If the given frame intersects the NLA strip, the distance is zero.
+ */
+float BKE_nlastrip_distance_to_frame(const struct NlaStrip *strip, float timeline_frame);
 /**
  * Recalculate the start and end frames for the current strip, after changing
  * the extents of the action or the mapping (repeats or scale factor) info.
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index c0aff204069..ad8085be3d6 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1360,6 +1360,17 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
   return true;
 }
 
+float BKE_nlastrip_distance_to_frame(const NlaStrip *strip, const float timeline_frame)
+{
+  if (timeline_frame < strip->start) {
+    return strip->start - timeline_frame;
+  }
+  if (strip->end < timeline_frame) {
+    return timeline_frame - strip->end;
+  }
+  return 0.0f;
+}
+
 /* Ensure that strip doesn't overlap those around it after resizing
  * by offsetting those which follow. */
 static void nlastrip_fix_resize_overlaps(NlaStrip *strip)
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index ce93e36474f..281782123d1 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -14,6 +14,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_math_base.h"
 
 #include "BKE_context.h"
 #include "BKE_nla.h"
@@ -286,20 +287,35 @@ static void nlaedit_strip_at_region_position(
   /* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
    * (that is the size of keyframe icons, so user should be expecting similar tolerances)
    */
-  float xmin = UI_view2d_region_to_view_x(v2d, region_x - 7);
-  float xmax = UI_view2d_region_to_view_x(v2d, region_x + 7);
+  const float mouse_x = UI_view2d_region_to_view_x(v2d, region_x);
+  const float xmin = UI_view2d_region_to_view_x(v2d, region_x - 7);
+  const float xmax = UI_view2d_region_to_view_x(v2d, region_x + 7);
 
   bAnimListElem *ale = BLI_findlink(&anim_data, channel_index);
   if (ale != NULL) {
     if (ale->type == ANIMTYPE_NLATRACK) {
       NlaTrack *nlt = (NlaTrack *)ale->data;
+      float best_distance = MAXFRAMEF;
 
       LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) {
         if (BKE_nlastrip_within_bounds(strip, xmin, xmax)) {
+          const float distance = BKE_nlastrip_distance_to_frame(strip, mouse_x);
+
+          /* Skip if strip is further away from mouse cursor than any previous strip. */
+          if (distance > best_distance) {
+            continue;
+          }
+
           *r_ale = ale;
           *r_strip = strip;
+          best_distance = distance;
 
           BLI_remlink(&anim_data, ale);
+
+          /* Mouse cursor was directly on strip, no need to check other strips. */
+          if (distance == 0.0f) {
+            break;
+          }
         }
       }
     }



More information about the Bf-blender-cvs mailing list