Tidy up region gain line drawing slightly so that it doesn't overhang its region.
[ardour.git] / gtk2_ardour / audio_region_view.cc
index 6af8496e9bc825a906e2086a128eab4cb2722c47..2a9722543424753544566c53ecbd349a48c3cece 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2001-2006 Paul Davis 
+    Copyright (C) 2001-2006 Paul Davis
 
     This program is free software; you can r>edistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 
 #include <gtkmm2ext/gtk_ui.h>
 
-#include <ardour/playlist.h>
-#include <ardour/audioregion.h>
-#include <ardour/audiosource.h>
-#include <ardour/audio_diskstream.h>
-#include <ardour/profile.h>
+#include "ardour/playlist.h"
+#include "ardour/audioregion.h"
+#include "ardour/audiosource.h"
+#include "ardour/audio_diskstream.h"
+#include "ardour/profile.h"
 
-#include <pbd/memento_command.h>
-#include <pbd/stacktrace.h>
+#include "pbd/memento_command.h"
+#include "pbd/stacktrace.h"
 
-#include <evoral/Curve.hpp>
+#include "evoral/Curve.hpp"
 
 #include "streamview.h"
 #include "audio_region_view.h"
@@ -56,6 +56,7 @@
 
 #define MUTED_ALPHA 10
 
+using namespace std;
 using namespace sigc;
 using namespace ARDOUR;
 using namespace PBD;
@@ -65,7 +66,7 @@ using namespace ArdourCanvas;
 static const int32_t sync_mark_width = 9;
 
 AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
-                                 Gdk::Color& basic_color)
+                                 Gdk::Color const & basic_color)
        : RegionView (parent, tv, r, spu, basic_color)
        , sync_mark(0)
        , zero_line(0)
@@ -81,8 +82,8 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
 }
 
 
-AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu, 
-                                 Gdk::Color& basic_color, bool recording, TimeAxisViewItem::Visibility visibility)
+AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<AudioRegion> r, double spu,
+                                 Gdk::Color const & basic_color, bool recording, TimeAxisViewItem::Visibility visibility)
        : RegionView (parent, tv, r, spu, basic_color, recording, visibility)
        , sync_mark(0)
        , zero_line(0)
@@ -99,7 +100,8 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView
 
 
 AudioRegionView::AudioRegionView (const AudioRegionView& other)
-       : RegionView (other)
+       : sigc::trackable(other)
+       , RegionView (other)
        , zero_line(0)
        , fade_in_shape(0)
        , fade_out_shape(0)
@@ -116,7 +118,7 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other)
 
        UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
        c.set_rgb_p (r/255.0, g/255.0, b/255.0);
-       
+
        init (c, false);
 }
 
@@ -143,13 +145,13 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, boost::shared_pt
 }
 
 void
-AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
+AudioRegionView::init (Gdk::Color const & basic_color, bool wfd)
 {
        // FIXME: Some redundancy here with RegionView::init.  Need to figure out
        // where order is important and where it isn't...
-       
+
        RegionView::init (basic_color, wfd);
-       
+
        XMLNode *node;
 
        _amplitude_above_axis = 1.0;
@@ -168,13 +170,13 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
        }
 
        compute_colors (basic_color);
-       
+
        create_waves ();
 
        fade_in_shape = new ArdourCanvas::Polygon (*group);
        fade_in_shape->property_fill_color_rgba() = fade_color;
        fade_in_shape->set_data ("regionview", this);
-       
+
        fade_out_shape = new ArdourCanvas::Polygon (*group);
        fade_out_shape->property_fill_color_rgba() = fade_color;
        fade_out_shape->set_data ("regionview", this);
@@ -182,23 +184,23 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
        {
                uint32_t r,g,b,a;
                UINT_TO_RGBA(fill_color,&r,&g,&b,&a);
-       
+
                fade_in_handle = new ArdourCanvas::SimpleRect (*group);
                fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
                fade_in_handle->property_outline_pixels() = 0;
-               
+
                fade_in_handle->set_data ("regionview", this);
-               
+
                fade_out_handle = new ArdourCanvas::SimpleRect (*group);
                fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
                fade_out_handle->property_outline_pixels() = 0;
-               
+
                fade_out_handle->set_data ("regionview", this);
        }
 
        setup_fade_handle_positions ();
 
