Preserve stacked / overlaid state of tracks in the session file.
[ardour.git] / gtk2_ardour / audio_streamview.cc
index 8dcee5aaab1bf4d10f25c9bc8bb68578de0898ea..99755d6a975ee215386aad7f63a84360b80e8af9 100644 (file)
@@ -29,7 +29,6 @@
 #include "ardour/audiofilesource.h"
 #include "ardour/audio_diskstream.h"
 #include "ardour/audio_track.h"
-#include "ardour/playlist_templates.h"
 #include "ardour/source.h"
 #include "ardour/region_factory.h"
 #include "ardour/profile.h"
@@ -60,12 +59,12 @@ AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
        : StreamView (tv)
 {
        crossfades_visible = true;
-       _waveform_scale = LinearWaveform;
-       _waveform_shape = Traditional;
        color_handler ();
        _amplitude_above_axis = 1.0;
 
        use_rec_regions = tv.editor().show_waveforms_recording ();
+
+       Config->ParameterChanged.connect (sigc::mem_fun (*this, &AudioStreamView::parameter_changed));
 }
 
 AudioStreamView::~AudioStreamView ()
@@ -78,7 +77,7 @@ AudioStreamView::set_samples_per_unit (gdouble spp)
        StreamView::set_samples_per_unit(spp);
 
        for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
-               (*xi)->set_samples_per_unit (spp);
+               xi->second->set_samples_per_unit (spp);
        }
 
        return 0;
@@ -105,32 +104,13 @@ AudioStreamView::set_amplitude_above_axis (gdouble app)
 }
 
 RegionView*
-AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
+AudioStreamView::create_region_view (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
 {
        AudioRegionView *region_view = 0;
-
        boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
 
        if (region == 0) {
-               return NULL;
-       }
-
-       for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
-               if ((*i)->region() == r) {
-                       
-                       /* great. we already have a AudioRegionView for this Region. use it again. */
-                       
-                       (*i)->set_valid (true);
-
-                       // this might not be necessary
-                       AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-                       if (arv) {
-                               arv->set_waveform_scale (_waveform_scale);
-                               arv->set_waveform_shape (_waveform_shape);
-                       }
-                               
-                       return NULL;
-               }
+               return 0;
        }
 
        switch (_trackview.audio_track()->mode()) {
@@ -159,7 +139,6 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
        region_view->init (region_color, wait_for_waves);
        region_view->set_amplitude_above_axis(_amplitude_above_axis);
        region_view->set_height (child_height ());
-       region_views.push_front (region_view);
 
        /* if its the special single-sample length that we use for rec-regions, make it 
           insensitive to events 
@@ -169,33 +148,46 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
                region_view->set_sensitive (false);
        }
 
-       /* if this was the first one, then lets query the waveform scale and shape.
-          otherwise, we set it to the current value */
-          
-       if (region_views.size() == 1) {
-               if (region_view->waveform_logscaled()) {
-                       _waveform_scale = LogWaveform;
-               } else {
-                       _waveform_scale = LinearWaveform;
-               }
+       region_view->set_waveform_scale (Config->get_waveform_scale ());
+       region_view->set_waveform_shape (Config->get_waveform_shape ());
+       region_view->set_waveform_visible (Config->get_show_waveforms ());
 
-               if (region_view->waveform_rectified()) {
-                       _waveform_shape = Rectified;
-               } else {
-                       _waveform_shape = Traditional;
-               }
-       }
-       else {
-               region_view->set_waveform_scale(_waveform_scale);
-               region_view->set_waveform_shape(_waveform_shape);
+       return region_view;     
+}
+
+RegionView*
+AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves, bool recording)
+{
+       RegionView *region_view = create_region_view (r, wait_for_waves, recording);
+       if (region_view == 0) {
+               return 0;
        }
-       
-       /* follow global waveform setting */
 
-       region_view->set_waveform_visible(_trackview.editor().show_waveforms());
+//     if(!recording){
+//             for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+//                     if ((*i)->region() == r) {
+//                             cerr << "audio_streamview in add_region_view_internal region found" << endl;
+                               /* great. we already have a AudioRegionView for this Region. use it again. */
+                               
+//                             (*i)->set_valid (true);
+
+                               // this might not be necessary
+//                             AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+
+//                             if (arv) {
+//                                     arv->set_waveform_scale (_waveform_scale);
+//                                     arv->set_waveform_shape (_waveform_shape);
+//                             }
+                                       
+//                             return NULL;
+//                     }
+//             }
+//     }
+
+       region_views.push_front (region_view);
 
        /* catch regionview going away */
-       region->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r)));
+       r->GoingAway.connect (bind (mem_fun (*this, &AudioStreamView::remove_region_view), boost::weak_ptr<Region> (r)));
 
        RegionViewAdded (region_view);
 
