diff layer/TimeValueLayer.cpp @ 517:1c6439ef99d6

* "ffwd-similar" * stop when ffwding to end
author Chris Cannam
date Tue, 03 Mar 2009 21:48:03 +0000
parents ff1dc4f302bd
children e60e6fccfe4e
line wrap: on
line diff
--- a/layer/TimeValueLayer.cpp	Tue Mar 03 16:46:27 2009 +0000
+++ b/layer/TimeValueLayer.cpp	Tue Mar 03 21:48:03 2009 +0000
@@ -605,6 +605,79 @@
     return found;
 }
 
+bool
+TimeValueLayer::snapToSimilarFeature(View *v, int &frame,
+                                     size_t &resolution,
+                                     SnapType snap) const
+{
+    if (!m_model) {
+	return Layer::snapToSimilarFeature(v, frame, resolution, snap);
+    }
+
+    resolution = m_model->getResolution();
+
+    const SparseTimeValueModel::PointList &points = m_model->getPoints();
+    SparseTimeValueModel::PointList close = m_model->getPoints(frame, frame);
+
+    SparseTimeValueModel::PointList::const_iterator i;
+
+    int matchframe = frame;
+    float matchvalue = 0.f;
+
+    for (i = close.begin(); i != close.end(); ++i) {
+        if (i->frame > frame) break;
+        matchvalue = i->value;
+        matchframe = i->frame;
+    }
+
+    int snapped = frame;
+    bool found = false;
+    bool distant = false;
+    float epsilon = 0.0001;
+
+    i = close.begin();
+
+    // Scan through the close points first, then the more distant ones
+    // if no suitable close one is found
+
+    while (i != points.end()) {
+
+        if (i == close.end()) {
+            i = points.begin();
+            distant = true;
+        }
+
+	if (snap == SnapRight) {
+
+	    if (i->frame > matchframe &&
+                fabsf(i->value - matchvalue) < epsilon) {
+		snapped = i->frame;
+		found = true;
+		break;
+	    }
+
+	} else if (snap == SnapLeft) {
+
+	    if (i->frame < matchframe) {
+                if (fabsf(i->value - matchvalue) < epsilon) {
+                    snapped = i->frame;
+                    found = true; // don't break, as the next may be better
+                }
+	    } else if (found || distant) {
+		break;
+	    }
+
+	} else { 
+            // no other snap types supported
+	}
+
+        ++i;
+    }
+
+    frame = snapped;
+    return found;
+}
+
 void
 TimeValueLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const
 {