Final tweaks and removal of Film::playlist().
[dcpomatic.git] / src / wx / timeline.cc
index 6ed91e098e17b05b5961fb47b5056191806e526a..3929cf1c24d1cdb48ad5d96e96905f579be4544c 100644 (file)
@@ -64,12 +64,12 @@ Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr<Film> film)
        Bind (wxEVT_MOTION,     boost::bind (&Timeline::mouse_moved, this, _1));
        Bind (wxEVT_SIZE,       boost::bind (&Timeline::resized,     this));
 
-       playlist_changed ();
+       film_changed (Film::CONTENT);
 
        SetMinSize (wxSize (640, tracks() * track_height() + 96));
 
-       _playlist_changed_connection = film->playlist()->Changed.connect (bind (&Timeline::playlist_changed, this));
-       _playlist_content_changed_connection = film->playlist()->ContentChanged.connect (bind (&Timeline::playlist_content_changed, this, _2));
+       _film_changed_connection = film->Changed.connect (bind (&Timeline::film_changed, this, _1));
+       _film_content_changed_connection = film->ContentChanged.connect (bind (&Timeline::film_content_changed, this, _2));
 }
 
 void
@@ -90,10 +90,17 @@ Timeline::paint ()
 }
 
 void
-Timeline::playlist_changed ()
+Timeline::film_changed (Film::Property p)
+{
+       if (p == Film::CONTENT) {
+               ensure_ui_thread ();
+               recreate_views ();
+       }
+}
+
+void
+Timeline::recreate_views ()
 {
-       ensure_ui_thread ();
-       
        shared_ptr<const Film> fl = _film.lock ();
        if (!fl) {
                return;
@@ -102,13 +109,15 @@ Timeline::playlist_changed ()
        _views.clear ();
        _views.push_back (_time_axis_view);
 
-       ContentList content = fl->playlist()->content ();
+       ContentList content = fl->content ();
 
        for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
                if (dynamic_pointer_cast<VideoContent> (*i)) {
                        _views.push_back (shared_ptr<TimelineView> (new TimelineVideoContentView (*this, *i)));
                }
-               if (dynamic_pointer_cast<AudioContent> (*i)) {
+
+               shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (*i);
+               if (ac && !ac->audio_mapping().mapped_output_channels().empty ()) {
                        _views.push_back (shared_ptr<TimelineView> (new TimelineAudioContentView (*this, *i)));
                }
 
@@ -124,14 +133,19 @@ Timeline::playlist_changed ()
 }
 
 void
-Timeline::playlist_content_changed (int property)
+Timeline::film_content_changed (int property)
 {
        ensure_ui_thread ();
 
        if (property == ContentProperty::POSITION) {
                assign_tracks ();
-               setup_pixels_per_second ();
+               if (!_left_down) {
+                       /* Only do this if we are not dragging, as it's confusing otherwise */
+                       setup_pixels_per_second ();
+               }
                Refresh ();
+       } else if (property == AudioContentProperty::AUDIO_STREAMS) {
+               recreate_views ();
        }
 }
 
@@ -277,6 +291,12 @@ Timeline::left_up (wxMouseEvent& ev)
        }
 
        set_position_from_event (ev);
+
+       /* We don't do this during drag, and set_position_from_event above
+          might not have changed the position, so do it now.
+       */
+       setup_pixels_per_second ();
+       Refresh ();
 }
 
 void
@@ -303,7 +323,7 @@ Timeline::right_down (wxMouseEvent& ev)
                cv->set_selected (true);
        }
 
-       _menu.popup (_film, selected_content (), ev.GetPosition ());
+       _menu.popup (_film, selected_content (), selected_views (), ev.GetPosition ());
 }
 
 void
@@ -345,7 +365,7 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
        
        if (_snap) {
 
-               DCPTime const new_end = new_position + _down_view->content()->length_after_trim ();
+               DCPTime const new_end = new_position + _down_view->content()->length_after_trim () - DCPTime (1);
                /* Signed `distance' to nearest thing (i.e. negative is left on the timeline,
                   positive is right).
                */
@@ -354,14 +374,14 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
                /* Find the nearest content edge; this is inefficient */
                for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
                        shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
-                       if (!cv || cv == _down_view) {
+                       if (!cv || cv == _down_view || cv->content() == _down_view->content()) {
                                continue;
                        }
 
                        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);
+                       maybe_snap (cv->content()->position(), new_end + DCPTime (1), nearest_distance);
+                       maybe_snap (cv->content()->end() + DCPTime (1), new_position, nearest_distance);
+                       maybe_snap (cv->content()->end() + DCPTime (1), new_end, nearest_distance);
                }
                
                if (nearest_distance) {