@@ -215,15 +207,15 @@ AudioStreamView::remove_region_view (boost::weak_ptr<Region> weak_r)
 
        if (!_trackview.session().deletion_in_progress()) {
 
-               for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
-                       list<CrossfadeView*>::iterator tmp;
+               for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
+                       CrossfadeViewList::iterator tmp;
                        
                        tmp = i;
                        ++tmp;
                        
                        boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
-                       if (ar && (*i)->crossfade->involves (ar)) {
-                               delete *i;
+                       if (ar && i->second->crossfade->involves (ar)) {
+                               delete i->second;
                                crossfade_views.erase (i);
                        }
                        
@@ -240,7 +232,7 @@ AudioStreamView::undisplay_diskstream ()
        StreamView::undisplay_diskstream();
 
        for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               delete *i;
+               delete i->second;
        }
 
        crossfade_views.clear ();
@@ -265,8 +257,8 @@ AudioStreamView::playlist_modified (boost::shared_ptr<Diskstream> ds)
        
        /* make sure xfades are on top and all the regionviews are stacked correctly. */
 
-       for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               (*i)->get_canvas_group()->raise_to_top();
+       for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+               i->second->get_canvas_group()->raise_to_top();
        }
 }
 
@@ -319,17 +311,15 @@ AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
 
        /* first see if we already have a CrossfadeView for this Crossfade */
 
-       for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               if ((*i)->crossfade == crossfade) {
-
-                       if (!crossfades_visible || _layer_display == Stacked) {
-                               (*i)->hide();
-                       } else {
-                               (*i)->show ();
-                       }
-                       (*i)->set_valid (true);
-                       return;
+       CrossfadeViewList::iterator i = crossfade_views.find (crossfade);
+       if (i != crossfade_views.end()) {
+               if (!crossfades_visible || _layer_display == Stacked) {
+                       i->second->hide();
+               } else {
+                       i->second->show ();
                }
+               i->second->set_valid (true);
+               return;
        }
 
        /* create a new one */
@@ -353,8 +343,8 @@ AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
                                               *lview, *rview);
        cv->set_valid (true);
        crossfade->Invalidated.connect (mem_fun (*this, &AudioStreamView::remove_crossfade));
-       crossfade_views.push_back (cv);
-       if (!Config->get_xfades_visible() || !crossfades_visible || _layer_display == Stacked) {
+       crossfade_views[cv->crossfade] = cv;
+       if (!_trackview.session().config.get_xfades_visible() || !crossfades_visible || _layer_display == Stacked) {
                cv->hide ();
        }
 }
@@ -366,9 +356,9 @@ AudioStreamView::remove_crossfade (boost::shared_ptr<Region> r)
 
        boost::shared_ptr<Crossfade> xfade = boost::dynamic_pointer_cast<Crossfade> (r);
 
