X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Fvideo_waveform_plot.cc;h=9f71140f308345526e5964f9fb96657de120d7fb;hb=c370a1f38215f6461cf4366e6885757e7aa2b96a;hp=eb2cf97c6d72b4c6f65fd431f2b7ddd9a7a871d0;hpb=a9228a36ed335dc0a624f0d65b9a2d9e42bec3b0;p=dcpomatic.git diff --git a/src/wx/video_waveform_plot.cc b/src/wx/video_waveform_plot.cc index eb2cf97c6..9f71140f3 100644 --- a/src/wx/video_waveform_plot.cc +++ b/src/wx/video_waveform_plot.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2018 Carl Hetherington This file is part of DCP-o-matic. @@ -22,6 +22,7 @@ #include "film_viewer.h" #include "wx_util.h" #include "lib/image.h" +#include "lib/film.h" #include "lib/dcp_video.h" #include #include @@ -32,15 +33,19 @@ using std::cout; using std::min; +using std::max; using std::string; using boost::weak_ptr; using boost::shared_ptr; using dcp::locale_convert; int const VideoWaveformPlot::_vertical_margin = 8; +int const VideoWaveformPlot::_pixel_values = 4096; +int const VideoWaveformPlot::_x_axis_width = 52; -VideoWaveformPlot::VideoWaveformPlot (wxWindow* parent, FilmViewer* viewer) +VideoWaveformPlot::VideoWaveformPlot (wxWindow* parent, weak_ptr film, weak_ptr viewer) : wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) + , _film (film) , _dirty (true) , _enabled (false) , _component (0) @@ -50,10 +55,14 @@ VideoWaveformPlot::VideoWaveformPlot (wxWindow* parent, FilmViewer* viewer) SetDoubleBuffered (true); #endif - _viewer_connection = viewer->ImageChanged.connect (boost::bind (&VideoWaveformPlot::set_image, this, _1)); + shared_ptr fv = viewer.lock (); + DCPOMATIC_ASSERT (fv); + + _viewer_connection = fv->ImageChanged.connect (boost::bind (&VideoWaveformPlot::set_image, this, _1)); Bind (wxEVT_PAINT, boost::bind (&VideoWaveformPlot::paint, this)); Bind (wxEVT_SIZE, boost::bind (&VideoWaveformPlot::sized, this, _1)); + Bind (wxEVT_MOTION, boost::bind (&VideoWaveformPlot::mouse_moved, this, _1)); SetMinSize (wxSize (640, 512)); SetBackgroundColour (wxColour (0, 0, 0)); @@ -78,7 +87,6 @@ VideoWaveformPlot::paint () return; } - int const axis_x = 48; int const height = _waveform->size().height; gc->SetPen (wxPen (wxColour (255, 255, 255), 1, wxPENSTYLE_SOLID)); @@ -108,10 +116,10 @@ VideoWaveformPlot::paint () wxGraphicsPath p = gc->CreatePath (); int const y = _vertical_margin + height - (i * height / label_gaps) - 1; p.MoveToPoint (label_width + 8, y); - p.AddLineToPoint (axis_x, y); + p.AddLineToPoint (_x_axis_width - 4, y); gc->StrokePath (p); int x = 4; - int const n = i * 4096 / label_gaps; + int const n = i * _pixel_values / label_gaps; if (n < 10) { x += extra[0]; } else if (n < 100) { @@ -124,7 +132,7 @@ VideoWaveformPlot::paint () wxImage waveform (_waveform->size().width, height, _waveform->data()[0], true); wxBitmap bitmap (waveform); - gc->DrawBitmap (bitmap, axis_x + 4, _vertical_margin, _waveform->size().width, height); + gc->DrawBitmap (bitmap, _x_axis_width, _vertical_margin, _waveform->size().width, height); delete gc; } @@ -153,7 +161,7 @@ VideoWaveformPlot::create_waveform () int* ip = _image->data (_component) + x; for (int y = 0; y < image_size.height; ++y) { - strip[*ip * waveform_height / 4096]++; + strip[*ip * waveform_height / _pixel_values]++; ip += image_size.width; } @@ -166,7 +174,7 @@ VideoWaveformPlot::create_waveform () } _waveform = _waveform->scale ( - dcp::Size (GetSize().GetWidth() - 32, waveform_height), + dcp::Size (GetSize().GetWidth() - _x_axis_width, waveform_height), dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, false, false ); } @@ -220,3 +228,34 @@ VideoWaveformPlot::set_contrast (int b) _dirty = true; Refresh (); } + +void +VideoWaveformPlot::mouse_moved (wxMouseEvent& ev) +{ + if (!_image) { + return; + } + + if (_dirty) { + create_waveform (); + _dirty = false; + } + + shared_ptr film = _film.lock (); + if (!film) { + return; + } + + dcp::Size const full = film->frame_size (); + + double const xs = static_cast (full.width) / _waveform->size().width; + int const x1 = max (0, min (full.width - 1, int (floor (ev.GetPosition().x - _x_axis_width - 0.5) * xs))); + int const x2 = max (0, min (full.width - 1, int (floor (ev.GetPosition().x - _x_axis_width + 0.5) * xs))); + + double const ys = static_cast (_pixel_values) / _waveform->size().height; + int const fy = _waveform->size().height - (ev.GetPosition().y - _vertical_margin); + int const y1 = max (0, min (_pixel_values - 1, int (floor (fy - 0.5) * ys))); + int const y2 = max (0, min (_pixel_values - 1, int (floor (fy + 0.5) * ys))); + + MouseMoved (x1, x2, y1, y2); +}