+ if (i == _views.end ()) {
+ return shared_ptr<View> ();
+ }
+
+ return *i;
+}
+
+void
+Timeline::left_down (wxMouseEvent& ev)
+{
+ shared_ptr<View> view = event_to_view (ev);
+ shared_ptr<ContentView> content_view = dynamic_pointer_cast<ContentView> (view);
+
+ _down_view.reset ();
+
+ if (content_view) {
+ _down_view = content_view;
+ _down_view_position = content_view->content()->position ();
+ }
+
+ for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) {
+ shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (*i);
+ if (!cv) {
+ continue;
+ }
+
+ if (!ev.ShiftDown ()) {
+ cv->set_selected (view == *i);
+ }
+
+ if (view == *i) {
+ _film_editor->set_selection (cv->content ());
+ }
+ }
+
+ if (content_view && ev.ShiftDown ()) {
+ content_view->set_selected (!content_view->selected ());
+ }
+
+ _left_down = true;
+ _down_point = ev.GetPosition ();
+ _first_move = false;
+
+ if (_down_view) {
+ _down_view->content()->set_change_signals_frequent (true);
+ }
+}
+
+void
+Timeline::left_up (wxMouseEvent& ev)
+{
+ _left_down = false;
+
+ if (_down_view) {
+ _down_view->content()->set_change_signals_frequent (false);
+ }
+
+ set_position_from_event (ev);
+}
+
+void
+Timeline::mouse_moved (wxMouseEvent& ev)
+{
+ if (!_left_down) {
+ return;
+ }
+
+ set_position_from_event (ev);
+}
+
+void
+Timeline::right_down (wxMouseEvent& ev)
+{
+ shared_ptr<View> view = event_to_view (ev);
+ shared_ptr<ContentView> cv = dynamic_pointer_cast<ContentView> (view);
+ if (!cv) {
+ return;
+ }
+
+ if (!cv->selected ()) {
+ clear_selection ();
+ cv->set_selected (true);
+ }
+
+ _menu.popup (_film, selected_content (), ev.GetPosition ());
+}
+
+void
+Timeline::set_position_from_event (wxMouseEvent& ev)
+{
+ wxPoint const p = ev.GetPosition();
+
+ if (!_first_move) {
+ /* We haven't moved yet; in that case, we must move the mouse some reasonable distance
+ before the drag is considered to have started.
+ */
+ int const dist = sqrt (pow (p.x - _down_point.x, 2) + pow (p.y - _down_point.y, 2));
+ if (dist < 8) {
+ return;