+private:
+
+ void do_paint (wxGraphicsContext* gc)
+ {
+#if wxMAJOR_VERSION == 2 && wxMINOR_VERSION >= 9
+ gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxPENSTYLE_SOLID));
+#else
+ gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (0, 0, 0), 1, wxSOLID));
+#endif
+
+ int mark_interval = rint (128 / (TIME_HZ * _timeline.pixels_per_time_unit ()));
+ if (mark_interval > 5) {
+ mark_interval -= mark_interval % 5;
+ }
+ if (mark_interval > 10) {
+ mark_interval -= mark_interval % 10;
+ }
+ if (mark_interval > 60) {
+ mark_interval -= mark_interval % 60;
+ }
+ if (mark_interval > 3600) {
+ mark_interval -= mark_interval % 3600;
+ }
+
+ if (mark_interval < 1) {
+ mark_interval = 1;
+ }
+
+ wxGraphicsPath path = gc->CreatePath ();
+ path.MoveToPoint (_timeline.x_offset(), _y);
+ path.AddLineToPoint (_timeline.width(), _y);
+ gc->StrokePath (path);
+
+ Time t = 0;
+ while ((t * _timeline.pixels_per_time_unit()) < _timeline.width()) {
+ wxGraphicsPath path = gc->CreatePath ();
+ path.MoveToPoint (time_x (t), _y - 4);
+ path.AddLineToPoint (time_x (t), _y + 4);
+ gc->StrokePath (path);
+
+ int tc = t / TIME_HZ;
+ int const h = tc / 3600;
+ tc -= h * 3600;
+ int const m = tc / 60;
+ tc -= m * 60;
+ int const s = tc;
+
+ wxString str = wxString::Format (wxT ("%02d:%02d:%02d"), h, m, s);
+ wxDouble str_width;
+ wxDouble str_height;
+ wxDouble str_descent;
+ wxDouble str_leading;
+ gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading);
+
+ int const tx = _timeline.x_offset() + t * _timeline.pixels_per_time_unit();
+ if ((tx + str_width) < _timeline.width()) {
+ gc->DrawText (str, time_x (t), _y + 16);
+ }
+
+ t += mark_interval * TIME_HZ;
+ }
+ }
+
+private:
+ int _y;
+};
+
+Timeline::Timeline (wxWindow* parent, FilmEditor* ed, shared_ptr<Film> film)
+ : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
+ , _film_editor (ed)
+ , _film (film)
+ , _time_axis_view (new TimeAxisView (*this, 32))
+ , _tracks (0)
+ , _pixels_per_time_unit (0)
+ , _left_down (false)
+ , _down_view_start (0)
+ , _first_move (false)
+{
+ SetDoubleBuffered (true);
+
+ setup_pixels_per_time_unit ();
+
+ 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_MOTION, wxMouseEventHandler (Timeline::mouse_moved), 0, this);
+ Connect (wxID_ANY, wxEVT_SIZE, wxSizeEventHandler (Timeline::resized), 0, this);
+
+ playlist_changed ();
+
+ SetMinSize (wxSize (640, tracks() * track_height() + 96));
+
+ _playlist_connection = film->playlist()->Changed.connect (bind (&Timeline::playlist_changed, this));
+
+ _views.push_back (_time_axis_view);