Split up Timeline view classes.
authorCarl Hetherington <cth@carlh.net>
Thu, 19 Feb 2015 00:17:34 +0000 (00:17 +0000)
committerCarl Hetherington <cth@carlh.net>
Thu, 19 Feb 2015 00:17:34 +0000 (00:17 +0000)
17 files changed:
src/lib/image_filename_sorter.cc
src/lib/rect.h
src/wx/timeline.cc
src/wx/timeline.h
src/wx/timeline_audio_content_view.cc [new file with mode: 0644]
src/wx/timeline_audio_content_view.h [new file with mode: 0644]
src/wx/timeline_content_view.cc [new file with mode: 0644]
src/wx/timeline_content_view.h [new file with mode: 0644]
src/wx/timeline_subtitle_content_view.cc [new file with mode: 0644]
src/wx/timeline_subtitle_content_view.h [new file with mode: 0644]
src/wx/timeline_time_axis_view.cc [new file with mode: 0644]
src/wx/timeline_time_axis_view.h [new file with mode: 0644]
src/wx/timeline_video_content_view.cc [new file with mode: 0644]
src/wx/timeline_video_content_view.h [new file with mode: 0644]
src/wx/timeline_view.cc [new file with mode: 0644]
src/wx/timeline_view.h [new file with mode: 0644]
src/wx/wscript

index 251124758bc5d39ba939f2474af2f378873716c5..7bb1b4c376bb24762a860b3990fb4b5acebc1087 100644 (file)
@@ -57,6 +57,6 @@ private:
                        return boost::optional<int> ();
                }
 
-               return libdcp::raw_convert<int> (number);
+               return dcp::raw_convert<int> (number);
        }
 };
index 1feb8ad4fed460d19a9f83439e21bdd0abcc1ea0..963119b507b793998d370ffdf1acd786af1dbe9b 100644 (file)
@@ -21,6 +21,7 @@
 #define DCPOMATIC_RECT_H
 
 #include "position.h"
+#include <algorithm>
 
 /* Put this inside a namespace as Apple put a Rect in the global namespace */
 
index bd001b12e385d78ba8d7df9a363b0f8a990d0afb..6ed91e098e17b05b5961fb47b5056191806e526a 100644 (file)
 #include "lib/image_content.h"
 #include "film_editor.h"
 #include "timeline.h"
+#include "timeline_time_axis_view.h"
+#include "timeline_video_content_view.h"
+#include "timeline_audio_content_view.h"
+#include "timeline_subtitle_content_view.h"
 #include "content_panel.h"
 #include "wx_util.h"
 
@@ -37,378 +41,11 @@ using boost::dynamic_pointer_cast;
 using boost::bind;
 using boost::optional;
 