-       if (!Config->get_show_region_fades()) {
+       if (!trackview.session().config.get_show_region_fades()) {
                set_fade_visibility (false);
        }
 
@@ -313,7 +315,7 @@ AudioRegionView::fade_in_active_changed ()
                fade_in_shape->property_fill_color_rgba() = col;
                fade_in_shape->property_width_pixels() = 0;
                fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
-       } else { 
+       } else {
                col = RGBA_TO_UINT(r,g,b,0);
                fade_in_shape->property_fill_color_rgba() = col;
                fade_in_shape->property_width_pixels() = 1;
@@ -333,7 +335,7 @@ AudioRegionView::fade_out_active_changed ()
                fade_out_shape->property_fill_color_rgba() = col;
                fade_out_shape->property_width_pixels() = 0;
                fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
-       } else { 
+       } else {
                col = RGBA_TO_UINT(r,g,b,0);
                fade_out_shape->property_fill_color_rgba() = col;
                fade_out_shape->property_width_pixels() = 1;
@@ -357,7 +359,7 @@ void
 AudioRegionView::region_renamed ()
 {
        Glib::ustring str = RegionView::make_name ();
-       
+
        if (audio_region()->speed_mismatch (trackview.session().frame_rate())) {
                str = string ("*") + str;
        }
@@ -382,7 +384,7 @@ AudioRegionView::region_resized (Change what_changed)
                for (uint32_t n = 0; n < waves.size(); ++n) {
                        waves[n]->property_region_start() = _region->start();
                }
-               
+
                for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
                        if((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
 
@@ -413,7 +415,7 @@ AudioRegionView::reset_width_dependent_items (double pixel_width)
                                fade_in_handle->hide();
                                fade_out_handle->hide();
                        } else {
-                               if (Config->get_show_region_fades()) {
+                               if (trackview.session().config.get_show_region_fades()) {
                                        fade_in_handle->show();
                                        fade_out_handle->show();
                                }
@@ -450,7 +452,7 @@ AudioRegionView::setup_fade_handle_positions()
                fade_in_handle->property_y1() = handle_pos;
                fade_in_handle->property_y2() = handle_pos + handle_height;
        }
-       
+
        if (fade_out_handle) {
                fade_out_handle->property_y1() = handle_pos;
                fade_out_handle->property_y2() = handle_pos + handle_height;
@@ -466,7 +468,7 @@ AudioRegionView::set_height (gdouble height)
 
        // FIXME: ick
        height -= 2;
-       
+
        _height = height;
 
        for (uint32_t n=0; n < wcnt; ++n) {
@@ -477,9 +479,9 @@ AudioRegionView::set_height (gdouble height)
                } else {
                        ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
                }
-               
+
                gdouble yoff = n * (ht+1);
-               
+
                waves[n]->property_height() = ht;
                waves[n]->property_y() = yoff + 2;
        }
@@ -492,15 +494,16 @@ AudioRegionView::set_height (gdouble height)
                                gain_line->show ();
                        }
                }
-               gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE));
+               gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE - 2));
        }
 
        manage_zero_line ();
        reset_fade_shapes ();
-       
-       if (name_text) {
-               name_text->raise_to_top();
+
+       if (name_pixbuf) {
+               name_pixbuf->raise_to_top();
        }
+
 }
 
 void
@@ -532,7 +535,7 @@ AudioRegionView::reset_fade_in_shape ()
 {
        reset_fade_in_shape_width ((nframes_t) audio_region()->fade_in()->back()->when);
 }
-       
+
 void
 AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 {
@@ -547,8 +550,8 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
        Points* points;
        double pwidth = width / samples_per_unit;
        uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth);
