, _video_frame_rate (24)
, _audio_channels (6)
, _three_d (false)
- , _sequence_video (true)
+ , _sequence (true)
, _interop (Config::instance()->default_interop ())
, _audio_processor (0)
, _reel_type (REELTYPE_SINGLE)
_log.reset (new NullLog);
}
- _playlist->set_sequence_video (_sequence_video);
+ _playlist->set_sequence (_sequence);
}
Film::~Film ()
root->add_child("ISDCFDate")->add_child_text (boost::gregorian::to_iso_string (_isdcf_date));
root->add_child("AudioChannels")->add_child_text (raw_convert<string> (_audio_channels));
root->add_child("ThreeD")->add_child_text (_three_d ? "1" : "0");
- root->add_child("SequenceVideo")->add_child_text (_sequence_video ? "1" : "0");
+ root->add_child("Sequence")->add_child_text (_sequence ? "1" : "0");
root->add_child("Interop")->add_child_text (_interop ? "1" : "0");
root->add_child("Signed")->add_child_text (_signed ? "1" : "0");
root->add_child("Encrypted")->add_child_text (_encrypted ? "1" : "0");
} else if ((_audio_channels % 2) == 1) {
_audio_channels++;
}
- _sequence_video = f.bool_child ("SequenceVideo");
+
+ if (f.optional_bool_child("SequenceVideo")) {
+ _sequence = f.bool_child("SequenceVideo");
+ } else {
+ _sequence = f.bool_child("Sequence");
+ }
+
_three_d = f.bool_child ("ThreeD");
_interop = f.bool_child ("Interop");
_key = dcp::Key (f.string_child ("Key"));
set_video_frame_rate (_playlist->best_dcp_frame_rate ());
break;
case Film::VIDEO_FRAME_RATE:
- case Film::SEQUENCE_VIDEO:
- _playlist->maybe_sequence_video ();
+ case Film::SEQUENCE:
+ _playlist->maybe_sequence ();
break;
default:
break;
void
Film::add_content (shared_ptr<Content> c)
{
- /* Add video content after any existing content */
+ /* Add {video,subtitle} content after any existing {video,subtitle} content */
if (dynamic_pointer_cast<VideoContent> (c)) {
c->set_position (_playlist->video_end ());
+ } else if (dynamic_pointer_cast<SubtitleContent> (c)) {
+ c->set_position (_playlist->subtitle_end ());
}
_playlist->add (c);
}
void
-Film::set_sequence_video (bool s)
+Film::set_sequence (bool s)
{
- _sequence_video = s;
- _playlist->set_sequence_video (s);
- signal_changed (SEQUENCE_VIDEO);
+ _sequence = s;
+ _playlist->set_sequence (s);
+ signal_changed (SEQUENCE);
}
/** @return Size of the largest possible image in whatever resolution we are using */
AUDIO_CHANNELS,
/** The setting of _three_d has changed */
THREE_D,
- SEQUENCE_VIDEO,
+ SEQUENCE,
INTEROP,
AUDIO_PROCESSOR,
REEL_TYPE,
return _three_d;
}
- bool sequence_video () const {
- return _sequence_video;
+ bool sequence () const {
+ return _sequence;
}
bool interop () const {
void set_audio_channels (int);
void set_three_d (bool);
void set_isdcf_date_today ();
- void set_sequence_video (bool);
+ void set_sequence (bool);
void set_interop (bool);
void set_audio_processor (AudioProcessor const * processor);
void set_reel_type (ReelType);
This will be regardless of what content is on the playlist.
*/
bool _three_d;
- bool _sequence_video;
+ bool _sequence;
bool _interop;
AudioProcessor const * _audio_processor;
ReelType _reel_type;
using boost::dynamic_pointer_cast;
Playlist::Playlist ()
- : _sequence_video (true)
- , _sequencing_video (false)
+ : _sequence (true)
+ , _sequencing (false)
{
}
- any other position changes will be timeline drags which should not result in content
being sequenced.
*/
- maybe_sequence_video ();
+ maybe_sequence ();
}
if (
}
void
-Playlist::maybe_sequence_video ()
+Playlist::maybe_sequence ()
{
- if (!_sequence_video || _sequencing_video) {
+ if (!_sequence || _sequencing) {
return;
}
- _sequencing_video = true;
+ _sequencing = true;
+
+ /* Video */
DCPTime next_left;
DCPTime next_right;
}
}
+ /* Subtitles */
+
+ DCPTime next;
+ BOOST_FOREACH (shared_ptr<Content> i, _content) {
+ shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (i);
+ if (!sc) {
+ continue;
+ }
+
+ sc->set_position (next);
+ next = sc->end();
+ }
+
+
/* This won't change order, so it does not need a sort */
- _sequencing_video = false;
+ _sequencing = false;
}
string
return end;
}
+DCPTime
+Playlist::subtitle_end () const
+{
+ DCPTime end;
+ BOOST_FOREACH (shared_ptr<Content> i, _content) {
+ if (dynamic_pointer_cast<const SubtitleContent> (i)) {
+ end = max (end, i->end ());
+ }
+ }
+
+ return end;
+}
+
FrameRateChange
Playlist::active_frame_rate_change (DCPTime t, int dcp_video_frame_rate) const
{
}
void
-Playlist::set_sequence_video (bool s)
+Playlist::set_sequence (bool s)
{
- _sequence_video = s;
+ _sequence = s;
}
bool
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
int best_dcp_frame_rate () const;
DCPTime video_end () const;
+ DCPTime subtitle_end () const;
FrameRateChange active_frame_rate_change (DCPTime, int dcp_frame_rate) const;
- void set_sequence_video (bool);
- void maybe_sequence_video ();
+ void set_sequence (bool);
+ void maybe_sequence ();
void repeat (ContentList, int);
/** List of content. Kept sorted in position order. */
ContentList _content;
- bool _sequence_video;
- bool _sequencing_video;
+ bool _sequence;
+ bool _sequencing;
std::list<boost::signals2::connection> _content_connections;
};
void
ContentPanel::selection_changed ()
{
+ if (_last_selected == selected()) {
+ /* This was triggered by a re-build of the view but the selection
+ did not really change.
+ */
+ return;
+ }
+
+ _last_selected = selected ();
+
setup_sensitivity ();
BOOST_FOREACH (ContentSubPanel* i, _panels) {
ContentMenu* _menu;
TimelineDialog* _timeline_dialog;
wxNotebook* _parent;
+ ContentList _last_selected;
boost::shared_ptr<Film> _film;
FilmViewer* _film_viewer;
film_changed (Film::ISDCF_METADATA);
film_changed (Film::VIDEO_FRAME_RATE);
film_changed (Film::AUDIO_CHANNELS);
- film_changed (Film::SEQUENCE_VIDEO);
+ film_changed (Film::SEQUENCE);
film_changed (Film::THREE_D);
film_changed (Film::INTEROP);
film_changed (Film::AUDIO_PROCESSOR);
/*
- Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
SetMinSize (wxSize (640, tracks() * track_height() + 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));
+ _film_content_changed_connection = film->ContentChanged.connect (bind (&Timeline::film_content_changed, this, _2, _3));
}
void
ensure_ui_thread ();
recreate_views ();
} else if (p == Film::CONTENT_ORDER) {
- assign_tracks ();
- if (!_left_down) {
- /* Only do this if we are not dragging, as it's confusing otherwise */
- setup_pixels_per_second ();
- }
Refresh ();
}
}
}
void
-Timeline::film_content_changed (int property)
+Timeline::film_content_changed (int property, bool frequent)
{
ensure_ui_thread ();
if (property == AudioContentProperty::AUDIO_STREAMS) {
recreate_views ();
+ } else if (!frequent) {
+ setup_pixels_per_second ();
+ Refresh ();
}
}
set_position_from_event (ev);
- /* We don't do this during drag, and set_position_from_event above
- might not have changed the position, so do it now.
- */
+ /* Clear up up the stuff we don't do during drag */
+ assign_tracks ();
setup_pixels_per_second ();
Refresh ();
shared_ptr<Film> film = _film.lock ();
DCPOMATIC_ASSERT (film);
- film->set_sequence_video (false);
+ film->set_sequence (false);
}
void
void right_down (wxMouseEvent &);
void mouse_moved (wxMouseEvent &);
void film_changed (Film::Property);
- void film_content_changed (int);
+ void film_content_changed (int, bool frequent);
void resized ();
void assign_tracks ();
void set_position_from_event (wxMouseEvent &);
, _content (c)
, _selected (false)
{
- _content_connection = c->Changed.connect (bind (&TimelineContentView::content_changed, this, _2, _3));
+ _content_connection = c->Changed.connect (bind (&TimelineContentView::content_changed, this, _2));
}
dcpomatic::Rect<int>
}
void
-TimelineContentView::content_changed (int p, bool frequent)
+TimelineContentView::content_changed (int p)
{
ensure_ui_thread ();
if (p == ContentProperty::POSITION || p == ContentProperty::LENGTH) {
force_redraw ();
}
-
- if (!frequent) {
- _timeline.setup_pixels_per_second ();
- _timeline.Refresh ();
- }
}
void do_paint (wxGraphicsContext* gc);
int y_pos (int t) const;
- void content_changed (int p, bool frequent);
+ void content_changed (int p);
boost::weak_ptr<Content> _content;
boost::optional<int> _track;
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
wxBoxSizer* controls = new wxBoxSizer (wxHORIZONTAL);
_snap = new wxCheckBox (this, wxID_ANY, _("Snap"));
controls->Add (_snap);
- _sequence_video = new wxCheckBox (this, wxID_ANY, _("Keep video in sequence"));
- controls->Add (_sequence_video, 1, wxLEFT, 12);
+ _sequence = new wxCheckBox (this, wxID_ANY, _("Keep video and subtitles in sequence"));
+ controls->Add (_sequence, 1, wxLEFT, 12);
sizer->Add (controls, 0, wxALL, 12);
sizer->Add (&_timeline, 1, wxEXPAND | wxALL, 12);
_snap->SetValue (_timeline.snap ());
_snap->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&TimelineDialog::snap_toggled, this));
- film_changed (Film::SEQUENCE_VIDEO);
- _sequence_video->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&TimelineDialog::sequence_video_toggled, this));
+ film_changed (Film::SEQUENCE);
+ _sequence->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&TimelineDialog::sequence_toggled, this));
_film_changed_connection = film->Changed.connect (bind (&TimelineDialog::film_changed, this, _1));
}
}
void
-TimelineDialog::sequence_video_toggled ()
+TimelineDialog::sequence_toggled ()
{
shared_ptr<Film> film = _film.lock ();
if (!film) {
return;
}
- film->set_sequence_video (_sequence_video->GetValue ());
+ film->set_sequence (_sequence->GetValue ());
}
void
return;
}
- if (p == Film::SEQUENCE_VIDEO) {
- _sequence_video->SetValue (film->sequence_video ());
+ if (p == Film::SEQUENCE) {
+ _sequence->SetValue (film->sequence ());
}
}
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 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
private:
void snap_toggled ();
- void sequence_video_toggled ();
+ void sequence_toggled ();
void film_changed (Film::Property);
boost::weak_ptr<Film> _film;
Timeline _timeline;
wxCheckBox* _snap;
- wxCheckBox* _sequence_video;
+ wxCheckBox* _sequence;
boost::signals2::scoped_connection _film_changed_connection;
};
film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR"));
film->set_name ("black_fill_test");
film->set_container (Ratio::from_id ("185"));
- film->set_sequence_video (false);
+ film->set_sequence (false);
shared_ptr<ImageContent> contentA (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
shared_ptr<ImageContent> contentB (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
check_dcp (ref.string(), check.string());
}
-
list<string> notes;
shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
- film->set_sequence_video (false);
+ film->set_sequence (false);
film->add_content (content);
shared_ptr<Player> player (new Player (film, film->playlist ()));
list<string> notes;
shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
- film->set_sequence_video (false);
+ film->set_sequence (false);
film->add_content (content);
shared_ptr<Player> player (new Player (film, film->playlist ()));
list<string> notes;
shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
AudioStreamPtr stream = content->audio_streams().front();
- film->set_sequence_video (false);
+ film->set_sequence (false);
film->add_content (content);
shared_ptr<Player> player (new Player (film, film->playlist ()));