X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Ftimeline.cc;h=e04d9ee744e94f83f4cf5354cfc6e150f65d5910;hb=659a80afd870d4432540fe76d6b5a919437d4cca;hp=8b0e4762a6ac9f6b888bb9190b23c9da686cb4ef;hpb=ec7c27b80a07bffcdb175512fa6d3811c277d959;p=dcpomatic.git diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 8b0e4762a..e04d9ee74 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -33,7 +33,9 @@ using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; using boost::bind; +using boost::optional; +/** Parent class for components of the timeline (e.g. a piece of content or an axis) */ class View : public boost::noncopyable { public: @@ -42,6 +44,8 @@ public: { } + + virtual ~View () {} void paint (wxGraphicsContext* g) { @@ -71,6 +75,8 @@ private: dcpomatic::Rect _last_paint_bbox; }; + +/** Parent class for views of pieces of content */ class ContentView : public View { public: @@ -92,9 +98,9 @@ public: } return dcpomatic::Rect ( - time_x (content->start ()) - 8, + time_x (content->position ()) - 8, y_pos (_track) - 8, - content->length () * _timeline.pixels_per_time_unit() + 16, + content->length_after_trim () * _timeline.pixels_per_time_unit() + 16, _timeline.track_height() + 16 ); } @@ -133,8 +139,8 @@ private: return; } - Time const start = cont->start (); - Time const len = cont->length (); + Time const position = cont->position (); + Time const len = cont->length_after_trim (); wxColour selected (colour().Red() / 2, colour().Green() / 2, colour().Blue() / 2); @@ -148,11 +154,11 @@ private: } wxGraphicsPath path = gc->CreatePath (); - path.MoveToPoint (time_x (start), y_pos (_track) + 4); - path.AddLineToPoint (time_x (start + len), y_pos (_track) + 4); - path.AddLineToPoint (time_x (start + len), y_pos (_track + 1) - 4); - path.AddLineToPoint (time_x (start), y_pos (_track + 1) - 4); - path.AddLineToPoint (time_x (start), y_pos (_track) + 4); + path.MoveToPoint (time_x (position), y_pos (_track) + 4); + path.AddLineToPoint (time_x (position + len), y_pos (_track) + 4); + path.AddLineToPoint (time_x (position + len), y_pos (_track + 1) - 4); + path.AddLineToPoint (time_x (position), y_pos (_track + 1) - 4); + path.AddLineToPoint (time_x (position), y_pos (_track) + 4); gc->StrokePath (path); gc->FillPath (path); @@ -163,8 +169,8 @@ private: wxDouble name_leading; gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading); - gc->Clip (wxRegion (time_x (start), y_pos (_track), len * _timeline.pixels_per_time_unit(), _timeline.track_height())); - gc->DrawText (name, time_x (start) + 12, y_pos (_track + 1) - name_height - 4); + gc->Clip (wxRegion (time_x (position), y_pos (_track), len * _timeline.pixels_per_time_unit(), _timeline.track_height())); + gc->DrawText (name, time_x (position) + 12, y_pos (_track + 1) - name_height - 4); gc->ResetClip (); } @@ -177,7 +183,7 @@ private: { ensure_ui_thread (); - if (p == ContentProperty::START || p == ContentProperty::LENGTH) { + if (p == ContentProperty::POSITION || p == ContentProperty::LENGTH) { force_redraw (); } @@ -319,6 +325,7 @@ private: int _y; }; + Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr film) : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) , _film_editor (ed) @@ -327,20 +334,21 @@ Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr film) , _tracks (0) , _pixels_per_time_unit (0) , _left_down (false) - , _down_view_start (0) + , _down_view_position (0) , _first_move (false) , _menu (film, this) + , _snap (true) { #ifndef __WXOSX__ SetDoubleBuffered (true); #endif - Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (Timeline::paint), 0, this); - Connect (wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler (Timeline::left_down), 0, this); - Connect (wxID_ANY, wxEVT_LEFT_UP, wxMouseEventHandler (Timeline::left_up), 0, this); - 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); + Bind (wxEVT_PAINT, boost::bind (&Timeline::paint, this)); + Bind (wxEVT_LEFT_DOWN, boost::bind (&Timeline::left_down, this, _1)); + Bind (wxEVT_LEFT_UP, boost::bind (&Timeline::left_up, this, _1)); + Bind (wxEVT_RIGHT_DOWN, boost::bind (&Timeline::right_down, this, _1)); + Bind (wxEVT_MOTION, boost::bind (&Timeline::mouse_moved, this, _1)); + Bind (wxEVT_SIZE, boost::bind (&Timeline::resized, this)); playlist_changed (); @@ -350,7 +358,7 @@ Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr film) } void -Timeline::paint (wxPaintEvent &) +Timeline::paint () { wxPaintDC dc (this); @@ -430,8 +438,8 @@ Timeline::assign_tracks () if (test && test->track() == t) { bool const no_overlap = - (acv_content->start() < test_content->start() && acv_content->end() < test_content->start()) || - (acv_content->start() > test_content->end() && acv_content->end() > test_content->end()); + (acv_content->position() < test_content->position() && acv_content->end() < test_content->position()) || + (acv_content->position() > test_content->end() && acv_content->end() > test_content->end()); if (!no_overlap) { /* we have an overlap on track `t' */ @@ -499,7 +507,7 @@ Timeline::left_down (wxMouseEvent& ev) if (content_view) { _down_view = content_view; - _down_view_start = content_view->content()->start (); + _down_view_position = content_view->content()->position (); } for (ViewList::iterator i = _views.begin(); i != _views.end(); ++i) { @@ -539,7 +547,7 @@ Timeline::left_up (wxMouseEvent& ev) _down_view->content()->set_change_signals_frequent (false); } - set_start_from_event (ev); + set_position_from_event (ev); } void @@ -549,7 +557,7 @@ Timeline::mouse_moved (wxMouseEvent& ev) return; } - set_start_from_event (ev); + set_position_from_event (ev); } void @@ -570,11 +578,14 @@ Timeline::right_down (wxMouseEvent& ev) } void -Timeline::set_start_from_event (wxMouseEvent& ev) +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; @@ -582,14 +593,63 @@ Timeline::set_start_from_event (wxMouseEvent& ev) _first_move = true; } - Time const time_diff = (p.x - _down_point.x) / _pixels_per_time_unit; - if (_down_view) { - _down_view->content()->set_start (max (static_cast