+ _gain_correction = gain;
+ Refresh ();
+}
+
+
+AudioPoint
+AudioPlot::get_point (int channel, int point) const
+{
+ auto p = _analysis->get_point (channel, point);
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ p[i] *= db_to_linear(_gain_correction);
+ }
+
+ return p;
+}
+
+
+/** @param n Channel index.
+ * @return Colour used by that channel in the plot.
+ */
+wxColour
+AudioPlot::colour (int n) const
+{
+ DCPOMATIC_ASSERT (n < int(_colours.size()));
+ return _colours[n];
+}
+
+
+void
+AudioPlot::left_down ()
+{
+ if (_cursor) {
+ if (auto fv = _viewer.lock()) {
+ fv->seek (_cursor->time, true);
+ }
+ }
+}
+
+
+void
+AudioPlot::mouse_moved (wxMouseEvent& ev)
+{
+ double min_dist = DBL_MAX;
+ Point min_point;
+
+ auto search = [this](map<int, PointList> const & search, wxMouseEvent const & ev, double& min_dist, Point& min_point) {
+ for (auto const& i: search) {
+ if (_channel_visible[i.first]) {
+ for (auto const& j: i.second) {
+ double const dist = pow(ev.GetX() - j.draw.x, 2) + pow(ev.GetY() - j.draw.y, 2);
+ if (dist < min_dist) {
+ min_dist = dist;
+ min_point = j;
+ }
+ }
+ }
+ }
+ };
+
+ if (_type_visible[AudioPoint::RMS]) {
+ search (_rms, ev, min_dist, min_point);
+ }
+ if (_type_visible[AudioPoint::PEAK]) {
+ search (_peak, ev, min_dist, min_point);
+ }
+
+ _cursor = boost::none;
+
+ if (min_dist < DBL_MAX) {
+ wxRect before (min_point.draw.x - _cursor_size / 2, min_point.draw.y - _cursor_size / 2, _cursor_size, _cursor_size);
+ GetParent()->Refresh (true, &before);
+ _cursor = min_point;
+ wxRect after (min_point.draw.x - _cursor_size / 2, min_point.draw.y - _cursor_size / 2, _cursor_size, _cursor_size);
+ GetParent()->Refresh (true, &after);
+ Cursor (min_point.time, min_point.db);
+ }
+}
+
+
+void
+AudioPlot::mouse_leave (wxMouseEvent &)
+{
+ _cursor = boost::none;