+ cairo_t* cr = gdk_cairo_create (GDK_DRAWABLE (get_window ()->gobj ()));
+ cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
+ cairo_clip (cr);
+
+ cairo_set_source_surface(cr, _surface, 0, 0);
+ cairo_paint (cr);
+
+
+ if (_ann_x > 0 && _ann_y > 0) {
+ const float x = _ann_x - hl_margin;
+ const float freq = expf(_fft_log_base * x / currentScaleWidth) * _fft_start;
+
+ std::stringstream ss;
+ if (freq >= 10000) {
+ ss << std::setprecision (1) << std::fixed << freq / 1000 << " kHz";
+ } else if (freq >= 1000) {
+ ss << std::setprecision (2) << std::fixed << freq / 1000 << " kHz";
+ } else {
+ ss << std::setprecision (0) << std::fixed << freq << " Hz";
+ }
+ layout->set_text (ss.str ());
+ int lw, lh;
+ layout->get_pixel_size (lw, lh);
+ lw|=1; lh|=1;
+
+ const float y0 = _ann_y - lh - 7;
+
+ _ann_area.x = _ann_x - 1 - lw * .5;
+ _ann_area.y = y0 - 1;
+ _ann_area.width = lw + 3;
+ _ann_area.height = lh + 8;
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.7);
+ cairo_rectangle (cr, _ann_x - 1 - lw * .5, y0 - 1, lw + 2, lh + 2);
+ cairo_fill (cr);
+
+ cairo_move_to (cr, _ann_x , _ann_y - 0.5);
+ cairo_rel_line_to (cr, -3.0, -5.5);
+ cairo_rel_line_to (cr, 6, 0);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+ cairo_move_to (cr, _ann_x - lw / 2, y0);
+ pango_cairo_update_layout (cr, layout->gobj ());
+ pango_cairo_show_layout (cr, layout->gobj ());
+
+ }
+
+#ifdef HARLEQUIN_DEBUGGING
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_set_source_rgba (cr, (random() % 255) / 255.f, (random() % 255) / 255.f, 0.0, 0.5);
+ cairo_fill (cr);
+#endif
+
+ cairo_destroy (cr);
+ return true;
+}
+
+bool
+FFTGraph::on_motion_notify_event (GdkEventMotion* ev)
+{
+ gint x, y;
+
+ x = (int) floor (ev->x);
+ y = (int) floor (ev->y);
+
+ if (x <= hl_margin + 1 || x >= width - hr_margin) {
+ x = -1;
+ }
+ if (y <= _yoff || y >= height - v_margin - 1) {
+ y = -1;
+ }
+
+ if (x == _ann_x && y == _ann_y) {
+ return true;
+ }
+ _ann_x = x;
+ _ann_y = y;
+
+ if (_ann_area.width == 0 || _ann_area.height == 0) {
+ queue_draw ();
+ } else {
+ queue_draw_area (_ann_area.x, _ann_area.y, _ann_area.width, _ann_area.height + 1);
+ }
+
+ if (_ann_x > 0 &&_ann_y > 0) {
+ queue_draw_area (_ann_x - _ann_area.width, _ann_y - _ann_area.height - 1, _ann_area.width * 2, _ann_area.height + 2);
+ }
+