Initial steps towards usable range-based automation editing.
authorBen Loftis <ben@harrisonconsoles.com>
Tue, 5 Aug 2014 20:42:06 +0000 (15:42 -0500)
committerBen Loftis <ben@harrisonconsoles.com>
Tue, 5 Aug 2014 20:42:06 +0000 (15:42 -0500)
TODO:  needs undo. only works in top quarter of automation lane.  selection model feels weird sometimes.  needs to show gain curve when you are using Range tool

gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_selection.cc
libs/evoral/evoral/ControlList.hpp
libs/evoral/src/ControlList.cpp

index 8e16ad9bc6f09dfeaf09e2625eac8f90e3c0652a..eb130c5f294fedd86175379f13103e4bb6c603b8 100644 (file)
@@ -4239,6 +4239,14 @@ SelectionDrag::motion (GdkEvent* event, bool first_move)
                        }
                }
                
+               //if user is selecting a range on an automation track, bail out here before we get to the grouped stuff, 
+               // because the grouped stuff will start working on tracks (routeTAVs), and end up removing this 
+               AutomationTimeAxisView *atest = dynamic_cast<AutomationTimeAxisView *>(_editor->clicked_axisview);
+               if (atest) {
+                       _editor->selection->add (atest);
+                       break; 
+               }
+               
                /* select all tracks within the rectangle that we've marked out so far */
                TrackViewList new_selection;
                TrackViewList& all_tracks (_editor->track_views);
@@ -4991,8 +4999,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                                double const p = j->line->time_converter().from (i->start - j->line->time_converter().origin_b ());
                                double const q = j->line->time_converter().from (a - j->line->time_converter().origin_b ());
 
-                               the_list->add (p, the_list->eval (p));
-                               the_list->add (q, the_list->eval (q));
+                               the_list->editor_add (p, the_list->eval (p));
+                               the_list->editor_add (q, the_list->eval (q));
                        }
 
                        /* same thing for the end */
@@ -5017,8 +5025,8 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                                double const p = j->line->time_converter().from (b - j->line->time_converter().origin_b ());
                                double const q = j->line->time_converter().from (i->end - j->line->time_converter().origin_b ());
 
-                               the_list->add (p, the_list->eval (p));
-                               the_list->add (q, the_list->eval (q));
+                               the_list->editor_add (p, the_list->eval (p));
+                               the_list->editor_add (q, the_list->eval (q));
                        }
                }
 
index c12d11ff3f9d06e928c8482b99043c84dcf7df52..8d800ae205740cb6bb973fce180b938d5a92684a 100644 (file)
@@ -776,19 +776,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                                /* grab selection for moving */
                                _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionMove), event);
                        } else {
-                               double const y = event->button.y;
-                               pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
-                               if (tvp.first) {
-                                       AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
-                                       if ( get_smart_mode() && atv) {
-                                               /* smart "join" mode: drag automation */
-                                               _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
-                                       } else {
-                                               /* this was debated, but decided the more common action was to
-                                                  make a new selection */
-                                               _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
-                                       }
-                               }
+                               /* this was debated, but decided the more common action was to
+                                  make a new selection */
+                               _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event);
                        }
                        break;
 
