#include <wx/graphics.h>
#include <boost/weak_ptr.hpp>
#include <boost/foreach.hpp>
-#include <boost/make_shared.hpp>
#include <list>
#include <iostream>
using std::cout;
using std::max;
using boost::shared_ptr;
-using boost::make_shared;
using boost::weak_ptr;
using boost::dynamic_pointer_cast;
using boost::bind;
BOOST_FOREACH (shared_ptr<Content> i, film->content ()) {
if (i->video) {
- _views.push_back (make_shared<TimelineVideoContentView> (*this, i));
+ _views.push_back (shared_ptr<TimelineView> (new TimelineVideoContentView (*this, i)));
}
if (i->audio && !i->audio->mapping().mapped_output_channels().empty ()) {
- _views.push_back (make_shared<TimelineAudioContentView> (*this, i));
+ _views.push_back (shared_ptr<TimelineView> (new TimelineAudioContentView (*this, i)));
}
if (i->subtitle) {
- _views.push_back (make_shared<TimelineSubtitleContentView> (*this, i));
+ _views.push_back (shared_ptr<TimelineView> (new TimelineSubtitleContentView (*this, i)));
}
if (dynamic_pointer_cast<AtmosMXFContent> (i)) {
- _views.push_back (make_shared<TimelineAtmosContentView> (*this, i));
+ _views.push_back (shared_ptr<TimelineView> (new TimelineAtmosContentView (*this, i)));
}
}
}
}
+template <class T>
+int
+place (TimelineViewList& views, int& tracks)
+{
+ int const base = tracks;
+
+ BOOST_FOREACH (shared_ptr<TimelineView> i, views) {
+ if (!dynamic_pointer_cast<T>(i)) {
+ continue;
+ }
+
+ shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (i);
+
+ int t = base;
+
+ shared_ptr<Content> content = cv->content();
+ DCPTimePeriod const content_period (content->position(), content->end());
+
+ while (true) {
+ TimelineViewList::iterator j = views.begin();
+ while (j != views.end()) {
+ shared_ptr<T> test = dynamic_pointer_cast<T> (*j);
+ if (!test) {
+ ++j;
+ continue;
+ }
+
+ shared_ptr<Content> test_content = test->content();
+ if (
+ test->track() && test->track().get() == t &&
+ content_period.overlap(DCPTimePeriod(test_content->position(), test_content->end()))) {
+ /* we have an overlap on track `t' */
+ ++t;
+ break;
+ }
+
+ ++j;
+ }
+
+ if (j == views.end ()) {
+ /* no overlap on `t' */
+ break;
+ }
+ }
+
+ cv->set_track (t);
+ tracks = max (tracks, t + 1);
+ }
+
+ return tracks - base;
+}
+
void
Timeline::assign_tracks ()
{
+ /* Tracks are:
+ Video (mono or left-eye)
+ Video (right-eye)
+ Subtitle 1
+ Subtitle 2
+ Subtitle N
+ Atmos
+ Audio 1
+ Audio 2
+ Audio N
+ */
+
+ _tracks = 0;
+
for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
shared_ptr<TimelineContentView> c = dynamic_pointer_cast<TimelineContentView> (*i);
if (c) {
}
}
- /* See if we have any subtitle / atmos / right-eye views */
+ /* Video */
+
bool have_3d = false;
- bool have_subtitle = false;
- bool have_atmos = false;
BOOST_FOREACH (shared_ptr<TimelineView> i, _views) {
- shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (i);
+ shared_ptr<TimelineVideoContentView> cv = dynamic_pointer_cast<TimelineVideoContentView> (i);
if (!cv) {
continue;
}
- if (dynamic_pointer_cast<TimelineVideoContentView> (i)) {
- if (cv->content()->video->frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) {
- have_3d = true;
- }
- } else if (dynamic_pointer_cast<TimelineSubtitleContentView> (i)) {
- have_subtitle = true;
- } else if (dynamic_pointer_cast<TimelineAtmosContentView> (i)) {
- have_atmos = true;
+ /* Video on tracks 0 and maybe 1 (left and right eye) */
+ if (cv->content()->video->frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT) {
+ cv->set_track (1);
+ _tracks = max (_tracks, 2);
+ have_3d = true;
+ } else {
+ cv->set_track (0);
}
}
- _labels_view->set_3d (have_3d);
- _labels_view->set_subtitle (have_subtitle);
- _labels_view->set_atmos (have_atmos);
+ _tracks = max (_tracks, 1);
- /* Hence decide where to start subtitle, atmos and audio tracks */
- int const subtitle = have_3d ? 2 : 1;
- int const atmos = have_subtitle ? subtitle + 1 : subtitle;
- int const audio = have_atmos ? atmos + 1: atmos;
+ /* Subtitle */
- for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
- shared_ptr<TimelineContentView> cv = dynamic_pointer_cast<TimelineContentView> (*i);
+ int const subtitle_tracks = place<TimelineSubtitleContentView> (_views, _tracks);
+
+ /* Atmos */
+
+ bool have_atmos = false;
+ BOOST_FOREACH (shared_ptr<TimelineView> i, _views) {
+ shared_ptr<TimelineVideoContentView> cv = dynamic_pointer_cast<TimelineVideoContentView> (i);
if (!cv) {
continue;
}
-
- if (dynamic_pointer_cast<TimelineVideoContentView> (*i)) {
- /* Video on tracks 0 and maybe 1 (left and right eye) */
- cv->set_track (cv->content()->video->frame_type() == VIDEO_FRAME_TYPE_3D_RIGHT ? 1 : 0);
- _tracks = max (_tracks, have_3d ? 2 : 1);
- continue;
- } else if (dynamic_pointer_cast<TimelineSubtitleContentView> (*i)) {
- cv->set_track (subtitle);
- _tracks = max (_tracks, subtitle + 1);
- continue;
- } else if (dynamic_pointer_cast<TimelineAtmosContentView> (*i)) {
- cv->set_track (atmos);
- _tracks = max (_tracks, atmos + 1);
- continue;
+ if (dynamic_pointer_cast<TimelineAtmosContentView> (i)) {
+ cv->set_track (_tracks - 1);
+ have_atmos = true;
}
+ }
- int t = audio;
-
- shared_ptr<Content> content = cv->content();
- DCPTimePeriod content_period (content->position(), content->end());
-
- while (true) {
- TimelineViewList::iterator j = _views.begin();
- while (j != _views.end()) {
- shared_ptr<TimelineAudioContentView> test = dynamic_pointer_cast<TimelineAudioContentView> (*j);
- if (!test) {
- ++j;
- continue;
- }
-
- shared_ptr<Content> test_content = test->content();
+ if (have_atmos) {
+ ++_tracks;
+ }
- if (test && test->track() && test->track().get() == t) {
- if (content_period.overlaps (DCPTimePeriod(test_content->position(), test_content->end()))) {
- /* we have an overlap on track `t' */
- ++t;
- break;
- }
- }
+ /* Audio */
- ++j;
- }
+ place<TimelineAudioContentView> (_views, _tracks);
- if (j == _views.end ()) {
- /* no overlap on `t' */
- break;
- }
- }
-
- cv->set_track (t);
- _tracks = max (_tracks, t + 1);
- }
+ _labels_view->set_3d (have_3d);
+ _labels_view->set_subtitle_tracks (subtitle_tracks);
+ _labels_view->set_atmos (have_atmos);
_time_axis_view->set_y (tracks() * track_height() + 64);
_reels_view->set_y (8);
if (_down_view) {
_down_view->content()->set_change_signals_frequent (false);
- _content_panel->set_selection (_down_view->content ());
}
+ _content_panel->set_selection (selected_content ());
set_position_from_event (ev);
/* Clear up up the stuff we don't do during drag */