Fix time axis view position.
[dcpomatic.git] / src / wx / timeline.cc
index 8c90c3d8c1aa33768a70a93449f507c4f3efd079..902788bc9efab0fe8867a54ca3633a2d246c529f 100644 (file)
 #include <wx/graphics.h>
 #include <boost/weak_ptr.hpp>
 #include "film.h"
+#include "film_editor.h"
 #include "timeline.h"
 #include "wx_util.h"
-#include "playlist.h"
+#include "lib/playlist.h"
 
 using std::list;
 using std::cout;
@@ -111,6 +112,14 @@ public:
                return _content;
        }
 
+       void set_track (int t) {
+               _track = t;
+       }
+
+       int track () const {
+               return _track;
+       }
+
        virtual wxString type () const = 0;
        virtual wxColour colour () const = 0;
        
@@ -175,7 +184,7 @@ private:
 
        void content_changed (int p)
        {
-               if (p == ContentProperty::START || p == VideoContentProperty::VIDEO_LENGTH) {
+               if (p == ContentProperty::START || p == ContentProperty::LENGTH) {
                        force_redraw ();
                }
        }
@@ -233,6 +242,19 @@ public:
                : View (tl)
                , _y (y)
        {}
+       
+       Rect bbox () const
+       {
+               return Rect (0, _y - 4, _timeline.width(), 24);
+       }
+
+       void set_y (int y)
+       {
+               _y = y;
+               force_redraw ();
+       }
+
+private:       
 
        void do_paint (wxGraphicsContext* gc)
        {
@@ -295,18 +317,16 @@ public:
                }
        }
 
-       Rect bbox () const
-       {
-               return Rect (0, _y - 4, _timeline.width(), 24);
-       }
-
 private:
        int _y;
 };
 
-Timeline::Timeline (wxWindow* parent, shared_ptr<const Film> film)
+Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr<Film> film)
        : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
+       , _film_editor (ed)
        , _film (film)
+       , _time_axis_view (new TimeAxisView (*this, 32))
+       , _tracks (0)
        , _pixels_per_time_unit (0)
        , _left_down (false)
        , _down_view_start (0)
@@ -322,11 +342,13 @@ Timeline::Timeline (wxWindow* parent, shared_ptr<const Film> film)
        Connect (wxID_ANY, wxEVT_MOTION, wxMouseEventHandler (Timeline::mouse_moved), 0, this);
        Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (Timeline::resized), 0, this);
 
-       SetMinSize (wxSize (640, tracks() * track_height() + 96));
-
        playlist_changed ();
 
+       SetMinSize (wxSize (640, tracks() * track_height() + 96));
+
        _playlist_connection = film->playlist()->Changed.connect (bind (&Timeline::playlist_changed, this));
+
+       _views.push_back (_time_axis_view);
 }
 
 void
@@ -365,20 +387,76 @@ Timeline::playlist_changed ()
                        _views.push_back (shared_ptr<View> (new VideoContentView (*this, *i, 0)));
                }
                if (dynamic_pointer_cast<AudioContent> (*i)) {
-                       _views.push_back (shared_ptr<View> (new AudioContentView (*this, *i, 1)));
+                       _views.push_back (shared_ptr<View> (new AudioContentView (*this, *i, 0)));
                }
        }
 
-       _views.push_back (shared_ptr<View> (new TimeAxisView (*this, tracks() * track_height() + 32)));
-               
+       assign_tracks ();
        Refresh ();
 }
 
+void
+Timeline::assign_tracks ()
+{
+       for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+               if (cv) {
+                       cv->set_track (0);
+                       _tracks = 1;
+               }
+       }
+
+       for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<AudioContentView> acv = dynamic_pointer_cast<AudioContentView> (*i);
+               if (!acv) {
+                       continue;
+               }
+       
+               shared_ptr<Content> acv_content = acv->content().lock ();
+               assert (acv_content);
+               
+               int t = 1;
+               while (1) {
+                       list<shared_ptr<View> >::iterator j = _views.begin();
+                       while (j != _views.end()) {
+                               shared_ptr<AudioContentView> test = dynamic_pointer_cast<AudioContentView> (*j);
+                               if (!test) {
+                                       ++j;
+                                       continue;
+                               }
+                               
+                               shared_ptr<Content> test_content = test->content().lock ();
+                               assert (test_content);
+                                       
+                               if (test && test->track() == t) {
+                                       if ((acv_content->start() <= test_content->start() && test_content->start() <= acv_content->end()) ||
+                                           (acv_content->start() <= test_content->end()   && test_content->end()   <= acv_content->end())) {
+                                               /* we have an overlap on track `t' */
+                                               ++t;
+                                               break;
+                                       }
+                               }
+                               
+                               ++j;
+                       }
+
+                       if (j == _views.end ()) {
+                               /* no overlap on `t' */
+                               break;
+                       }
+               }
+
+               acv->set_track (t);
+               _tracks = max (_tracks, t + 1);
+       }
+
+       _time_axis_view->set_y (tracks() * track_height() + 32);
+}
+
 int
 Timeline::tracks () const
 {
-       /* XXX */
-       return 2;
+       return _tracks;
 }
 
 void
@@ -417,6 +495,9 @@ Timeline::left_down (wxMouseEvent& ev)
                shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*j);
                if (cv) {
                        cv->set_selected (i == j);
+                       if (i == j) {
+                               _film_editor->set_selection (cv->content ());
+                       }
                }
        }
 
@@ -453,6 +534,10 @@ Timeline::mouse_moved (wxMouseEvent& ev)
                shared_ptr<Content> c = _down_view->content().lock();
                if (c) {
                        c->set_start (max (static_cast<Time> (0), _down_view_start + time_diff));
+
+                       shared_ptr<Film> film = _film.lock ();
+                       assert (film);
+                       film->set_sequence_video (false);
                }
        }
 }