summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-05-08 10:54:49 +0100
committerCarl Hetherington <cth@carlh.net>2017-05-08 10:54:49 +0100
commit58e851f428a035841acf0196348a0643230ed808 (patch)
tree505c1401445581a39d428b43addefcbe93b324c0 /src
parent0e9d03990993bd19a968ee356443a39336e9b8c5 (diff)
Show overlapping subs in multiple tracks on the timeline (#941).
Diffstat (limited to 'src')
-rw-r--r--src/wx/timeline.cc157
-rw-r--r--src/wx/timeline_labels_view.cc10
-rw-r--r--src/wx/timeline_labels_view.h4
3 files changed, 95 insertions, 76 deletions
diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc
index 5cdd73b25..04db5c628 100644
--- a/src/wx/timeline.cc
+++ b/src/wx/timeline.cc
@@ -184,19 +184,75 @@ Timeline::film_content_changed (int property, bool frequent)
}
}
+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
+ 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) {
@@ -204,93 +260,56 @@ Timeline::assign_tracks ()
}
}
- /* 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.overlap (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);
diff --git a/src/wx/timeline_labels_view.cc b/src/wx/timeline_labels_view.cc
index 1a712f42d..ee1b19489 100644
--- a/src/wx/timeline_labels_view.cc
+++ b/src/wx/timeline_labels_view.cc
@@ -31,7 +31,7 @@ using std::max;
TimelineLabelsView::TimelineLabelsView (Timeline& tl)
: TimelineView (tl)
, _threed (true)
- , _subtitle (true)
+ , _subtitle_tracks (0)
, _atmos (true)
{
wxString labels[] = {
@@ -69,8 +69,8 @@ TimelineLabelsView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int> >
gc->DrawText (_("Video"), 0, _timeline.tracks_position().y + (ty + fy) / 2 - 8);
fy = ty;
- if (_subtitle) {
- ty = fy + h;
+ if (_subtitle_tracks) {
+ ty = fy + _subtitle_tracks * h;
gc->DrawText (_("Subtitles"), 0, _timeline.tracks_position().y + (ty + fy) / 2 - 8);
fy = ty;
}
@@ -92,9 +92,9 @@ TimelineLabelsView::set_3d (bool s)
}
void
-TimelineLabelsView::set_subtitle (bool s)
+TimelineLabelsView::set_subtitle_tracks (int n)
{
- _subtitle = s;
+ _subtitle_tracks = n;
}
void
diff --git a/src/wx/timeline_labels_view.h b/src/wx/timeline_labels_view.h
index 3b7153344..87b3cc902 100644
--- a/src/wx/timeline_labels_view.h
+++ b/src/wx/timeline_labels_view.h
@@ -30,7 +30,7 @@ public:
dcpomatic::Rect<int> bbox () const;
void set_3d (bool s);
- void set_subtitle (bool s);
+ void set_subtitle_tracks (int n);
void set_atmos (bool s);
private:
@@ -38,6 +38,6 @@ private:
int _width;
bool _threed;
- bool _subtitle;
+ int _subtitle_tracks;
bool _atmos;
};