using std::cout;
using std::min;
using std::max;
+using std::abs;
using boost::shared_ptr;
using boost::weak_ptr;
using boost::dynamic_pointer_cast;
using boost::bind;
using boost::optional;
+using namespace dcpomatic;
/* 3 hours in 640 pixels */
double const Timeline::_minimum_pixels_per_second = 640.0 / (60 * 60 * 3);
_main_canvas->Bind (wxEVT_SCROLLWIN_PAGEDOWN, boost::bind (&Timeline::scrolled, this, _1));
_main_canvas->Bind (wxEVT_SCROLLWIN_THUMBTRACK, boost::bind (&Timeline::scrolled, this, _1));
- film_changed (Film::CONTENT);
+ film_change (CHANGE_TYPE_DONE, Film::CONTENT);
SetMinSize (wxSize (640, 4 * pixels_per_track() + 96));
- _film_changed_connection = film->Changed.connect (bind (&Timeline::film_changed, this, _1));
- _film_content_changed_connection = film->ContentChanged.connect (bind (&Timeline::film_content_changed, this, _2, _3));
+ _film_changed_connection = film->Change.connect (bind (&Timeline::film_change, this, _1, _2));
+ _film_content_change_connection = film->ContentChange.connect (bind (&Timeline::film_content_change, this, _1, _3, _4));
setup_scrollbars ();
_labels_canvas->ShowScrollbars (wxSHOW_SB_NEVER, wxSHOW_SB_NEVER);
gc->DrawRectangle (
min (_down_point.x, _zoom_point->x),
min (_down_point.y, _zoom_point->y),
- fabs (_down_point.x - _zoom_point->x),
- fabs (_down_point.y - _zoom_point->y)
+ abs (_down_point.x - _zoom_point->x),
+ abs (_down_point.y - _zoom_point->y)
);
}
}
void
-Timeline::film_changed (Film::Property p)
+Timeline::film_change (ChangeType type, Film::Property p)
{
+ if (type != CHANGE_TYPE_DONE) {
+ return;
+ }
+
if (p == Film::CONTENT || p == Film::REEL_TYPE || p == Film::REEL_LENGTH) {
ensure_ui_thread ();
recreate_views ();
}
void
-Timeline::film_content_changed (int property, bool frequent)
+Timeline::film_content_change (ChangeType type, int property, bool frequent)
{
+ if (type != CHANGE_TYPE_DONE) {
+ return;
+ }
+
ensure_ui_thread ();
- if (property == AudioContentProperty::STREAMS) {
+ if (property == AudioContentProperty::STREAMS || property == VideoContentProperty::FRAME_TYPE) {
recreate_views ();
} else if (property == ContentProperty::POSITION || property == ContentProperty::LENGTH) {
_reels_view->force_redraw ();
template <class T>
int
-place (TimelineViewList& views, int& tracks)
+place (shared_ptr<const Film> film, TimelineViewList& views, int& tracks)
{
int const base = tracks;
int t = base;
shared_ptr<Content> content = cv->content();
- DCPTimePeriod const content_period (content->position(), content->end());
+ DCPTimePeriod const content_period (content->position(), content->end(film));
while (true) {
TimelineViewList::iterator j = views.begin();
shared_ptr<Content> test_content = test->content();
if (
test->track() && test->track().get() == t &&
- content_period.overlap(DCPTimePeriod(test_content->position(), test_content->end()))) {
+ content_period.overlap(DCPTimePeriod(test_content->position(), test_content->end(film)))) {
/* we have an overlap on track `t' */
++t;
break;
Audio N
*/
+ shared_ptr<const Film> film = _film.lock ();
+ DCPOMATIC_ASSERT (film);
+
_tracks = 0;
for (TimelineViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
/* Texts */
- int const text_tracks = place<TimelineTextContentView> (_views, _tracks);
+ int const text_tracks = place<TimelineTextContentView> (film, _views, _tracks);
/* Atmos */
TimelineViewList views = _views;
sort(views.begin(), views.end(), AudioMappingComparator());
- int const audio_tracks = place<TimelineAudioContentView> (views, _tracks);
+ int const audio_tracks = place<TimelineAudioContentView> (film, views, _tracks);
_labels_view->set_3d (have_3d);
_labels_view->set_audio_tracks (audio_tracks);
continue;
}
+ shared_ptr<Film> film = _film.lock ();
+ DCPOMATIC_ASSERT (film);
+
_start_snaps.push_back (cv->content()->position());
_end_snaps.push_back (cv->content()->position());
- _start_snaps.push_back (cv->content()->end());
- _end_snaps.push_back (cv->content()->end());
+ _start_snaps.push_back (cv->content()->end(film));
+ _end_snaps.push_back (cv->content()->end(film));
- BOOST_FOREACH (DCPTime i, cv->content()->reel_split_points()) {
+ BOOST_FOREACH (DCPTime i, cv->content()->reel_split_points(film)) {
_start_snaps.push_back (i);
}
}
}
_content_panel->set_selection (selected_content ());
- set_position_from_event (ev);
+ /* Since we may have just set change signals back to `not-frequent', we have to
+ make sure this position change is signalled, even if the position value has
+ not changed since the last time it was set (with frequent=true). This is
+ a bit of a hack.
+ */
+ set_position_from_event (ev, true);
/* Clear up up the stuff we don't do during drag */
assign_tracks ();
}
void
-Timeline::set_position_from_event (wxMouseEvent& ev)
+Timeline::set_position_from_event (wxMouseEvent& ev, bool force_emit)
{
if (!_pixels_per_second) {
return;
DCPTime new_position = _down_view_position + DCPTime::from_seconds ((p.x - _down_point.x) / pps);
- if (_snap) {
+ shared_ptr<Film> film = _film.lock ();
+ DCPOMATIC_ASSERT (film);
- DCPTime const new_end = new_position + _down_view->content()->length_after_trim();
+ if (_snap) {
+ DCPTime const new_end = new_position + _down_view->content()->length_after_trim(film);
/* Signed `distance' to nearest thing (i.e. negative is left on the timeline,
positive is right).
*/
new_position = DCPTime ();
}
- _down_view->content()->set_position (new_position);
+ _down_view->content()->set_position (film, new_position, force_emit);
- shared_ptr<Film> film = _film.lock ();
- DCPOMATIC_ASSERT (film);
film->set_sequence (false);
}