-/** @class View
- *  @brief Parent class for components of the timeline (e.g. a piece of content or an axis).
- */
-class View : public boost::noncopyable
-{
-public:
-       View (Timeline& t)
-               : _timeline (t)
-       {
-
-       }
-
-       virtual ~View () {}
-               
-       void paint (wxGraphicsContext* g)
-       {
-               _last_paint_bbox = bbox ();
-               do_paint (g);
-       }
-       
-       void force_redraw ()
-       {
-               _timeline.force_redraw (_last_paint_bbox);
-               _timeline.force_redraw (bbox ());
-       }
-
-       virtual dcpomatic::Rect<int> bbox () const = 0;
-
-protected:
-       virtual void do_paint (wxGraphicsContext *) = 0;
-       
-       int time_x (DCPTime t) const
-       {
-               return _timeline.tracks_position().x + t.seconds() * _timeline.pixels_per_second().get_value_or (0);
-       }
-       
-       Timeline& _timeline;
-
-private:
-       dcpomatic::Rect<int> _last_paint_bbox;
-};
-
-
-/** @class ContentView
- *  @brief Parent class for views of pieces of content.
- */
-class ContentView : public View
-{
-public:
-       ContentView (Timeline& tl, shared_ptr<Content> c)
-               : View (tl)
-               , _content (c)
-               , _selected (false)
-       {
-               _content_connection = c->Changed.connect (bind (&ContentView::content_changed, this, _2, _3));
-       }
-
-       dcpomatic::Rect<int> bbox () const
-       {
-               DCPOMATIC_ASSERT (_track);
-
-               shared_ptr<const Film> film = _timeline.film ();
-               shared_ptr<const Content> content = _content.lock ();
-               if (!film || !content) {
-                       return dcpomatic::Rect<int> ();
-               }
-               
-               return dcpomatic::Rect<int> (
-                       time_x (content->position ()) - 8,
-                       y_pos (_track.get()) - 8,
-                       content->length_after_trim().seconds() * _timeline.pixels_per_second().get_value_or(0) + 16,
-                       _timeline.track_height() + 16
-                       );
-       }
-
-       void set_selected (bool s) {
-               _selected = s;
-               force_redraw ();
-       }
-       
-       bool selected () const {
-               return _selected;
-       }
-
-       shared_ptr<Content> content () const {
-               return _content.lock ();
-       }
-
-       void set_track (int t) {
-               _track = t;
-       }
-
-       void unset_track () {
-               _track = boost::optional<int> ();
-       }
-
-       optional<int> track () const {
-               return _track;
-       }
-
-       virtual wxString type () const = 0;
-       virtual wxColour background_colour () const = 0;
-       virtual wxColour foreground_colour () const = 0;
-       
-private:
-
-       void do_paint (wxGraphicsContext* gc)
-       {
-               DCPOMATIC_ASSERT (_track);
-
-               shared_ptr<const Film> film = _timeline.film ();
-               shared_ptr<const Content> cont = content ();
-               if (!film || !cont) {
-                       return;
-               }
-
-               DCPTime const position = cont->position ();
-               DCPTime const len = cont->length_after_trim ();
-
-               wxColour selected (background_colour().Red() / 2, background_colour().Green() / 2, background_colour().Blue() / 2);
-
-               gc->SetPen (*wxThePenList->FindOrCreatePen (foreground_colour(), 4, wxPENSTYLE_SOLID));
-               if (_selected) {
-                       gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (selected, wxBRUSHSTYLE_SOLID));
-               } else {
-                       gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (background_colour(), wxBRUSHSTYLE_SOLID));
-               }
-
-               wxGraphicsPath path = gc->CreatePath ();
-               path.MoveToPoint    (time_x (position),       y_pos (_track.get()) + 4);
-               path.AddLineToPoint (time_x (position + len), y_pos (_track.get()) + 4);
-               path.AddLineToPoint (time_x (position + len), y_pos (_track.get() + 1) - 4);
-               path.AddLineToPoint (time_x (position),       y_pos (_track.get() + 1) - 4);
-               path.AddLineToPoint (time_x (position),       y_pos (_track.get()) + 4);
-               gc->StrokePath (path);
-               gc->FillPath (path);
-
-               wxString name = wxString::Format (wxT ("%s [%s]"), std_to_wx (cont->summary()).data(), type().data());
-               wxDouble name_width;
-               wxDouble name_height;
-               wxDouble name_descent;
-               wxDouble name_leading;
-               gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading);
-               
-               gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len.seconds() * _timeline.pixels_per_second().get_value_or(0), _timeline.track_height()));
-               gc->SetFont (gc->CreateFont (*wxNORMAL_FONT, foreground_colour ()));
-               gc->DrawText (name, time_x (position) + 12, y_pos (_track.get() + 1) - name_height - 4);
-               gc->ResetClip ();
-       }
-
-       int y_pos (int t) const
-       {
-               return _timeline.tracks_position().y + t * _timeline.track_height();
-       }
-
-       void content_changed (int p, bool frequent)
-       {
-               ensure_ui_thread ();
-               
-               if (p == ContentProperty::POSITION || p == ContentProperty::LENGTH) {
-                       force_redraw ();
-               }
-
-               if (!frequent) {
-                       _timeline.setup_pixels_per_second ();
-                       _timeline.Refresh ();
-               }
-       }
-
-       boost::weak_ptr<Content> _content;
-       optional<int> _track;
-       bool _selected;
-
-       boost::signals2::scoped_connection _content_connection;
-};
-
-/** @class AudioContentView
- *  @brief Timeline view for AudioContent.
- */
-class AudioContentView : public ContentView
-{
-public:
-       AudioContentView (Timeline& tl, shared_ptr<Content> c)
-               : ContentView (tl, c)
-       {}
-       
-private:
-       wxString type () const
-       {
-               return _("audio");
-       }
-
-       wxColour background_colour () const
-       {
-               return wxColour (149, 121, 232, 255);
-       }
-
-       wxColour foreground_colour () const
-       {
-               return wxColour (0, 0, 0, 255);
-       }
-};
-
-/** @class AudioContentView
- *  @brief Timeline view for VideoContent.
- */
-class VideoContentView : public ContentView
-{
-public:
-       VideoContentView (Timeline& tl, shared_ptr<Content> c)
-               : ContentView (tl, c)
-       {}
-
-private:       
-
-       wxString type () const
-       {
-               if (dynamic_pointer_cast<ImageContent> (content ()) && content()->number_of_paths() == 1) {
-                       return _("still");
-               } else {
-                       return _("video");
-               }
-       }
-
-       wxColour background_colour () const
-       {
-               return wxColour (242, 92, 120, 255);
-       }
-
-       wxColour foreground_colour () const
-       {
-               return wxColour (0, 0, 0, 255);
-       }
-};
-
-/** @class AudioContentView
- *  @brief Timeline view for SubtitleContent.
- */
-class SubtitleContentView : public ContentView
-{
-public:
-       SubtitleContentView (Timeline& tl, shared_ptr<SubtitleContent> c)
-               : ContentView (tl, c)
-               , _subtitle_content (c)
-       {}
-
-private:
-       wxString type () const
-       {
-               return _("subtitles");
-       }
-
-       wxColour background_colour () const
-       {
-               shared_ptr<SubtitleContent> sc = _subtitle_content.lock ();
-               if (!sc || !sc->use_subtitles ()) {
-                       return wxColour (210, 210, 210, 128);
-               }
-               
-               return wxColour (163, 255, 154, 255);
-       }
-
-       wxColour foreground_colour () const
-       {
-               shared_ptr<SubtitleContent> sc = _subtitle_content.lock ();
-               if (!sc || !sc->use_subtitles ()) {
-                       return wxColour (180, 180, 180, 128);
-               }
-
-               return wxColour (0, 0, 0, 255);
-       }
-
-       boost::weak_ptr<SubtitleContent> _subtitle_content;
-};
-
-class TimeAxisView : public View
-{
-public:
-       TimeAxisView (Timeline& tl, int y)
-               : View (tl)
-               , _y (y)
-       {}
-       
-       dcpomatic::Rect<int> bbox () const
-       {
-               return dcpomatic::Rect<int> (0, _y - 4, _timeline.width(), 24);
-       }
-
-       void set_y (int y)
-       {
-               _y = y;
-               force_redraw ();
-       }
-
-private:       
-
-       void do_paint (wxGraphicsContext* gc)
-       {
-               if (!_timeline.pixels_per_second()) {
-                       return;
-               }
-
-               double const pps = _timeline.pixels_per_second().get ();
-               
-               gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID));
-               
-               double mark_interval = rint (128 / pps);
-               if (mark_interval > 5) {
-                       mark_interval -= int (rint (mark_interval)) % 5;
-               }
-               if (mark_interval > 10) {
-                       mark_interval -= int (rint (mark_interval)) % 10;
-               }
-               if (mark_interval > 60) {
-                       mark_interval -= int (rint (mark_interval)) % 60;
-               }
-               if (mark_interval > 3600) {
-                       mark_interval -= int (rint (mark_interval)) % 3600;
-               }
-               
-               if (mark_interval < 1) {
-                       mark_interval = 1;
-               }
-
-               wxGraphicsPath path = gc->CreatePath ();
-               path.MoveToPoint (_timeline.x_offset(), _y);
-               path.AddLineToPoint (_timeline.width(), _y);
-               gc->StrokePath (path);
-
-               gc->SetFont (gc->CreateFont (*wxNORMAL_FONT));
-               
-               /* Time in seconds */
-               DCPTime t;
-               while ((t.seconds() * pps) < _timeline.width()) {
-                       wxGraphicsPath path = gc->CreatePath ();
-                       path.MoveToPoint (time_x (t), _y - 4);
-                       path.AddLineToPoint (time_x (t), _y + 4);
-                       gc->StrokePath (path);
-
-                       double tc = t.seconds ();
-                       int const h = tc / 3600;
-                       tc -= h * 3600;
-                       int const m = tc / 60;
-                       tc -= m * 60;
-                       int const s = tc;
-                       
-                       wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s);
-                       wxDouble str_width;
-                       wxDouble str_height;
-                       wxDouble str_descent;
-                       wxDouble str_leading;
-                       gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading);
-                       
-                       int const tx = _timeline.x_offset() + t.seconds() * pps;
-                       if ((tx + str_width) < _timeline.width()) {
-                               gc->DrawText (str, time_x (t), _y + 16);
-                       }
-                       
-                       t += DCPTime::from_seconds (mark_interval);
-               }
-       }
-
-private:
-       int _y;
-};
-
-
 Timeline::Timeline (wxWindow* parent, ContentPanel* cp, shared_ptr<Film> film)
        : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
        , _content_panel (cp)
        , _film (film)