-       double h; 
-       
+       double h;
+
        if (_height < 5) {
                fade_in_shape->hide();
                fade_in_handle->hide();
@@ -557,7 +560,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 
        double handle_center;
        handle_center = pwidth;
-       
+
        if (handle_center > 7.0) {
                handle_center -= 3.0;
        } else {
@@ -566,13 +569,13 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
 
        fade_in_handle->property_x1() =  handle_center - 3.0;
        fade_in_handle->property_x2() =  handle_center + 3.0;
-       
+
        if (pwidth < 5) {
                fade_in_shape->hide();
                return;
        }
 
-       if (Config->get_show_region_fades()) {
+       if (trackview.session().config.get_show_region_fades()) {
                fade_in_shape->show();
        }
 
@@ -596,7 +599,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
                (*points)[pi].set_x(1 + (pc * xdelta));
                (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
        }
-       
+
        /* fold back */
 
        (*points)[pi].set_x(pwidth);
@@ -608,9 +611,12 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
        /* connect the dots ... */
 
        (*points)[pi] = (*points)[0];
-       
+
        fade_in_shape->property_points() = *points;
        delete points;
+
+       /* ensure trim handle stays on top */
+       frame_handle_start->raise_to_top();
 }
 
 void
@@ -621,7 +627,7 @@ AudioRegionView::reset_fade_out_shape ()
 
 void
 AudioRegionView::reset_fade_out_shape_width (nframes_t width)
-{      
+{
        if (fade_out_handle == 0) {
                return;
        }
@@ -643,24 +649,24 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
 
        double handle_center;
        handle_center = (_region->length() - width) / samples_per_unit;
-       
+
        if (handle_center > 7.0) {
                handle_center -= 3.0;
        } else {
                handle_center = 3.0;
        }
-       
+
        fade_out_handle->property_x1() =  handle_center - 3.0;
        fade_out_handle->property_x2() =  handle_center + 3.0;
 
        /* don't show shape if its too small */
-       
+
        if (pwidth < 5) {
                fade_out_shape->hide();
                return;
-       } 
-       
-       if (Config->get_show_region_fades()) {
+       }
+
+       if (trackview.session().config.get_show_region_fades()) {
                fade_out_shape->show();
        }
 
@@ -684,7 +690,7 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
                (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta));
                (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
        }
-       
+
        /* fold back */
 
        (*points)[pi].set_x(_pixel_width);
@@ -699,6 +705,9 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
 
        fade_out_shape->property_points() = *points;
        delete points;
+
+       /* ensure trim handle stays on top */
+       frame_handle_end->raise_to_top();
 }
 
 void
@@ -728,10 +737,10 @@ AudioRegionView::set_amplitude_above_axis (gdouble spp)
 }
 
 void
-AudioRegionView::compute_colors (Gdk::Color& basic_color)
+AudioRegionView::compute_colors (Gdk::Color const & basic_color)
 {
-       RegionView::compute_colors(basic_color);
-       
+       RegionView::compute_colors (basic_color);
+
        uint32_t r, g, b, a;
 
        /* gain color computed in envelope_active_changed() */
@@ -744,7 +753,7 @@ void
 AudioRegionView::set_colors ()
 {
        RegionView::set_colors();
-       
+
        if (gain_line) {
                gain_line->set_line_color (audio_region()->envelope_active() ? ARDOUR_UI::config()->canvasvar_GainLine.get() : ARDOUR_UI::config()->canvasvar_GainLineInactive.get());
        }
@@ -769,7 +778,7 @@ AudioRegionView::show_region_editor ()
                // GTK2FIX : how to ensure float without realizing
                // editor->realize ();
                // trackview.editor.ensure_float (*editor);
-       } 
+       }
 
        editor->present ();
        editor->show_all();
@@ -843,26 +852,24 @@ AudioRegionView::create_waves ()
 
        // cerr << "creating waves for " << _region->name() << " with wfd = " << wait_for_data
        //              << " and channels = " << nchans.n_audio() << endl;
-       
+
        /* in tmp_waves, set up null pointers for each channel so the vector is allocated */
        for (uint32_t n = 0; n < nchans.n_audio(); ++n) {
                tmp_waves.push_back (0);
        }
 
        for (uint32_t n = 0; n < nchans.n_audio(); ++n) {
-               
+
                if (n >= audio_region()->n_channels()) {
                        break;
                }
-               
+
                wave_caches.push_back (WaveView::create_cache ());
 
                // cerr << "\tchannel " << n << endl;
 
                if (wait_for_data) {
                        if (audio_region()->audio_source(n)->peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
-                               // cerr << "\tData is ready\n";
-                               cerr << "\tData is ready\n";
                                // cerr << "\tData is ready\n";
                                create_one_wave (n, true);
                        } else {
@@ -870,7 +877,7 @@ AudioRegionView::create_waves ()
                                // we'll get a PeaksReady signal from the source in the future
                                // and will call create_one_wave(n) then.
                        }
-                       
+
                } else {
                        // cerr << "\tdon't delay, display today!\n";
                        create_one_wave (n, true);
@@ -880,7 +887,7 @@ AudioRegionView::create_waves ()
 }
 
 void
-AudioRegionView::create_one_wave (uint32_t which, bool direct)
+AudioRegionView::create_one_wave (uint32_t which, bool /*direct*/)
 {
        //cerr << "AudioRegionView::create_one_wave() called which: " << which << " this: " << this << endl;//DEBUG
        RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
@@ -941,9 +948,9 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
        } else {
                /* n-channel track, >n-channel source */
        }
-       
+
        /* see if we're all ready */
-       
+
        for (n = 0; n < nchans; ++n) {
                if (tmp_waves[n] == 0) {
                        break;
@@ -958,7 +965,7 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
                tmp_waves.clear ();
 
                /* all waves created, don't hook into peaks ready anymore */
-               data_ready_connection.disconnect ();            
+               data_ready_connection.disconnect ();
 
 #if 0
                if (!zero_line) {
@@ -991,7 +998,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
        /* don't create points that can't be seen */
 
        set_envelope_visible (true);
-       
+
        x = ev->button.x;
        y = ev->button.y;
 
@@ -1022,14 +1029,14 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
        }
 
        audio_region()->envelope()->add (fx, y);
-       
+
        XMLNode &after = audio_region()->envelope()->get_state();
        trackview.session().add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
        trackview.session().commit_reversible_command ();
 }
 
 void
-AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
+AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent */*ev*/)
 {
        ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
        audio_region()->envelope()->erase (cp->model());
@@ -1054,36 +1061,36 @@ AudioRegionView::set_flags (XMLNode* node)
        XMLProperty *prop;
 
        if ((prop = node->property ("waveform-visible")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= WaveformVisible;
                }
        }
 
        if ((prop = node->property ("envelope-visible")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= EnvelopeVisible;
                }
        }
 
        if ((prop = node->property ("waveform-rectified")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= WaveformRectified;
                }
        }
 
        if ((prop = node->property ("waveform-logscaled")) != 0) {
-               if (prop->value() == "yes") {
+               if (string_is_affirmative (prop->value())) {
                        _flags |= WaveformLogScaled;
                }
        }
 }
-       
+
 void
 AudioRegionView::set_waveform_shape (WaveformShape shape)
 {
        bool yn;
 
-       /* this slightly odd approach is to leave the door open to 
+       /* this slightly odd approach is to leave the door open to
           other "shapes" such as spectral displays, etc.
        */
 
@@ -1122,7 +1129,7 @@ AudioRegionView::set_waveform_shape (WaveformShape shape)
 void
 AudioRegionView::set_waveform_scale (WaveformScale scale)
 {
-       bool yn = (scale == LogWaveform);
+       bool yn = (scale == Logarithmic);
 
        if (yn != (bool) (_flags & WaveformLogScaled)) {
                for (vector<WaveView *>::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
@@ -1148,15 +1155,15 @@ AudioRegionView::add_ghost (TimeAxisView& tv)
        double unit_position = _region->position () / samples_per_unit;
        AudioGhostRegion* ghost = new AudioGhostRegion (tv, trackview, unit_position);
        uint32_t nchans;
-       
+
        nchans = rtv->get_diskstream()->n_channels().n_audio();
 
        for (uint32_t n = 0; n < nchans; ++n) {
-               
+
                if (n >= audio_region()->n_channels()) {
                        break;
                }
-               
+
                WaveView *wave = new WaveView(*ghost->group);
 
                wave->property_data_src() = _region.get();
@@ -1195,7 +1202,7 @@ AudioRegionView::entered ()
        uint32_t r,g,b,a;
        UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
        a=255;
-       
+
        if (fade_in_handle) {
                fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
                fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
@@ -1208,11 +1215,11 @@ AudioRegionView::exited ()
        if (gain_line) {
                gain_line->hide_all_but_selected_control_points ();
        }
-       
+
        uint32_t r,g,b,a;
        UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
        a=0;
-       
+
        if (fade_in_handle) {
                fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
                fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
@@ -1237,11 +1244,11 @@ AudioRegionView::set_waveview_data_src()
                // TODO: something else to let it know the channel
                waves[n]->property_data_src() = _region.get();
        }
-       
+
        for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
-               
+
                (*i)->set_duration (unit_length);
-               
+
                if((agr = dynamic_cast<AudioGhostRegion*>(*i)) != 0) {
                        for (vector<WaveView*>::iterator w = agr->waves.begin(); w != agr->waves.end(); ++w) {
                                (*w)->property_data_src() = _region.get();
@@ -1280,7 +1287,7 @@ AudioRegionView::set_frame_color ()
        }
 
        uint32_t r,g,b,a;
-       
+
        if (_selected && should_show_selection) {
                UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
                frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
@@ -1331,10 +1338,10 @@ AudioRegionView::set_fade_visibility (bool yn)
                }
                if (fade_out_shape) {
                        fade_out_shape->show ();
-               } 
+               }
                if (fade_in_handle) {
                        fade_in_handle->show ();
-               } 
+               }
                if (fade_out_handle) {
                        fade_out_handle->show ();
                }
@@ -1344,12 +1351,21 @@ AudioRegionView::set_fade_visibility (bool yn)
                }
                if (fade_out_shape) {
                        fade_out_shape->hide ();
-               } 
+               }
                if (fade_in_handle) {
                        fade_in_handle->hide ();
-               } 
+               }
                if (fade_out_handle) {
                        fade_out_handle->hide ();
                }
        }
 }
+
+void
+AudioRegionView::update_coverage_frames (LayerDisplay d)
+{
+       RegionView::update_coverage_frames (d);
+
+       fade_in_handle->raise_to_top ();
+       fade_out_handle->raise_to_top ();
+}