changeset 517:1c6439ef99d6

* "ffwd-similar" * stop when ffwding to end
author Chris Cannam
date Tue, 03 Mar 2009 21:48:03 +0000
parents e4e0ae491a48
children fe134ec37a2a
files layer/Layer.h layer/TimeValueLayer.cpp layer/TimeValueLayer.h
diffstat 3 files changed, 102 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Layer.h	Tue Mar 03 16:46:27 2009 +0000
+++ b/layer/Layer.h	Tue Mar 03 21:48:03 2009 +0000
@@ -166,8 +166,8 @@
      *
      * Return true if a suitable feature was found and frame adjusted
      * accordingly.  Return false if no suitable feature was available
-     * (and leave frame unmodified).  Also return the resolution of
-     * the model in this layer in sample frames.
+     * (and leave frame unmodified).  If returning true, also return
+     * the resolution of the model in this layer in sample frames.
      */
     virtual bool snapToFeatureFrame(View *   /* v */,
 				    int &    /* frame */,
@@ -177,6 +177,30 @@
 	return false;
     }
 
+    /**
+     * Adjust the given frame to snap to the next feature that has
+     * "effectively" the same value as the feature prior to the given
+     * frame, if possible.
+     *
+     * The snap type must be SnapLeft (snap to the time of the next
+     * feature prior to the one preceding the given frame that has a
+     * similar value to it) or SnapRight (snap to the time of the next
+     * feature following the given frame that has a similar value to
+     * the feature preceding it).  Other values are not permitted.
+     *
+     * Return true if a suitable feature was found and frame adjusted
+     * accordingly.  Return false if no suitable feature was available
+     * (and leave frame unmodified).  If returning true, also return
+     * the resolution of the model in this layer in sample frames.
+     */
+    virtual bool snapToSimilarFeature(View *   /* v */,
+                                      int &    /* source frame */,
+                                      size_t &resolution,
+                                      SnapType /* snap */) const {
+	resolution = 1;
+	return false;
+    }
+
     // Draw, erase, and edit modes:
     //
     // Layer needs to get actual mouse events, I guess.  Draw mode is
--- 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
 {
--- a/layer/TimeValueLayer.h	Tue Mar 03 16:46:27 2009 +0000
+++ b/layer/TimeValueLayer.h	Tue Mar 03 21:48:03 2009 +0000
@@ -42,6 +42,9 @@
     virtual bool snapToFeatureFrame(View *v, int &frame,
 				    size_t &resolution,
 				    SnapType snap) const;
+    virtual bool snapToSimilarFeature(View *v, int &frame,
+                                      size_t &resolution,
+                                      SnapType snap) const;
 
     virtual void drawStart(View *v, QMouseEvent *);
     virtual void drawDrag(View *v, QMouseEvent *);