-       for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               if ((*i)->crossfade == xfade) {
-                       delete *i;
+       for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+               if (i->second->crossfade == xfade) {
+                       delete i->second;
                        crossfade_views.erase (i);
                        break;
                }
@@ -379,7 +369,7 @@ void
 AudioStreamView::redisplay_diskstream ()
 {
        list<RegionView *>::iterator i;
-       list<CrossfadeView*>::iterator xi, tmpx;
+       CrossfadeViewList::iterator xi, tmpx;
 
        // Flag region views as invalid and disable drawing
        for (i = region_views.begin(); i != region_views.end(); ++i) {
@@ -389,22 +379,26 @@ AudioStreamView::redisplay_diskstream ()
 
        // Flag crossfade views as invalid
        for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
-               (*xi)->set_valid (false);
-               if ((*xi)->visible() && _layer_display != Stacked) {
-                       (*xi)->show ();
+               xi->second->set_valid (false);
+               if (xi->second->visible() && _layer_display != Stacked) {
+                       xi->second->show ();
                }
        }
 
        // Add and display region and crossfade views, and flag them as valid
+
        if (_trackview.is_audio_track()) {
                _trackview.get_diskstream()->playlist()->foreach_region(
-                               static_cast<StreamView*>(this),
-                               &StreamView::add_region_view);
+                       sigc::hide_return (sigc::mem_fun (*this, &StreamView::add_region_view))
+                       );
 
                boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(
-                               _trackview.get_diskstream()->playlist());
-               if (apl)
-                       apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
+                               _trackview.get_diskstream()->playlist()
+                       );
+               
+               if (apl) {
+                       apl->foreach_crossfade (sigc::mem_fun (*this, &AudioStreamView::add_crossfade));
+               }
        }
        
        // Remove invalid crossfade views
@@ -412,8 +406,8 @@ AudioStreamView::redisplay_diskstream ()
                tmpx = xi;
                tmpx++;
 
-               if (!(*xi)->valid()) {
-                       delete *xi;
+               if (!xi->second->valid()) {
+                       delete xi->second;
                        crossfade_views.erase (xi);
                }
 
@@ -443,7 +437,6 @@ AudioStreamView::set_waveform_shape (WaveformShape shape)
                if (arv)
                        arv->set_waveform_shape (shape);
        }
-       _waveform_shape = shape;
 }              
 
 void
@@ -451,10 +444,10 @@ AudioStreamView::set_waveform_scale (WaveformScale scale)
 {
        for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
-               if (arv) 
+               if (arv) {
                        arv->set_waveform_scale (scale);
+               }
        }
-       _waveform_scale = scale;
 }              
 
 void
@@ -502,8 +495,9 @@ AudioStreamView::setup_rec_box ()
                                }
                                
                                boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion>
-                                                                      (RegionFactory::create (sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false)));
+                                                                      (RegionFactory::create (sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags), false)));
                                assert(region);
+                               region->block_property_changes ();
                                region->set_position (_trackview.session().transport_frame(), this);
                                rec_regions.push_back (make_pair(region, (RegionView*)0));
                        }
@@ -615,8 +609,8 @@ AudioStreamView::setup_rec_box ()
 void
 AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
 {
-       for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               ((*i)->*pmf) ();
+       for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+               (i->second->*pmf) ();
        }
 }
 
@@ -766,9 +760,9 @@ AudioStreamView::hide_all_xfades ()
 void
 AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
 {
-       for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               if ((*i)->crossfade->involves (rv.audio_region())) {
-                       (*i)->fake_hide ();
+       for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+               if (i->second->crossfade->involves (rv.audio_region())) {
+                       i->second->fake_hide ();
                }
        }
 }
@@ -776,9 +770,9 @@ AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
 void
 AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
 {
-       for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-               if ((*i)->crossfade->involves (rv.audio_region()) && (*i)->visible() && _layer_display != Stacked) {
-                       (*i)->show ();
+       for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+               if (i->second->crossfade->involves (rv.audio_region()) && i->second->visible() && _layer_display != Stacked) {
+                       i->second->show ();
                }
        }
 }
@@ -808,10 +802,22 @@ AudioStreamView::update_contents_height ()
        
        for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
                if (_layer_display == Overlaid) {
-                       (*i)->show ();
-                       (*i)->set_height (height);
+                       i->second->show ();
+                       i->second->set_height (height);
                } else {
-                       (*i)->hide ();
+                       i->second->hide ();
                }
        }
 }
+
+void
+AudioStreamView::parameter_changed (string const & p)
+{
+       if (p == "show-waveforms") {
+               set_show_waveforms (Config->get_show_waveforms ());
+       } else if (p == "waveform-scale") {
+               set_waveform_scale (Config->get_waveform_scale ());
+       } else if (p == "waveform-shape") {
+               set_waveform_shape (Config->get_waveform_shape ());
+       }
+}