Mackie Control: Save old bank before we change it to new.
[ardour.git] / gtk2_ardour / audio_region_view.cc
index 706611a81d23e8a36b59f4c709184ede7a7ca391..148f99f4c9b439717b200725ad969dbe5d8eec1d 100644 (file)
@@ -1309,18 +1309,34 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
                return;
        }
 
-       double x, y;
+       uint32_t before_p, after_p;
+       double mx = ev->button.x;
+       double my = ev->button.y;
 
-       /* don't create points that can't be seen */
+       item->canvas_to_item (mx, my);
 
-       update_envelope_visibility ();
+       framecnt_t const frame_within_region = (framecnt_t) floor (mx * samples_per_pixel);
+
+       if (!gain_line->control_points_adjacent (frame_within_region, before_p, after_p)) {
+               /* no adjacent points */
+               return;
+       }
+
+       /*y is in item frame */
+       double const bx = gain_line->nth (before_p)->get_x();
+       double const ax = gain_line->nth (after_p)->get_x();
+       double const click_ratio = (ax - mx) / (ax - bx);
 
-       x = ev->button.x;
-       y = ev->button.y;
+       double y = ((gain_line->nth (before_p)->get_y() * click_ratio) + (gain_line->nth (after_p)->get_y() * (1 - click_ratio)));
 
-       item->canvas_to_item (x, y);
+       /* don't create points that can't be seen */
 
-       framepos_t fx = trackview.editor().pixel_to_sample (x);
+       update_envelope_visibility ();
+
+       framepos_t rpos = region ()->position ();
+       framepos_t fx = trackview.editor().pixel_to_sample (mx) + rpos;
+       trackview.editor ().snap_to_with_modifier (fx, ev);
+       fx -= rpos;
 
        if (fx > _region->length()) {
                return;
@@ -1328,31 +1344,44 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
 
        /* compute vertical fractional position */
 
-       y = 1.0 - (y / (_height - NAME_HIGHLIGHT_SIZE));
+       y = 1.0 - (y / (gain_line->height()));
 
        /* map using gain line */
 
-       gain_line->view_to_model_coord (x, y);
+       gain_line->view_to_model_coord (mx, y);
 
        /* XXX STATEFUL: can't convert to stateful diff until we
           can represent automation data with it.
        */
 
-       trackview.editor().begin_reversible_command (_("add gain control point"));
        XMLNode &before = audio_region()->envelope()->get_state();
+       MementoCommand<AudioRegion>* region_memento = 0;
 
        if (!audio_region()->envelope_active()) {
                XMLNode &region_before = audio_region()->get_state();
                audio_region()->set_envelope_active(true);
                XMLNode &region_after = audio_region()->get_state();
-               trackview.session()->add_command (new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after));
+               region_memento = new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after);
        }
 
-       audio_region()->envelope()->editor_add (fx, y, with_guard_points);
+       if (audio_region()->envelope()->editor_add (fx, y, with_guard_points)) {
+               XMLNode &after = audio_region()->envelope()->get_state();
+               std::list<Selectable*> results;
+
+               trackview.editor().begin_reversible_command (_("add gain control point"));
+
+               if (region_memento) {
+                       trackview.session()->add_command (region_memento);
+               }
 
-       XMLNode &after = audio_region()->envelope()->get_state();
-       trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
-       trackview.editor().commit_reversible_command ();
+               trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
+
+               gain_line->get_selectables (fx + region ()->position (), fx + region ()->position (), 0.0, 1.0, results);
+               trackview.editor ().get_selection ().set (results);
+
+               trackview.editor ().commit_reversible_command ();
+               trackview.session ()->set_dirty ();
+       }
 }
 
 void
@@ -1369,7 +1398,7 @@ AudioRegionView::add_ghost (TimeAxisView& tv)
        assert(rtv);
 
        double unit_position = _region->position () / samples_per_pixel;
-       AudioGhostRegion* ghost = new AudioGhostRegion (tv, trackview, unit_position);
+       AudioGhostRegion* ghost = new AudioGhostRegion (*this, tv, trackview, unit_position);
        uint32_t nchans;
 
        nchans = rtv->track()->n_channels().n_audio();