-       , _time_axis_view (new TimeAxisView (*this, 32))
+       , _time_axis_view (new TimelineTimeAxisView (*this, 32))
        , _tracks (0)
        , _left_down (false)
        , _down_view_position (0)
@@ -445,7 +82,7 @@ Timeline::paint ()
                return;
        }
 
-       for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+       for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
                (*i)->paint (gc);
        }
 
@@ -469,15 +106,15 @@ Timeline::playlist_changed ()
 
        for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
                if (dynamic_pointer_cast<VideoContent> (*i)) {
-                       _views.push_back (shared_ptr<View> (new VideoContentView (*this, *i)));
+                       _views.push_back (shared_ptr<TimelineView> (new TimelineVideoContentView (*this, *i)));
                }
                if (dynamic_pointer_cast<AudioContent> (*i)) {
-                       _views.push_back (shared_ptr<View> (new AudioContentView (*this, *i)));
+                       _views.push_back (shared_ptr<TimelineView> (new TimelineAudioContentView (*this, *i)));
                }
 
                shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (*i);
                if (sc && sc->has_subtitles ()) {
-                       _views.push_back (shared_ptr<View> (new SubtitleContentView (*this, sc)));
+                       _views.push_back (shared_ptr<TimelineView> (new TimelineSubtitleContentView (*this, sc)));
                }
        }
 
