summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-19 15:22:26 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-19 15:22:26 +0100
commit56506a1993f402fe889a650faa3de2e265632498 (patch)
treeea8b0f404dbfaf3def2592e6192280ab37338049 /src
parent3857b8b178d94873a6ffc6f51cdb4c241fd54f90 (diff)
Add remove option; resize timeline after drags.
Diffstat (limited to 'src')
-rw-r--r--src/lib/film.cc2
-rw-r--r--src/lib/film.h2
-rw-r--r--src/lib/player.cc4
-rw-r--r--src/lib/playlist.cc25
-rw-r--r--src/lib/playlist.h5
-rw-r--r--src/lib/types.h1
-rw-r--r--src/wx/film_editor.cc8
-rw-r--r--src/wx/timeline.cc79
-rw-r--r--src/wx/timeline.h13
9 files changed, 98 insertions, 41 deletions
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 172fd20ab..d5a5abae4 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -728,7 +728,7 @@ Film::playlist () const
return _playlist;
}
-Playlist::ContentList
+ContentList
Film::content () const
{
return _playlist->content ();
diff --git a/src/lib/film.h b/src/lib/film.h
index 497320c5e..51db8ce00 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -106,7 +106,7 @@ public:
/* Proxies for some Playlist methods */
- Playlist::ContentList content () const;
+ ContentList content () const;
Time length () const;
bool has_subtitles () const;
diff --git a/src/lib/player.cc b/src/lib/player.cc
index ec20892ef..d3d5d0f6b 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -401,10 +401,10 @@ Player::setup_pieces ()
_pieces.clear ();
- Playlist::ContentList content = _playlist->content ();
+ ContentList content = _playlist->content ();
sort (content.begin(), content.end(), ContentSorter ());
- for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
+ for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
shared_ptr<Piece> piece (new Piece (*i));
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index e4494acb0..c9d05b049 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -158,6 +158,23 @@ Playlist::remove (shared_ptr<Content> c)
}
}
+void
+Playlist::remove (ContentList c)
+{
+ for (ContentList::iterator i = c.begin(); i != c.end(); ++i) {
+ ContentList::iterator j = _content.begin ();
+ while (j != _content.end() && *j != *i) {
+ ++j;
+ }
+
+ if (j != _content.end ()) {
+ _content.erase (j);
+ }
+ }
+
+ Changed ();
+}
+
bool
Playlist::has_subtitles () const
{
@@ -285,17 +302,17 @@ ContentSorter::operator() (shared_ptr<Content> a, shared_ptr<Content> b)
}
/** @return content in an undefined order */
-Playlist::ContentList
+ContentList
Playlist::content () const
{
return _content;
}
void
-Playlist::repeat (list<shared_ptr<Content> > c, int n)
+Playlist::repeat (ContentList c, int n)
{
pair<Time, Time> range (TIME_MAX, 0);
- for (list<shared_ptr<Content> >::iterator i = c.begin(); i != c.end(); ++i) {
+ for (ContentList::iterator i = c.begin(); i != c.end(); ++i) {
range.first = min (range.first, (*i)->start ());
range.second = max (range.second, (*i)->start ());
range.first = min (range.first, (*i)->end ());
@@ -304,7 +321,7 @@ Playlist::repeat (list<shared_ptr<Content> > c, int n)
Time pos = range.second;
for (int i = 0; i < n; ++i) {
- for (list<shared_ptr<Content> >::iterator i = c.begin(); i != c.end(); ++i) {
+ for (ContentList::iterator i = c.begin(); i != c.end(); ++i) {
shared_ptr<Content> copy = (*i)->clone ();
copy->set_start (pos + copy->start() - range.first);
_content.push_back (copy);
diff --git a/src/lib/playlist.h b/src/lib/playlist.h
index 1d69c34ba..e39e9f51f 100644
--- a/src/lib/playlist.h
+++ b/src/lib/playlist.h
@@ -60,11 +60,10 @@ public:
void add (boost::shared_ptr<Content>);
void remove (boost::shared_ptr<Content>);
+ void remove (ContentList);
bool has_subtitles () const;
- typedef std::vector<boost::shared_ptr<Content> > ContentList;
-
ContentList content () const;
std::string video_identifier () const;
@@ -77,7 +76,7 @@ public:
void set_sequence_video (bool);
void maybe_sequence_video ();
- void repeat (std::list<boost::shared_ptr<Content> >, int);
+ void repeat (ContentList, int);
mutable boost::signals2::signal<void ()> Changed;
/** Third parameter is true if signals are currently being emitted frequently */
diff --git a/src/lib/types.h b/src/lib/types.h
index aeaa82ec6..458a2ecf3 100644
--- a/src/lib/types.h
+++ b/src/lib/types.h
@@ -32,6 +32,7 @@ typedef int64_t Time;
#define TIME_HZ ((Time) 96000)
typedef int64_t OutputAudioFrame;
typedef int OutputVideoFrame;
+typedef std::vector<boost::shared_ptr<Content> > ContentList;
/** @struct Crop
* @brief A description of the crop of an image or video.
diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc
index f087bf84c..bfef303a8 100644
--- a/src/wx/film_editor.cc
+++ b/src/wx/film_editor.cc
@@ -1132,8 +1132,8 @@ FilmEditor::setup_content ()
_content->DeleteAllItems ();
- Playlist::ContentList content = _film->content ();
- for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
+ ContentList content = _film->content ();
+ for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
int const t = _content->GetItemCount ();
_content->InsertItem (t, std_to_wx ((*i)->summary ()));
if ((*i)->summary() == selected_summary) {
@@ -1240,7 +1240,7 @@ FilmEditor::selected_content ()
return shared_ptr<Content> ();
}
- Playlist::ContentList c = _film->content ();
+ ContentList c = _film->content ();
if (s < 0 || size_t (s) >= c.size ()) {
return shared_ptr<Content> ();
}
@@ -1466,7 +1466,7 @@ FilmEditor::length_changed ()
void
FilmEditor::set_selection (weak_ptr<Content> wc)
{
- Playlist::ContentList content = _film->content ();
+ ContentList content = _film->content ();
for (size_t i = 0; i < content.size(); ++i) {
if (content[i] == wc.lock ()) {
_content->SetItemState (i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc
index 7d0ce660c..116ff8191 100644
--- a/src/wx/timeline.cc
+++ b/src/wx/timeline.cc
@@ -81,7 +81,7 @@ public:
, _track (t)
, _selected (false)
{
- _content_connection = c->Changed.connect (bind (&ContentView::content_changed, this, _2));
+ _content_connection = c->Changed.connect (bind (&ContentView::content_changed, this, _2, _3));
}
dcpomatic::Rect<int> bbox () const
@@ -174,11 +174,16 @@ private:
return _timeline.tracks_position().y + t * _timeline.track_height();
}
- void content_changed (int p)
+ void content_changed (int p, bool frequent)
{
if (p == ContentProperty::START || p == ContentProperty::LENGTH) {
force_redraw ();
}
+
+ if (!frequent) {
+ _timeline.setup_pixels_per_time_unit ();
+ _timeline.Refresh ();
+ }
}
boost::weak_ptr<Content> _content;
@@ -314,7 +319,8 @@ private:
};
enum {
- ID_repeat
+ ID_repeat,
+ ID_remove
};
Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr<Film> film)
@@ -339,7 +345,9 @@ Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr<Film> film)
Connect (wxID_ANY, wxEVT_RIGHT_DOWN, wxMouseEventHandler (Timeline::right_down), 0, this);
Connect (wxID_ANY, wxEVT_MOTION, wxMouseEventHandler (Timeline::mouse_moved), 0, this);
Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (Timeline::resized), 0, this);
+
Connect (ID_repeat, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Timeline::repeat), 0, this);
+ Connect (ID_remove, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Timeline::remove), 0, this);
playlist_changed ();
@@ -360,7 +368,7 @@ Timeline::paint (wxPaintEvent &)
gc->SetFont (gc->CreateFont (*wxNORMAL_FONT));
- for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
(*i)->paint (gc);
}
@@ -378,9 +386,9 @@ Timeline::playlist_changed ()
_views.clear ();
_views.push_back (_time_axis_view);
- Playlist::ContentList content = fl->playlist()->content ();
+ ContentList content = fl->playlist()->content ();
- for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) {
+ for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
if (dynamic_pointer_cast<VideoContent> (*i)) {
_views.push_back (shared_ptr<View> (new VideoContentView (*this, *i, 0)));
}
@@ -397,7 +405,7 @@ Timeline::playlist_changed ()
void
Timeline::assign_tracks ()
{
- for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
if (cv) {
cv->set_track (0);
@@ -405,7 +413,7 @@ Timeline::assign_tracks ()
}
}
- for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
shared_ptr<AudioContentView> acv = dynamic_pointer_cast<AudioContentView> (*i);
if (!acv) {
continue;
@@ -415,7 +423,7 @@ Timeline::assign_tracks ()
int t = 1;
while (1) {
- list<shared_ptr<View> >::iterator j = _views.begin();
+ ViewList::iterator j = _views.begin();
while (j != _views.end()) {
shared_ptr<AudioContentView> test = dynamic_pointer_cast<AudioContentView> (*j);
if (!test) {
@@ -470,7 +478,7 @@ Timeline::setup_pixels_per_time_unit ()
shared_ptr<View>
Timeline::event_to_view (wxMouseEvent& ev)
{
- list<shared_ptr<View> >::iterator i = _views.begin();
+ ViewList::iterator i = _views.begin();
Position<int> const p (ev.GetX(), ev.GetY());
while (i != _views.end() && !(*i)->bbox().contains (p)) {
++i;
@@ -496,7 +504,7 @@ Timeline::left_down (wxMouseEvent& ev)
_down_view_start = content_view->content()->start ();
}
- for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
if (!cv) {
continue;
@@ -563,6 +571,8 @@ Timeline::right_down (wxMouseEvent& ev)
if (!_menu) {
_menu = new wxMenu;
_menu->Append (ID_repeat, _("Repeat..."));
+ _menu->AppendSeparator ();
+ _menu->Append (ID_remove, _("Remove"));
}
PopupMenu (_menu, ev.GetPosition ());
@@ -612,7 +622,7 @@ Timeline::resized (wxSizeEvent &)
void
Timeline::clear_selection ()
{
- for (list<shared_ptr<View> >::iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
if (cv) {
cv->set_selected (false);
@@ -623,7 +633,7 @@ Timeline::clear_selection ()
void
Timeline::repeat (wxCommandEvent &)
{
- list<shared_ptr<ContentView> > sel = selected ();
+ ContentList sel = selected_content ();
if (sel.empty ()) {
return;
}
@@ -636,21 +646,32 @@ Timeline::repeat (wxCommandEvent &)
return;
}
- list<shared_ptr<Content> > content;
- for (list<shared_ptr<ContentView> >::iterator i = sel.begin(); i != sel.end(); ++i) {
- content.push_back ((*i)->content ());
+ film->playlist()->repeat (sel, d.number ());
+ d.Destroy ();
+}
+
+void
+Timeline::remove (wxCommandEvent &)
+{
+ ContentList sel = selected_content ();
+ if (sel.empty ()) {
+ return;
}
- film->playlist()->repeat (content, d.number ());
- d.Destroy ();
+ shared_ptr<const Film> film = _film.lock ();
+ if (!film) {
+ return;
+ }
+
+ film->playlist()->remove (sel);
}
-list<shared_ptr<ContentView> >
-Timeline::selected () const
+Timeline::ContentViewList
+Timeline::selected_views () const
{
- list<shared_ptr<ContentView> > sel;
+ ContentViewList sel;
- for (list<shared_ptr<View> >::const_iterator i = _views.begin(); i != _views.end(); ++i) {
+ for (ViewList::const_iterator i = _views.begin(); i != _views.end(); ++i) {
shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
if (cv && cv->selected()) {
sel.push_back (cv);
@@ -659,4 +680,16 @@ Timeline::selected () const
return sel;
}
-
+
+ContentList
+Timeline::selected_content () const
+{
+ ContentList sel;
+ ContentViewList views = selected_views ();
+
+ for (ContentViewList::const_iterator i = views.begin(); i != views.end(); ++i) {
+ sel.push_back ((*i)->content ());
+ }
+
+ return sel;
+}
diff --git a/src/wx/timeline.h b/src/wx/timeline.h
index 99094788f..48eaa9d76 100644
--- a/src/wx/timeline.h
+++ b/src/wx/timeline.h
@@ -61,6 +61,8 @@ public:
int tracks () const;
+ void setup_pixels_per_time_unit ();
+
private:
void paint (wxPaintEvent &);
void left_down (wxMouseEvent &);
@@ -68,19 +70,24 @@ private:
void right_down (wxMouseEvent &);
void mouse_moved (wxMouseEvent &);
void playlist_changed ();
- void setup_pixels_per_time_unit ();
void resized (wxSizeEvent &);
void assign_tracks ();
void set_start_from_event (wxMouseEvent &);
void clear_selection ();
+
void repeat (wxCommandEvent &);
+ void remove (wxCommandEvent &);
+
+ typedef std::vector<boost::shared_ptr<View> > ViewList;
+ typedef std::vector<boost::shared_ptr<ContentView> > ContentViewList;
boost::shared_ptr<View> event_to_view (wxMouseEvent &);
- std::list<boost::shared_ptr<ContentView> > selected () const;
+ ContentViewList selected_views () const;
+ ContentList selected_content () const;
FilmEditor* _film_editor;
boost::weak_ptr<Film> _film;
- std::list<boost::shared_ptr<View> > _views;
+ ViewList _views;
boost::shared_ptr<TimeAxisView> _time_axis_view;
int _tracks;
double _pixels_per_time_unit;