Hand-apply 39e9f0794349f44caf440db9568b8b15eb900381 from master; snap improvements...
authorCarl Hetherington <cth@carlh.net>
Sun, 25 Jan 2015 15:35:31 +0000 (15:35 +0000)
committerCarl Hetherington <cth@carlh.net>
Sun, 25 Jan 2015 15:35:31 +0000 (15:35 +0000)
TO_PORT
src/wx/timeline.cc
src/wx/timeline.h

diff --git a/TO_PORT b/TO_PORT
index 78f09ccdee6cc1e40c5777c313334186f666d27b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
--- a/TO_PORT
+++ b/TO_PORT
@@ -1 +0,0 @@
-87521fff39a85b532f462a667bd2fb00adeb1185
index 6bce881a42013f0eba980723aca09e95e8f6505e..bd001b12e385d78ba8d7df9a363b0f8a990d0afb 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -669,6 +669,15 @@ Timeline::right_down (wxMouseEvent& ev)
        _menu.popup (_film, selected_content (), ev.GetPosition ());
 }
 
+void
+Timeline::maybe_snap (DCPTime a, DCPTime b, optional<DCPTime>& nearest_distance) const
+{
+       DCPTime const d = a - b;
+       if (!nearest_distance || d.abs() < nearest_distance.get().abs()) {
+               nearest_distance = d;
+       }
+}
+
 void
 Timeline::set_position_from_event (wxMouseEvent& ev)
 {
@@ -698,10 +707,12 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
        DCPTime new_position = _down_view_position + DCPTime::from_seconds ((p.x - _down_point.x) / pps);
        
        if (_snap) {
-               
-               bool first = true;
-               DCPTime nearest_distance = DCPTime::max ();
-               DCPTime nearest_new_position = DCPTime::max ();
+
+               DCPTime const new_end = new_position + _down_view->content()->length_after_trim ();
+               /* Signed `distance' to nearest thing (i.e. negative is left on the timeline,
+                  positive is right).
+               */
+               optional<DCPTime> nearest_distance;
                
                /* Find the nearest content edge; this is inefficient */
                for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
@@ -709,35 +720,17 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
                        if (!cv || cv == _down_view) {
                                continue;
                        }
-                       
-                       {
-                               /* Snap starts to ends */
-                               DCPTime const d = DCPTime (cv->content()->end() - new_position).abs ();
-                               if (first || d < nearest_distance) {
-                                       nearest_distance = d;
-                                       nearest_new_position = cv->content()->end() + DCPTime::delta ();
-                               }
-                       }
-                       
-                       {
-                               /* Snap ends to starts */
-                               DCPTime const d = DCPTime (
-                                       cv->content()->position() - (new_position + _down_view->content()->length_after_trim())
-                                       ).abs ();
-                               
-                               if (d < nearest_distance) {
-                                       nearest_distance = d;
-                                       nearest_new_position = cv->content()->position() - _down_view->content()->length_after_trim () - DCPTime::delta();
-                               }
-                       }
-                       
-                       first = false;
+
+                       maybe_snap (cv->content()->position(), new_position, nearest_distance);
+                       maybe_snap (cv->content()->position(), new_end, nearest_distance);
+                       maybe_snap (cv->content()->end(), new_position, nearest_distance);
+                       maybe_snap (cv->content()->end(), new_end, nearest_distance);
                }
                
-               if (!first) {
+               if (nearest_distance) {
                        /* Snap if it's close; `close' means within a proportion of the time on the timeline */
-                       if (nearest_distance < DCPTime::from_seconds ((width() / pps) / 32)) {
-                               new_position = nearest_new_position;
+                       if (nearest_distance.get().abs() < DCPTime::from_seconds ((width() / pps) / 64)) {
+                               new_position += nearest_distance.get ();
                        }
                }
        }
index 82d10afde6cc8a8337c910b8b9506c1461c96585..7595f10670bafebeb7a40830bbb1eb9ed52c998b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -91,6 +91,7 @@ private:
        boost::shared_ptr<View> event_to_view (wxMouseEvent &);
        ContentViewList selected_views () const;
        ContentList selected_content () const;
+       void maybe_snap (DCPTime a, DCPTime b, boost::optional<DCPTime>& nearest_distance) const;
 
        ContentPanel* _content_panel;
        boost::weak_ptr<Film> _film;