pending-peaks: checker pattern.
[ardour.git] / gtk2_ardour / audio_region_view.cc
index b0ca3ff8afc017f9c392c03745ae38c9c9266574..fef4868dc8c8351a1ba0bb3b00e5b8d6e9ca5f5f 100644 (file)
@@ -74,6 +74,36 @@ using namespace ArdourCanvas;
 
 static double const handle_size = 10; /* height of fade handles */
 
+Cairo::RefPtr<Cairo::Pattern> AudioRegionView::pending_peak_pattern;
+
+static Cairo::RefPtr<Cairo::Pattern> create_pending_peak_pattern() {
+       cairo_surface_t * is = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 8, 8);
+
+       // create checker pattern
+       unsigned char *img = cairo_image_surface_get_data (is);
+       cairo_surface_flush (is);
+       const int stride = cairo_image_surface_get_stride (is);
+
+       for (int y = 0; y < 8; ++y) {
+               for (int x = 0; x < 8; ++x) {
+                       const int off = (y * stride + x * 4);
+                       uint32_t *pixel = (uint32_t*) &img[off];
+                       if ((x < 4) ^ (y < 4)) {
+                               *pixel = 0xa0000000;
+                       } else {
+                               *pixel = 0x40000000;
+                       }
+               }
+       }
+       cairo_surface_mark_dirty (is);
+
+       cairo_pattern_t* pat = cairo_pattern_create_for_surface (is);
+       cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
+       Cairo::RefPtr<Cairo::Pattern> p (new Cairo::Pattern (pat, false));
+       cairo_surface_destroy (is);
+       return p;
+}
+
 AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
                                  uint32_t basic_color)
        : RegionView (parent, tv, r, spu, basic_color)
@@ -82,6 +112,7 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
        , fade_out_handle(0)
        , fade_in_trim_handle(0)
        , fade_out_trim_handle(0)
+       , pending_peak_data(0)
        , start_xfade_curve (0)
        , start_xfade_rect (0)
        , _start_xfade_visible (false)
@@ -103,6 +134,7 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
        , fade_out_handle(0)
        , fade_in_trim_handle(0)
        , fade_out_trim_handle(0)
+       , pending_peak_data(0)
        , start_xfade_curve (0)
        , start_xfade_rect (0)
        , _start_xfade_visible (false)
@@ -122,6 +154,7 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
        , fade_out_handle(0)
        , fade_in_trim_handle(0)
        , fade_out_trim_handle(0)
+       , pending_peak_data(0)
        , start_xfade_curve (0)
        , start_xfade_rect (0)
        , _start_xfade_visible (false)
@@ -143,6 +176,18 @@ AudioRegionView::init (bool wfd)
        // FIXME: Some redundancy here with RegionView::init.  Need to figure out
        // where order is important and where it isn't...
 
+       if (!pending_peak_pattern) {
+               pending_peak_pattern = create_pending_peak_pattern();
+       }
+
+       // needs to be created first, RegionView::init() calls set_height()
+       pending_peak_data = new ArdourCanvas::Rectangle (group);
+       CANVAS_DEBUG_NAME (pending_peak_data, string_compose ("pending peak rectangle for %1", region()->name()));
+       pending_peak_data->set_outline_color (ArdourCanvas::rgba_to_color (0, 0, 0, 0.0));
+       pending_peak_data->set_pattern (pending_peak_pattern);
+       pending_peak_data->set_data ("regionview", this);
+       pending_peak_data->hide ();
+
        RegionView::init (wfd);
 
        _amplitude_above_axis = 1.0;
@@ -232,6 +277,8 @@ AudioRegionView::init (bool wfd)
 
        setup_waveform_visibility ();
 
+       pending_peak_data->raise_to_top ();
+
        if (frame_handle_start) {
                frame_handle_start->raise_to_top ();
        }
@@ -407,6 +454,8 @@ AudioRegionView::reset_width_dependent_items (double pixel_width)
        RegionView::reset_width_dependent_items(pixel_width);
        assert(_pixel_width == pixel_width);
 
+       pending_peak_data->set_x1(pixel_width);
+
        if (pixel_width <= 20.0 || _height < 5.0 || !trackview.session()->config.get_show_region_fades()) {
                if (fade_in_handle)       { fade_in_handle->hide(); }
                if (fade_out_handle)      { fade_out_handle->hide(); }
@@ -475,6 +524,7 @@ void
 AudioRegionView::set_height (gdouble height)
 {
        RegionView::set_height (height);
+       pending_peak_data->set_y1 (height);
 
        uint32_t wcnt = waves.size();
 
@@ -1111,6 +1161,7 @@ AudioRegionView::create_waves ()
                                // cerr << "\tdata is not ready\n";
                                // we'll get a PeaksReady signal from the source in the future
                                // and will call create_one_wave(n) then.
+                               pending_peak_data->show ();
                        }
 
                } else {
@@ -1211,6 +1262,8 @@ AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
                waves = tmp_waves;
                tmp_waves.clear ();
 
+               /* indicate peak-completed */
+               pending_peak_data->hide ();
        }
 
        /* channel wave created, don't hook into peaks ready anymore */