From d2e8a683eed6fb82d4d255fffaf571ff27057132 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 25 Feb 2016 17:06:44 +0000 Subject: [PATCH] Plot video and subtitle on one track and audio on the rest in the timeline. --- src/lib/rect.h | 21 +++++++++++----- src/wx/timeline.cc | 29 ++++++++++++++++----- src/wx/timeline_audio_content_view.h | 3 +++ src/wx/timeline_content_view.cc | 9 ++++++- src/wx/timeline_content_view.h | 5 ++-- src/wx/timeline_reels_view.cc | 5 ++-- src/wx/timeline_reels_view.h | 4 +-- src/wx/timeline_subtitle_content_view.cc | 11 ++++++-- src/wx/timeline_subtitle_content_view.h | 1 + src/wx/timeline_time_axis_view.cc | 6 +++-- src/wx/timeline_time_axis_view.h | 4 +-- src/wx/timeline_video_content_view.h | 3 +++ src/wx/timeline_view.cc | 6 +++-- src/wx/timeline_view.h | 4 +-- test/rect_test.cc | 32 ++++++++++++++++++++++++ test/wscript | 1 + 16 files changed, 115 insertions(+), 29 deletions(-) create mode 100644 test/rect_test.cc diff --git a/src/lib/rect.h b/src/lib/rect.h index 5758dd04e..602acfc4b 100644 --- a/src/lib/rect.h +++ b/src/lib/rect.h @@ -21,6 +21,7 @@ #define DCPOMATIC_RECT_H #include "position.h" +#include #include /* Put this inside a namespace as Apple put a Rect in the global namespace */ @@ -67,16 +68,24 @@ public: return Position (x, y); } - Rect intersection (Rect const & other) const + boost::optional > intersection (Rect const & other) const { - T const tx = max (x, other.x); - T const ty = max (y, other.y); + /* This isn't exactly the paragon of mathematical precision */ - return Rect ( + T const tx = std::max (x, other.x); + T const ty = std::max (y, other.y); + + Rect r ( tx, ty, - min (x + width, other.x + other.width) - tx, - min (y + height, other.y + other.height) - ty + std::min (x + width, other.x + other.width) - tx, + std::min (y + height, other.y + other.height) - ty ); + + if (r.width < 0 || r.height < 0) { + return boost::optional > (); + } + + return r; } void extend (Rect const & other) diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 62b812c8b..de2070531 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -89,8 +89,26 @@ Timeline::paint () return; } - for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) { - (*i)->paint (gc); + + BOOST_FOREACH (shared_ptr i, _views) { + + shared_ptr ic = dynamic_pointer_cast (i); + + /* Find areas of overlap */ + list > overlaps; + BOOST_FOREACH (shared_ptr j, _views) { + shared_ptr jc = dynamic_pointer_cast (j); + if (!ic || !jc || i == j || ic->track() != jc->track() || !ic->active() || !jc->active()) { + continue; + } + + optional > r = j->bbox().intersection (i->bbox()); + if (r) { + overlaps.push_back (r.get ()); + } + } + + i->paint (gc, overlaps); } delete gc; @@ -169,14 +187,12 @@ Timeline::assign_tracks () continue; } - shared_ptr content = cv->content(); - - if (dynamic_pointer_cast (content)) { + if (dynamic_pointer_cast (*i)) { /* Video on track 0 */ cv->set_track (0); _tracks = max (_tracks, 1); continue; - } else if (dynamic_pointer_cast (content)) { + } else if (dynamic_pointer_cast (*i)) { /* Subtitles on track 1 */ cv->set_track (1); _tracks = max (_tracks, 2); @@ -186,6 +202,7 @@ Timeline::assign_tracks () /* Audio on tracks 2 and up */ int t = 2; + shared_ptr content = cv->content(); DCPTimePeriod content_period (content->position(), content->end()); while (true) { diff --git a/src/wx/timeline_audio_content_view.h b/src/wx/timeline_audio_content_view.h index 3d034eed4..f24037c34 100644 --- a/src/wx/timeline_audio_content_view.h +++ b/src/wx/timeline_audio_content_view.h @@ -28,6 +28,9 @@ public: TimelineAudioContentView (Timeline& tl, boost::shared_ptr c); private: + bool active () const { + return true; + } wxColour background_colour () const; wxColour foreground_colour () const; }; diff --git a/src/wx/timeline_content_view.cc b/src/wx/timeline_content_view.cc index ed7e1d3d0..b520b5ceb 100644 --- a/src/wx/timeline_content_view.cc +++ b/src/wx/timeline_content_view.cc @@ -24,6 +24,7 @@ #include #include +using std::list; using boost::shared_ptr; TimelineContentView::TimelineContentView (Timeline& tl, shared_ptr c) @@ -91,7 +92,7 @@ TimelineContentView::track () const } void -TimelineContentView::do_paint (wxGraphicsContext* gc) +TimelineContentView::do_paint (wxGraphicsContext* gc, list > overlaps) { DCPOMATIC_ASSERT (_track); @@ -132,6 +133,12 @@ TimelineContentView::do_paint (wxGraphicsContext* gc) gc->StrokePath (path); } + /* Overlaps */ + gc->SetBrush (*wxTheBrushList->FindOrCreateBrush (foreground_colour(), wxBRUSHSTYLE_CROSSDIAG_HATCH)); + for (list >::const_iterator i = overlaps.begin(); i != overlaps.end(); ++i) { + gc->DrawRectangle (i->x, i->y + 4, i->width, i->height - 8); + } + /* Label text */ wxString name = std_to_wx (cont->summary()); wxDouble name_width; diff --git a/src/wx/timeline_content_view.h b/src/wx/timeline_content_view.h index 07bfb2575..b1b8ecd5d 100644 --- a/src/wx/timeline_content_view.h +++ b/src/wx/timeline_content_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington + Copyright (C) 2013-2016 Carl Hetherington 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 @@ -43,12 +43,13 @@ public: void unset_track (); boost::optional track () const; + virtual bool active () const = 0; virtual wxColour background_colour () const = 0; virtual wxColour foreground_colour () const = 0; private: - void do_paint (wxGraphicsContext* gc); + void do_paint (wxGraphicsContext* gc, std::list > overlaps); int y_pos (int t) const; void content_changed (int p); diff --git a/src/wx/timeline_reels_view.cc b/src/wx/timeline_reels_view.cc index cc9d401cf..6c3da465e 100644 --- a/src/wx/timeline_reels_view.cc +++ b/src/wx/timeline_reels_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2016 Carl Hetherington 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 @@ -24,6 +24,7 @@ #include using std::min; +using std::list; TimelineReelsView::TimelineReelsView (Timeline& tl, int y) : TimelineView (tl) @@ -46,7 +47,7 @@ TimelineReelsView::set_y (int y) } void -TimelineReelsView::do_paint (wxGraphicsContext* gc) +TimelineReelsView::do_paint (wxGraphicsContext* gc, list >) { if (!_timeline.pixels_per_second()) { return; diff --git a/src/wx/timeline_reels_view.h b/src/wx/timeline_reels_view.h index b357be23c..5f8ae1d38 100644 --- a/src/wx/timeline_reels_view.h +++ b/src/wx/timeline_reels_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2016 Carl Hetherington 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 @@ -28,7 +28,7 @@ public: void set_y (int y); private: - void do_paint (wxGraphicsContext* gc); + void do_paint (wxGraphicsContext* gc, std::list > overlaps); private: int _y; diff --git a/src/wx/timeline_subtitle_content_view.cc b/src/wx/timeline_subtitle_content_view.cc index 559fc7f4d..2b6f8c4a9 100644 --- a/src/wx/timeline_subtitle_content_view.cc +++ b/src/wx/timeline_subtitle_content_view.cc @@ -33,7 +33,7 @@ wxColour TimelineSubtitleContentView::background_colour () const { shared_ptr sc = _subtitle_content.lock (); - if (!sc || !sc->use_subtitles ()) { + if (!active ()) { return wxColour (210, 210, 210, 128); } @@ -44,9 +44,16 @@ wxColour TimelineSubtitleContentView::foreground_colour () const { shared_ptr sc = _subtitle_content.lock (); - if (!sc || !sc->use_subtitles ()) { + if (!active ()) { return wxColour (180, 180, 180, 128); } return wxColour (0, 0, 0, 255); } + +bool +TimelineSubtitleContentView::active () const +{ + shared_ptr sc = _subtitle_content.lock (); + return sc && sc->use_subtitles(); +} diff --git a/src/wx/timeline_subtitle_content_view.h b/src/wx/timeline_subtitle_content_view.h index 42ba432f3..6b59912a3 100644 --- a/src/wx/timeline_subtitle_content_view.h +++ b/src/wx/timeline_subtitle_content_view.h @@ -30,6 +30,7 @@ public: TimelineSubtitleContentView (Timeline& tl, boost::shared_ptr c); private: + bool active () const; wxColour background_colour () const; wxColour foreground_colour () const; diff --git a/src/wx/timeline_time_axis_view.cc b/src/wx/timeline_time_axis_view.cc index 2667d9834..bbaf5fde2 100644 --- a/src/wx/timeline_time_axis_view.cc +++ b/src/wx/timeline_time_axis_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington + Copyright (C) 2013-2016 Carl Hetherington 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 @@ -22,6 +22,8 @@ #include #include +using std::list; + TimelineTimeAxisView::TimelineTimeAxisView (Timeline& tl, int y) : TimelineView (tl) , _y (y) @@ -43,7 +45,7 @@ TimelineTimeAxisView::set_y (int y) } void -TimelineTimeAxisView::do_paint (wxGraphicsContext* gc) +TimelineTimeAxisView::do_paint (wxGraphicsContext* gc, list >) { if (!_timeline.pixels_per_second()) { return; diff --git a/src/wx/timeline_time_axis_view.h b/src/wx/timeline_time_axis_view.h index f72acd4a7..fbd7c5de9 100644 --- a/src/wx/timeline_time_axis_view.h +++ b/src/wx/timeline_time_axis_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington + Copyright (C) 2013-2016 Carl Hetherington 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 @@ -28,7 +28,7 @@ public: void set_y (int y); private: - void do_paint (wxGraphicsContext* gc); + void do_paint (wxGraphicsContext* gc, std::list > overlaps); private: int _y; diff --git a/src/wx/timeline_video_content_view.h b/src/wx/timeline_video_content_view.h index 795c23006..6397ccdb3 100644 --- a/src/wx/timeline_video_content_view.h +++ b/src/wx/timeline_video_content_view.h @@ -28,6 +28,9 @@ public: TimelineVideoContentView (Timeline& tl, boost::shared_ptr c); private: + bool active () const { + return true; + } wxColour background_colour () const; wxColour foreground_colour () const; }; diff --git a/src/wx/timeline_view.cc b/src/wx/timeline_view.cc index fee1921ed..d96b8998f 100644 --- a/src/wx/timeline_view.cc +++ b/src/wx/timeline_view.cc @@ -20,6 +20,8 @@ #include "timeline_view.h" #include "timeline.h" +using std::list; + /** @class TimelineView * @brief Parent class for components of the timeline (e.g. a piece of content or an axis). */ @@ -30,10 +32,10 @@ TimelineView::TimelineView (Timeline& t) } void -TimelineView::paint (wxGraphicsContext* g) +TimelineView::paint (wxGraphicsContext* g, list > overlaps) { _last_paint_bbox = bbox (); - do_paint (g); + do_paint (g, overlaps); } void diff --git a/src/wx/timeline_view.h b/src/wx/timeline_view.h index 55fd64d51..01f1ca23d 100644 --- a/src/wx/timeline_view.h +++ b/src/wx/timeline_view.h @@ -36,13 +36,13 @@ public: TimelineView (Timeline& t); virtual ~TimelineView () {} - void paint (wxGraphicsContext* g); + void paint (wxGraphicsContext* g, std::list > overlaps); void force_redraw (); virtual dcpomatic::Rect bbox () const = 0; protected: - virtual void do_paint (wxGraphicsContext *) = 0; + virtual void do_paint (wxGraphicsContext *, std::list > overlaps) = 0; int time_x (DCPTime t) const; diff --git a/test/rect_test.cc b/test/rect_test.cc new file mode 100644 index 000000000..b2f70cf89 --- /dev/null +++ b/test/rect_test.cc @@ -0,0 +1,32 @@ +/* + Copyright (C) 2016 Carl Hetherington + + 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 "lib/rect.h" +#include +#include + +using boost::optional; + +BOOST_AUTO_TEST_CASE (rect_test) +{ + dcpomatic::Rect a (0, 0, 100, 100); + dcpomatic::Rect b (200, 200, 100, 100); + optional > c = a.intersection (b); + BOOST_CHECK (!c); +} diff --git a/test/wscript b/test/wscript index 5d468f68c..7efe6e61c 100644 --- a/test/wscript +++ b/test/wscript @@ -71,6 +71,7 @@ def build(bld): ratio_test.cc repeat_frame_test.cc recover_test.cc + rect_test.cc reels_test.cc required_disk_space_test.cc resampler_test.cc -- 2.30.2