@@ -1048,45 +1038,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                        case SelectionItem:
                        {
-                               if ( get_smart_mode() ) {
-                                       /* we're in "smart" joined mode, and we've clicked on a Selection */
-                                       double const y = event->button.y;
-                                       pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
-                                       if (tvp.first) {
-                                               /* if we're over an automation track, start a drag of its data */
-                                               AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
-                                               if (atv) {
-                                                       _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
-                                               }
-
-                                               /* if we're over a track and a region, and in the `object' part of a region,
-                                                  put a selection around the region and drag both
-                                               */
-/*                                             RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tvp.first);
-                                               if (rtv && _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) {
-                                                       boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (rtv->route ());
-                                                       if (t) {
-                                                               boost::shared_ptr<Playlist> pl = t->playlist ();
-                                                               if (pl) {
-
-                                                                       boost::shared_ptr<Region> r = pl->top_region_at (canvas_event_sample (event));
-                                                                       if (r) {
-                                                                               RegionView* rv = rtv->view()->find_view (r);
-                                                                               clicked_selection = select_range (rv->region()->position(), 
-                                                                                                                 rv->region()->last_frame()+1);
-                                                                               _drags->add (new SelectionDrag (this, item, SelectionDrag::SelectionMove));
-                                                                               list<RegionView*> rvs;
-                                                                               rvs.push_back (rv);
-                                                                               _drags->add (new RegionMoveDrag (this, item, rv, rvs, false, false));
-                                                                               _drags->start_grab (event);
-                                                                               return true;
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-*/
-                                       }
-                               }
                                break;
                        }
 
@@ -1118,6 +1069,17 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
                        if (arv) {
                                _drags->set (new AutomationRangeDrag (this, arv, selection->time), event, _cursors->up_down);
                                _drags->start_grab (event);
+                       } else {
+                               double const y = event->button.y;
+                               pair<TimeAxisView*, int> tvp = trackview_by_y_position (y);
+                               if (tvp.first) {
+                                       AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
+                                       if ( atv) {
+                                               /* smart "join" mode: drag automation */
+                                               _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
+                                               _drags->start_grab (event);
+                                       }
+                               }
                        }
                        return true;
                        break;
index 9c05c9f924b15aac7b7d80362ea3b6866cb0d873..4bc622ad2c0aa94afa9d56d434055fc2368a6a3e 100644 (file)
@@ -185,12 +185,12 @@ Editor::set_selected_track_as_side_effect (Selection::Operation op)
                return;
        }
 
-       if (!clicked_routeview) {
-               return;
+       RouteGroup* group = NULL;
+       if (clicked_routeview) {
+               group = clicked_routeview->route()->route_group();
        }
 
        bool had_tracks = !selection->tracks.empty();
-       RouteGroup* group = clicked_routeview->route()->route_group();
        RouteGroup& arg (_session->all_route_group());
 
        switch (op) {
index e66cbe2253444956b231102ed493abe57304fb58..debd4989e0b31f3f08062df39350ef135dde4148 100644 (file)
@@ -121,7 +121,9 @@ public:
 
        virtual bool clamp_value (double& /*when*/, double& /*value*/) const { return true; }
 
-        virtual void add (double when, double value, bool with_guards=true);
+       virtual void add (double when, double value, bool with_guards=true);
+       virtual void editor_add (double when, double value);
+       
        void fast_simple_add (double when, double value);
 
        void erase_range (double start, double end);
index 95e61c1742071855b43e93e4f1d286ed8d12f1cb..be08cb446b12da97d321f5839c5e59388dcc83d6 100644 (file)
@@ -443,6 +443,39 @@ ControlList::in_write_pass () const
        return _in_write_pass;
 }
 
+void
+ControlList::editor_add (double when, double value)
+{
+       /* this is for making changes from a graphical line editor
+       */
+
+       if (!clamp_value (when, value)) {
+               return;
+       }
+
+       if (_events.empty()) {
+               
+               /* as long as the point we're adding is not at zero,
+                * add an "anchor" point there.
+                */
+
+               if (when >= 1) {
+                       _events.insert (_events.end(), new ControlEvent (0, _default_value));
+                       DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value));
+               }
+       }
+
+       ControlEvent cp (when, 0.0f);
+       iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
+       DEBUG_TRACE (DEBUG::ControlList, string_compose ("editor_add: actually add when= %1 value= %1\n", when, value));
+       _events.insert (i, new ControlEvent (when, value));
+
+       mark_dirty ();
+
+       maybe_signal_changed ();
+
+}
+
 void
 ControlList::add (double when, double value, bool with_guards)
 {