@@ -501,15 +138,15 @@ Timeline::playlist_content_changed (int property)
 void
 Timeline::assign_tracks ()
 {
-       for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
-               shared_ptr<ContentView> c = dynamic_pointer_cast<ContentView> (*i);
+       for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<TimelineContentView> c = dynamic_pointer_cast<TimelineContentView> (*i);
                if (c) {
                        c->unset_track ();
                }
        }
 
-       for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
-               shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+       for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
                if (!cv) {
                        continue;
                }
@@ -518,9 +155,9 @@ Timeline::assign_tracks ()
 
                int t = 0;
                while (true) {
-                       ViewList::iterator j = _views.begin();
+                       TimelineViewList::iterator j = _views.begin();
                        while (j != _views.end()) {
-                               shared_ptr<ContentView> test = dynamic_pointer_cast<ContentView> (*j);
+                               shared_ptr<TimelineContentView> test = dynamic_pointer_cast<TimelineContentView> (*j);
                                if (!test) {
                                        ++j;
                                        continue;
@@ -573,17 +210,17 @@ Timeline::setup_pixels_per_second ()
        _pixels_per_second = static_cast<double>(width() - x_offset() * 2) / film->length().seconds ();
 }
 
-shared_ptr<View>
+shared_ptr<TimelineView>
 Timeline::event_to_view (wxMouseEvent& ev)
 {
-       ViewList::iterator i = _views.begin();
+       TimelineViewList::iterator i = _views.begin();
        Position<int> const p (ev.GetX(), ev.GetY());
        while (i != _views.end() && !(*i)->bbox().contains (p)) {
                ++i;
        }
 
        if (i == _views.end ()) {
-               return shared_ptr<View> ();
+               return shared_ptr<TimelineView> ();
        }
 
        return *i;
@@ -592,8 +229,8 @@ Timeline::event_to_view (wxMouseEvent& ev)
 void
 Timeline::left_down (wxMouseEvent& ev)
 {
-       shared_ptr<View> view = event_to_view (ev);
-       shared_ptr<ContentView> content_view = dynamic_pointer_cast<ContentView> (view);
+       shared_ptr<TimelineView> view = event_to_view (ev);
+       shared_ptr<TimelineContentView> content_view = dynamic_pointer_cast<TimelineContentView> (view);
 
        _down_view.reset ();
 
@@ -602,8 +239,8 @@ Timeline::left_down (wxMouseEvent& ev)
                _down_view_position = content_view->content()->position ();
        }
 
-       for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
-               shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+       for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
                if (!cv) {
                        continue;
                }
@@ -655,8 +292,8 @@ Timeline::mouse_moved (wxMouseEvent& ev)
 void
 Timeline::right_down (wxMouseEvent& ev)
 {
-       shared_ptr<View> view = event_to_view (ev);
-       shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (view);
+       shared_ptr<TimelineView> view = event_to_view (ev);
+       shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (view);
        if (!cv) {
                return;
        }
@@ -715,8 +352,8 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
                optional<DCPTime> nearest_distance;
                
                /* Find the nearest content edge; this is inefficient */
-               for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
-                       shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+               for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+                       shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
                        if (!cv || cv == _down_view) {
                                continue;
                        }
@@ -767,21 +404,21 @@ Timeline::resized ()
 void
 Timeline::clear_selection ()
 {
-       for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
-               shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+       for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
                if (cv) {
                        cv->set_selected (false);
                }
        }
 }
 
-Timeline::ContentViewList
+TimelineContentViewList
 Timeline::selected_views () const
 {
-       ContentViewList sel;
+       TimelineContentViewList sel;
        
-       for (ViewList::const_iterator i = _views.begin(); i != _views.end(); ++i) {
-               shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+       for (TimelineViewList::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+               shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
                if (cv && cv->selected()) {
                        sel.push_back (cv);
                }
@@ -794,9 +431,9 @@ ContentList
 Timeline::selected_content () const
 {
        ContentList sel;
-       ContentViewList views = selected_views ();
+       TimelineContentViewList views = selected_views ();
        
-       for (ContentViewList::const_iterator i = views.begin(); i != views.end(); ++i) {
+       for (TimelineContentViewList::const_iterator i = views.begin(); i != views.end(); ++i) {
                sel.push_back ((*i)->content ());
        }
 
index 7595f10670bafebeb7a40830bbb1eb9ed52c998b..66f982c4ae279b3b6767f4ca33d81e2e0324bae9 100644 (file)
 #include "lib/util.h"
 #include "lib/rect.h"
 #include "content_menu.h"
+#include "timeline_content_view.h"
 
 class Film;
-class View;
-class ContentView;
 class ContentPanel;
-class TimeAxisView;
+class TimelineView;
+class TimelineTimeAxisView;
 
 class Timeline : public wxPanel
 {
@@ -85,23 +85,20 @@ private:
        void set_position_from_event (wxMouseEvent &);
        void clear_selection ();
 
-       typedef std::vector<boost::shared_ptr<View> > ViewList;
-       typedef std::vector<boost::shared_ptr<ContentView> > ContentViewList;
-
-       boost::shared_ptr<View> event_to_view (wxMouseEvent &);
-       ContentViewList selected_views () const;
+       boost::shared_ptr<TimelineView> event_to_view (wxMouseEvent &);
+       TimelineContentViewList 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;
-       ViewList _views;
-       boost::shared_ptr<TimeAxisView> _time_axis_view;
+       TimelineViewList _views;
+       boost::shared_ptr<TimelineTimeAxisView> _time_axis_view;
        int _tracks;
        boost::optional<double> _pixels_per_second;
        bool _left_down;
        wxPoint _down_point;
-       boost::shared_ptr<ContentView> _down_view;
+       boost::shared_ptr<TimelineContentView> _down_view;
        DCPTime _down_view_position;
        bool _first_move;
        ContentMenu _menu;
diff --git a/src/wx/timeline_audio_content_view.cc b/src/wx/timeline_audio_content_view.cc
new file mode 100644 (file)
index 0000000..a9e3a6a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_audio_content_view.h"
+
+using boost::shared_ptr;
+
+/** @class TimelineAudioContentView
+ *  @brief Timeline view for AudioContent.
+ */
+
+TimelineAudioContentView::TimelineAudioContentView (Timeline& tl, shared_ptr<Content> c)
+       : TimelineContentView (tl, c)
+{
+
+}
+
+wxString
+TimelineAudioContentView::type () const
+{
+       return _("audio");
+}
+
+wxColour
+TimelineAudioContentView::background_colour () const
+{
+       return wxColour (149, 121, 232, 255);
+}
+
+wxColour
+TimelineAudioContentView::foreground_colour () const
+{
+       return wxColour (0, 0, 0, 255);
+}
diff --git a/src/wx/timeline_audio_content_view.h b/src/wx/timeline_audio_content_view.h
new file mode 100644 (file)
index 0000000..23c5c6d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_content_view.h"
+
+/** @class TimelineAudioContentView
+ *  @brief Timeline view for AudioContent.
+ */
+class TimelineAudioContentView : public TimelineContentView
+{
+public:
+       TimelineAudioContentView (Timeline& tl, boost::shared_ptr<Content> c);
+       
+private:
+       wxString type () const;
+       wxColour background_colour () const;
+       wxColour foreground_colour () const;
+};
diff --git a/src/wx/timeline_content_view.cc b/src/wx/timeline_content_view.cc
new file mode 100644 (file)
index 0000000..b72ba48
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_content_view.h"
+#include "timeline.h"
+#include "wx_util.h"
+#include "lib/content.h"
+#include <wx/graphics.h>
+
+using boost::shared_ptr;
+
+TimelineContentView::TimelineContentView (Timeline& tl, shared_ptr<Content> c)
+       : TimelineView (tl)
+       , _content (c)
+       , _selected (false)
+{
+       _content_connection = c->Changed.connect (bind (&TimelineContentView::content_changed, this, _2, _3));
+}
+
+dcpomatic::Rect<int>
+TimelineContentView::bbox () const
+{
+       DCPOMATIC_ASSERT (_track);
+       
+       shared_ptr<const Film> film = _timeline.film ();
+       shared_ptr<const Content> content = _content.lock ();
+       if (!film || !content) {
+               return dcpomatic::Rect<int> ();
+       }
+       
+       return dcpomatic::Rect<int> (
+               time_x (content->position ()) - 8,
+               y_pos (_track.get()) - 8,
+               content->length_after_trim().seconds() * _timeline.pixels_per_second().get_value_or(0) + 16,
+               _timeline.track_height() + 16
+               );
+}
+
+void
+TimelineContentView::set_selected (bool s)
+{
+       _selected = s;
+       force_redraw ();
+}
+
+bool
+TimelineContentView::selected () const
+{
+       return _selected;
+}
+
+shared_ptr<Content>
+TimelineContentView::content () const
+{
+       return _content.lock ();
+}
+
+void
+TimelineContentView::set_track (int t)
+{
+       _track = t;
+}
+
+void
+TimelineContentView::unset_track ()
+{
+       _track = boost::optional<int> ();
+}
+
+boost::optional<int>
+TimelineContentView::track () const
+{
+       return _track;
+}
+
+void
+TimelineContentView::do_paint (wxGraphicsContext* gc)
+{
+       DCPOMATIC_ASSERT (_track);
+       
+       shared_ptr<const Film> film = _timeline.film ();
+       shared_ptr<const Content> cont = content ();
+       if (!film || !cont) {
+               return;
+       }
+       
+       DCPTime const position = cont->position ();
+       DCPTime const len = cont->length_after_trim ();
+       
+       wxColour selected (background_colour().Red() / 2, background_colour().Green() / 2, background_colour().Blue() / 2);
+       
+       gc->SetPen (*wxThePenList->FindOrCreatePen (foreground_colour(), 4, wxPENSTYLE_SOLID));
+       if (_selected) {
+               gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (selected, wxBRUSHSTYLE_SOLID));
+       } else {
+               gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (background_colour(), wxBRUSHSTYLE_SOLID));
+       }
+
+       wxGraphicsPath path = gc->CreatePath ();
+       path.MoveToPoint    (time_x (position),       y_pos (_track.get()) + 4);
+       path.AddLineToPoint (time_x (position + len), y_pos (_track.get()) + 4);
+       path.AddLineToPoint (time_x (position + len), y_pos (_track.get() + 1) - 4);
+       path.AddLineToPoint (time_x (position),       y_pos (_track.get() + 1) - 4);
+       path.AddLineToPoint (time_x (position),       y_pos (_track.get()) + 4);
+       gc->StrokePath (path);
+       gc->FillPath (path);
+       
+       wxString name = wxString::Format (wxT ("%s [%s]"), std_to_wx (cont->summary()).data(), type().data());
+       wxDouble name_width;
+       wxDouble name_height;
+       wxDouble name_descent;
+       wxDouble name_leading;
+       gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading);
+       
+       gc->Clip (wxRegion (time_x (position), y_pos (_track.get()), len.seconds() * _timeline.pixels_per_second().get_value_or(0), _timeline.track_height()));
+       gc->SetFont (gc->CreateFont (*wxNORMAL_FONT, foreground_colour ()));
+       gc->DrawText (name, time_x (position) + 12, y_pos (_track.get() + 1) - name_height - 4);
+       gc->ResetClip ();
+}
+
+int
+TimelineContentView::y_pos (int t) const
+{
+       return _timeline.tracks_position().y + t * _timeline.track_height();
+}
+
+void
+TimelineContentView::content_changed (int p, bool frequent)
+{
+       ensure_ui_thread ();
+       
+       if (p == ContentProperty::POSITION || p == ContentProperty::LENGTH) {
+               force_redraw ();
+       }
+       
+       if (!frequent) {
+               _timeline.setup_pixels_per_second ();
+               _timeline.Refresh ();
+       }
+}
+
diff --git a/src/wx/timeline_content_view.h b/src/wx/timeline_content_view.h
new file mode 100644 (file)
index 0000000..d5c9126
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef DCPOMATIC_TIMELINE_CONTENT_VIEW_H
+#define DCPOMATIC_TIMELINE_CONTENT_VIEW_H
+
+#include "timeline_view.h"
+#include <wx/wx.h>
+#include <boost/signals2.hpp>
+
+class Content;
+
+/** @class TimelineContentView
+ *  @brief Parent class for views of pieces of content.
+ */
+class TimelineContentView : public TimelineView
+{
+public:
+       TimelineContentView (Timeline& tl, boost::shared_ptr<Content> c);
+
+       dcpomatic::Rect<int> bbox () const;
+
+       void set_selected (bool s);
+       bool selected () const;
+       boost::shared_ptr<Content> content () const;
+       void set_track (int t);
+       void unset_track ();
+       boost::optional<int> track () const;
+
+       virtual wxString type () const = 0;
+       virtual wxColour background_colour () const = 0;
+       virtual wxColour foreground_colour () const = 0;
+       
+private:
+
+       void do_paint (wxGraphicsContext* gc);
+       int y_pos (int t) const;
+       void content_changed (int p, bool frequent);
+
+       boost::weak_ptr<Content> _content;
+       boost::optional<int> _track;
+       bool _selected;
+
+       boost::signals2::scoped_connection _content_connection;
+};
+
+typedef std::vector<boost::shared_ptr<TimelineContentView> > TimelineContentViewList;
+
+#endif
diff --git a/src/wx/timeline_subtitle_content_view.cc b/src/wx/timeline_subtitle_content_view.cc
new file mode 100644 (file)
index 0000000..407997b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_subtitle_content_view.h"
+#include "lib/subtitle_content.h"
+
+using boost::shared_ptr;
+
+TimelineSubtitleContentView::TimelineSubtitleContentView (Timeline& tl, shared_ptr<SubtitleContent> c)
+       : TimelineContentView (tl, c)
+       , _subtitle_content (c)
+{
+
+}
+
+wxString
+TimelineSubtitleContentView::type () const
+{
+       return _("subtitles");
+}
+
+wxColour
+TimelineSubtitleContentView::background_colour () const
+{
+       shared_ptr<SubtitleContent> sc = _subtitle_content.lock ();
+       if (!sc || !sc->use_subtitles ()) {
+               return wxColour (210, 210, 210, 128);
+       }
+       
+       return wxColour (163, 255, 154, 255);
+}
+
+wxColour
+TimelineSubtitleContentView::foreground_colour () const
+{
+       shared_ptr<SubtitleContent> sc = _subtitle_content.lock ();
+       if (!sc || !sc->use_subtitles ()) {
+               return wxColour (180, 180, 180, 128);
+       }
+       
+       return wxColour (0, 0, 0, 255);
+}
diff --git a/src/wx/timeline_subtitle_content_view.h b/src/wx/timeline_subtitle_content_view.h
new file mode 100644 (file)
index 0000000..b2ba96c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_content_view.h"
+
+class SubtitleContent;
+
+/** @class TimelineSubtitleContentView
+ *  @brief Timeline view for SubtitleContent.
+ */
+class TimelineSubtitleContentView : public TimelineContentView
+{
+public:
+       TimelineSubtitleContentView (Timeline& tl, boost::shared_ptr<SubtitleContent> c);
+
+private:
+       wxString type () const;
+       wxColour background_colour () const;
+       wxColour foreground_colour () const;
+
+       boost::weak_ptr<SubtitleContent> _subtitle_content;
+};
+
diff --git a/src/wx/timeline_time_axis_view.cc b/src/wx/timeline_time_axis_view.cc
new file mode 100644 (file)
index 0000000..88236c6
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_time_axis_view.h"
+#include "timeline.h"
+#include <wx/wx.h>
+#include <wx/graphics.h>
+
+TimelineTimeAxisView::TimelineTimeAxisView (Timeline& tl, int y)
+       : TimelineView (tl)
+       , _y (y)
+{
+
+}
+       
+dcpomatic::Rect<int>
+TimelineTimeAxisView::bbox () const
+{
+       return dcpomatic::Rect<int> (0, _y - 4, _timeline.width(), 24);
+}
+
+void
+TimelineTimeAxisView::set_y (int y)
+{
+       _y = y;
+       force_redraw ();
+}
+
+void
+TimelineTimeAxisView::do_paint (wxGraphicsContext* gc)
+{
+       if (!_timeline.pixels_per_second()) {
+               return;
+       }
+       
+       double const pps = _timeline.pixels_per_second().get ();
+       
+       gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID));
+       
+       double mark_interval = rint (128 / pps);
+       if (mark_interval > 5) {
+               mark_interval -= int (rint (mark_interval)) % 5;
+       }
+       if (mark_interval > 10) {
+               mark_interval -= int (rint (mark_interval)) % 10;
+       }
+       if (mark_interval > 60) {
+               mark_interval -= int (rint (mark_interval)) % 60;
+       }
+       if (mark_interval > 3600) {
+               mark_interval -= int (rint (mark_interval)) % 3600;
+       }
+       
+       if (mark_interval < 1) {
+               mark_interval = 1;
+       }
+       
+       wxGraphicsPath path = gc->CreatePath ();
+       path.MoveToPoint (_timeline.x_offset(), _y);
+       path.AddLineToPoint (_timeline.width(), _y);
+       gc->StrokePath (path);
+       
+       gc->SetFont (gc->CreateFont (*wxNORMAL_FONT));
+       
+       /* Time in seconds */
+       DCPTime t;
+       while ((t.seconds() * pps) < _timeline.width()) {
+               wxGraphicsPath path = gc->CreatePath ();
+               path.MoveToPoint (time_x (t), _y - 4);
+               path.AddLineToPoint (time_x (t), _y + 4);
+               gc->StrokePath (path);
+               
+               double tc = t.seconds ();
+               int const h = tc / 3600;
+               tc -= h * 3600;
+               int const m = tc / 60;
+               tc -= m * 60;
+               int const s = tc;
+               
+               wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s);
+               wxDouble str_width;
+               wxDouble str_height;
+               wxDouble str_descent;
+               wxDouble str_leading;
+               gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading);
+               
+               int const tx = _timeline.x_offset() + t.seconds() * pps;
+               if ((tx + str_width) < _timeline.width()) {
+                       gc->DrawText (str, time_x (t), _y + 16);
+               }
+               
+               t += DCPTime::from_seconds (mark_interval);
+       }
+}
diff --git a/src/wx/timeline_time_axis_view.h b/src/wx/timeline_time_axis_view.h
new file mode 100644 (file)
index 0000000..4b17c09
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_view.h"
+
+class TimelineTimeAxisView : public TimelineView
+{
+public:
+       TimelineTimeAxisView (Timeline& tl, int y);
+
+       dcpomatic::Rect<int> bbox () const;
+       void set_y (int y);
+
+private:       
+       void do_paint (wxGraphicsContext* gc);
+
+private:
+       int _y;
+};
+
diff --git a/src/wx/timeline_video_content_view.cc b/src/wx/timeline_video_content_view.cc
new file mode 100644 (file)
index 0000000..6d37c68
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_video_content_view.h"
+#include "lib/image_content.h"
+
+using boost::dynamic_pointer_cast;
+using boost::shared_ptr;
+
+TimelineVideoContentView::TimelineVideoContentView (Timeline& tl, shared_ptr<Content> c)
+       : TimelineContentView (tl, c)
+{
+
+}
+
+wxString
+TimelineVideoContentView::type () const
+{
+       if (dynamic_pointer_cast<ImageContent> (content ()) && content()->number_of_paths() == 1) {
+               return _("still");
+       } else {
+               return _("video");
+       }
+}
+
+wxColour
+TimelineVideoContentView::background_colour () const
+{
+       return wxColour (242, 92, 120, 255);
+}
+
+wxColour
+TimelineVideoContentView::foreground_colour () const
+{
+       return wxColour (0, 0, 0, 255);
+}
+
diff --git a/src/wx/timeline_video_content_view.h b/src/wx/timeline_video_content_view.h
new file mode 100644 (file)
index 0000000..667c544
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_content_view.h"
+
+/** @class TimelineVideoContentView
+ *  @brief Timeline view for VideoContent.
+ */
+class TimelineVideoContentView : public TimelineContentView
+{
+public:
+       TimelineVideoContentView (Timeline& tl, boost::shared_ptr<Content> c);
+
+private:       
+       wxString type () const;
+       wxColour background_colour () const;
+       wxColour foreground_colour () const;
+};
diff --git a/src/wx/timeline_view.cc b/src/wx/timeline_view.cc
new file mode 100644 (file)
index 0000000..dbcbe02
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "timeline_view.h"
+#include "timeline.h"
+
+/** @class TimelineView
+ *  @brief Parent class for components of the timeline (e.g. a piece of content or an axis).
+ */
+TimelineView::TimelineView (Timeline& t)
+       : _timeline (t)
+{
+       
+}
+
+void
+TimelineView::paint (wxGraphicsContext* g)
+{
+       _last_paint_bbox = bbox ();
+       do_paint (g);
+}
+
+void
+TimelineView::force_redraw ()
+{
+       _timeline.force_redraw (_last_paint_bbox);
+       _timeline.force_redraw (bbox ());
+}
+
+int
+TimelineView::time_x (DCPTime t) const
+{
+               return _timeline.tracks_position().x + t.seconds() * _timeline.pixels_per_second().get_value_or (0);
+}
+
diff --git a/src/wx/timeline_view.h b/src/wx/timeline_view.h
new file mode 100644 (file)
index 0000000..e52e28d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef DCPOMATIC_TIMELINE_VIEW_H
+#define DCPOMATIC_TIMELINE_VIEW_H
+
+#include "lib/rect.h"
+#include "lib/dcpomatic_time.h"
+#include <boost/noncopyable.hpp>
+
+class wxGraphicsContext;
+class Timeline;
+
+/** @class TimelineView
+ *  @brief Parent class for components of the timeline (e.g. a piece of content or an axis).
+ */
+class TimelineView : public boost::noncopyable
+{
+public:
+       TimelineView (Timeline& t);
+       virtual ~TimelineView () {}
+               
+       void paint (wxGraphicsContext* g);
+       void force_redraw ();
+
+       virtual dcpomatic::Rect<int> bbox () const = 0;
+
+protected:
+       virtual void do_paint (wxGraphicsContext *) = 0;
+       
+       int time_x (DCPTime t) const;
+       
+       Timeline& _timeline;
+
+private:
+       dcpomatic::Rect<int> _last_paint_bbox;
+};
+
+typedef std::vector<boost::shared_ptr<TimelineView> > TimelineViewList;
+
+#endif
index 061c4e808d82a29ed09b47b8a52a070ecfb966d3..aa5487f5fa4dbbe561f9cd1b25bd35a8b056da74 100644 (file)
@@ -47,7 +47,13 @@ sources = """
           table_dialog.cc
           timecode.cc
           timeline.cc
+          timeline_content_view.cc
           timeline_dialog.cc
+          timeline_audio_content_view.cc
+          timeline_subtitle_content_view.cc
+          timeline_time_axis_view.cc
+          timeline_video_content_view.cc
+          timeline_view.cc
           timing_panel.cc
           update_dialog.cc
           video_panel.cc