From 57ce447fd19bd794afe90748d466bbe172c2eab0 Mon Sep 17 00:00:00 2001 From: nick_m Date: Sun, 7 Jun 2015 23:07:56 +1000 Subject: [PATCH 01/19] Fix some workflow problems wrt automation. - clearing automation points sets control to "off" rather than touch. - multiple touches on the same pass acts consistently (no more fader jumps on mouse button press - use actual value for initial point rather than some arbitrary default. clarify new semantics of add () (with_default->with_initial). - clean some whitespace - add guard points as needed in stop. - catch grab broken signal (i can't trigger it, but the docs seem to think it is essential). --- gtk2_ardour/automation_time_axis.cc | 2 +- libs/ardour/automation_control.cc | 2 ++ libs/evoral/evoral/ControlList.hpp | 2 +- libs/evoral/src/ControlList.cpp | 33 ++++++++++++++++++----------- libs/gtkmm2ext/gtkmm2ext/pixfader.h | 1 + libs/gtkmm2ext/pixfader.cc | 14 +++++++++++- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 01f2ebb514..6d3a506cfa 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -449,7 +449,7 @@ AutomationTimeAxisView::clear_clicked () } else if (_view) { _view->clear (); } - + set_automation_state ((AutoState) ARDOUR::Off); _editor.commit_reversible_command (); _session->set_dirty (); } diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 21952038cf..da33ad12a5 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -116,6 +116,8 @@ AutomationControl::start_touch(double when) if (!_list) return; if (!touching()) { if (alist()->automation_state() == Touch) { + /* subtle. aligns the user value with the playback */ + set_value (get_value ()); alist()->start_touch (when); if (!_desc.toggled) { AutomationWatch::instance().add_automation_watch (shared_from_this()); diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index 7a828264bd..d2be604e5e 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -124,7 +124,7 @@ public: void slide (iterator before, double distance); void shift (double before, double distance); - virtual void add (double when, double value, bool with_guards=true, bool with_default=true); + virtual void add (double when, double value, bool with_guards=true, bool with_initial=true); virtual void editor_add (double when, double value); void fast_simple_add (double when, double value); diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index a2f3aa4f33..2f1d8f4243 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -399,7 +399,7 @@ ControlList::add_guard_point (double when) most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); double eval_value = unlocked_eval (insert_position); - + if (most_recent_insert_iterator == _events.end()) { DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at end, adding eval-value there %2\n", this, eval_value)); @@ -407,7 +407,7 @@ ControlList::add_guard_point (double when) /* leave insert iterator at the end */ } else if ((*most_recent_insert_iterator)->when == when) { - + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at existing point, setting eval-value there %2\n", this, eval_value)); /* most_recent_insert_iterator points to a control event @@ -415,15 +415,15 @@ ControlList::add_guard_point (double when) nothing to do. ... except ... - + advance most_recent_insert_iterator so that the "real" insert occurs in the right place, since it points to the control event just inserted. */ - + ++most_recent_insert_iterator; } else { - + /* insert a new control event at the right spot */ @@ -431,7 +431,7 @@ ControlList::add_guard_point (double when) this, eval_value, (*most_recent_insert_iterator)->when)); most_recent_insert_iterator = _events.insert (most_recent_insert_iterator, new ControlEvent (when, eval_value)); - + /* advance most_recent_insert_iterator so that the "real" * insert occurs in the right place, since it * points to the control event just inserted. @@ -546,7 +546,7 @@ ControlList::erase_from_iterator_to (iterator iter, double when) } void -ControlList::add (double when, double value, bool with_guards, bool with_default) +ControlList::add (double when, double value, bool with_guards, bool with_initial) { /* this is for making changes from some kind of user interface or control surface (GUI, MIDI, OSC etc) @@ -561,12 +561,12 @@ ControlList::add (double when, double value, bool with_guards, bool with_default ControlEvent cp (when, 0.0f); iterator insertion_point; - if (_events.empty() && with_default) { + if (_events.empty() && with_initial) { /* empty: add an "anchor" point if the point we're adding past time 0 */ if (when >= 1) { - _events.insert (_events.end(), new ControlEvent (0, _default_value)); + _events.insert (_events.end(), new ControlEvent (0, value)); DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added default value %2 at zero\n", this, _default_value)); } } @@ -628,10 +628,19 @@ ControlList::add (double when, double value, bool with_guards, bool with_default if ((*most_recent_insert_iterator)->value != value) { DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 reset existing point to new value %2\n", this, value)); - /* only one point allowed per time point, so just - * reset the value here. + /* only one point allowed per time point, so add a guard point + * before it if needed then reset the value of the point. */ - + + if ((when > 0) && most_recent_insert_iterator != _events.begin ()) { + --most_recent_insert_iterator; + double last_when = (*most_recent_insert_iterator)->when; + ++most_recent_insert_iterator; + if (when - last_when > 64) { + add_guard_point (when - 64); + } + } + (*most_recent_insert_iterator)->value = value; /* if we modified the final value, then its as diff --git a/libs/gtkmm2ext/gtkmm2ext/pixfader.h b/libs/gtkmm2ext/gtkmm2ext/pixfader.h index f137a4ed65..0a316340b4 100644 --- a/libs/gtkmm2ext/gtkmm2ext/pixfader.h +++ b/libs/gtkmm2ext/gtkmm2ext/pixfader.h @@ -58,6 +58,7 @@ class LIBGTKMM2EXT_API PixFader : public CairoWidget void on_size_allocate (Gtk::Allocation& alloc); void render (cairo_t *, cairo_rectangle_t*); + bool on_grab_broken_event (GdkEventGrabBroken*); bool on_button_press_event (GdkEventButton*); bool on_button_release_event (GdkEventButton*); bool on_motion_notify_event (GdkEventMotion*); diff --git a/libs/gtkmm2ext/pixfader.cc b/libs/gtkmm2ext/pixfader.cc index b140d7b56b..1e814fd147 100644 --- a/libs/gtkmm2ext/pixfader.cc +++ b/libs/gtkmm2ext/pixfader.cc @@ -71,7 +71,7 @@ PixFader::PixFader (Gtk::Adjustment& adj, int orientation, int fader_length, int _adjustment.signal_value_changed().connect (mem_fun (*this, &PixFader::adjustment_changed)); _adjustment.signal_changed().connect (mem_fun (*this, &PixFader::adjustment_changed)); - + signal_grab_broken_event ().connect (mem_fun (*this, &PixFader::on_grab_broken_event)); if (_orien == VERT) { CairoWidget::set_size_request(_girth, _span); } else { @@ -365,6 +365,18 @@ PixFader::on_size_allocate (Gtk::Allocation& alloc) update_unity_position (); } +bool +PixFader::on_grab_broken_event (GdkEventGrabBroken* ev) +{ + if (_dragging) { + remove_modal_grab(); + _dragging = false; + gdk_pointer_ungrab (GDK_CURRENT_TIME); + StopGesture (); + } + return (_tweaks & NoButtonForward) ? true : false; +} + bool PixFader::on_button_press_event (GdkEventButton* ev) { From 7cb9dbb8af5c4bd957067816d304282fa5120844 Mon Sep 17 00:00:00 2001 From: nick_m Date: Sun, 14 Jun 2015 05:17:25 +1000 Subject: [PATCH 02/19] Rudimentary automation touch undo/redo. --- libs/ardour/ardour/automation_control.h | 1 + libs/ardour/automation_control.cc | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index 24a9e0de3e..5d73e4aef9 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -101,6 +101,7 @@ protected: ARDOUR::Session& _session; const ParameterDescriptor _desc; + XMLNode* _before; //used for undo of touch start/stop pairs. }; diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index da33ad12a5..4ece790248 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -19,12 +19,15 @@ */ #include - #include "ardour/automation_control.h" #include "ardour/automation_watch.h" #include "ardour/event_type_map.h" #include "ardour/session.h" +#include "pbd/memento_command.h" + +#include "i18n.h" + using namespace std; using namespace ARDOUR; using namespace PBD; @@ -118,6 +121,7 @@ AutomationControl::start_touch(double when) if (alist()->automation_state() == Touch) { /* subtle. aligns the user value with the playback */ set_value (get_value ()); + _before = &alist ()->get_state (); alist()->start_touch (when); if (!_desc.toggled) { AutomationWatch::instance().add_automation_watch (shared_from_this()); @@ -138,6 +142,10 @@ AutomationControl::stop_touch(bool mark, double when) if (!_desc.toggled) { AutomationWatch::instance().remove_automation_watch (shared_from_this()); } + + _session.begin_reversible_command (_("record automation controller")); + _session.add_command (new MementoCommand (*alist ().get (), _before, &alist ()->get_state ())); + _session.commit_reversible_command (); } } } From 15819f0896795b269811805546ea7621cb9ca213 Mon Sep 17 00:00:00 2001 From: nick_m Date: Mon, 15 Jun 2015 16:35:19 +1000 Subject: [PATCH 03/19] Automation -use editor_add in gui, record straight lines with fewer points. - don't keep setting/unsetting write pass when transport frame remains the same (think larger jack buffer sizes) - insert guards are now 64 frames after when. - refactor previous approach. --- gtk2_ardour/automation_controller.cc | 2 +- gtk2_ardour/automation_region_view.cc | 2 +- gtk2_ardour/automation_time_axis.cc | 4 +- gtk2_ardour/editor_drag.cc | 8 ++-- libs/ardour/automation_watch.cc | 2 +- libs/evoral/evoral/ControlList.hpp | 2 +- libs/evoral/src/ControlList.cpp | 53 ++++++++++++++++++--------- 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index f57f2a737a..44c03159a4 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -204,7 +204,7 @@ AutomationController::toggled () _controllable->set_automation_state(Write); } if (_controllable->list()) { - _controllable->list()->set_in_write_pass(true, false, _controllable->session().audible_frame()); + _controllable->list()->set_in_write_pass(true, true, _controllable->session().audible_frame()); } } const bool was_active = _controllable->get_value() >= 0.5; diff --git a/gtk2_ardour/automation_region_view.cc b/gtk2_ardour/automation_region_view.cc index 7e330949de..b418d096f2 100644 --- a/gtk2_ardour/automation_region_view.cc +++ b/gtk2_ardour/automation_region_view.cc @@ -190,7 +190,7 @@ AutomationRegionView::add_automation_event (GdkEvent *, framepos_t when, double view->editor().begin_reversible_command (_("add automation event")); XMLNode& before = _line->the_list()->get_state(); - _line->the_list()->add (when_d, y, with_guard_points, false); + _line->the_list()->editor_add (when_d, y, with_guard_points); XMLNode& after = _line->the_list()->get_state(); diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 6d3a506cfa..d5276e0cc5 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -644,10 +644,10 @@ AutomationTimeAxisView::add_automation_event (GdkEvent* event, framepos_t when, _editor.begin_reversible_command (_("add automation event")); XMLNode& before = list->get_state(); - list->add (when, y, with_guard_points); + list->editor_add (when, y, with_guard_points); XMLNode& after = list->get_state(); - _session->add_command (new MementoCommand (*list, &before, &after)); + _session->add_command (new MementoCommand (*list.get (), &before, &after)); _editor.commit_reversible_command (); _session->set_dirty (); } diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index b079972a1b..229b1ae1a0 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -5521,8 +5521,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->editor_add (p, value (the_list, p)); - the_list->editor_add (q, value (the_list, q)); + the_list->editor_add (p, value (the_list, p), false); + the_list->editor_add (q, value (the_list, q), false); } /* same thing for the end */ @@ -5547,8 +5547,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->editor_add (p, value (the_list, p)); - the_list->editor_add (q, value (the_list, q)); + the_list->editor_add (p, value (the_list, p), false); + the_list->editor_add (q, value (the_list, q), false); } } diff --git a/libs/ardour/automation_watch.cc b/libs/ardour/automation_watch.cc index 4e833fceb5..3714f17502 100644 --- a/libs/ardour/automation_watch.cc +++ b/libs/ardour/automation_watch.cc @@ -128,7 +128,7 @@ AutomationWatch::timer () (*aw)->list()->add (time, (*aw)->user_double(), true); } } - } else { //transport stopped or reversed. stop the automation pass and start a new one (for bonus points, someday store the previous pass in an undo record) + } else if (time != _last_time) { //transport stopped or reversed. stop the automation pass and start a new one (for bonus points, someday store the previous pass in an undo record) for (AutomationWatches::iterator aw = automation_watches.begin(); aw != automation_watches.end(); ++aw) { DEBUG_TRACE (DEBUG::Automation, string_compose ("%1: transport in rewind, speed %2, in write pass ? %3 writing ? %4\n", (*aw)->name(), _session->transport_speed(), _session->transport_rolling(), diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index d2be604e5e..82868cd24c 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -125,7 +125,7 @@ public: void shift (double before, double distance); virtual void add (double when, double value, bool with_guards=true, bool with_initial=true); - virtual void editor_add (double when, double value); + virtual void editor_add (double when, double value, bool with_guard); void fast_simple_add (double when, double value); diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 2f1d8f4243..d592be3491 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -452,7 +452,7 @@ ControlList::in_write_pass () const } void -ControlList::editor_add (double when, double value) +ControlList::editor_add (double when, double value, bool with_guard) { /* this is for making changes from a graphical line editor */ @@ -464,8 +464,8 @@ ControlList::editor_add (double when, double value) */ 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)); + _events.insert (_events.end(), new ControlEvent (0, value)); + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added value %2 at zero\n", this, value)); } } @@ -473,6 +473,9 @@ ControlList::editor_add (double when, double value) iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); DEBUG_TRACE (DEBUG::ControlList, string_compose ("editor_add: actually add when= %1 value= %2\n", when, value)); _events.insert (i, new ControlEvent (when, value)); + if (with_guard) { + add_guard_point (when); + } mark_dirty (); @@ -491,9 +494,9 @@ ControlList::maybe_add_insert_guard (double when) new control point so that our insert will happen correctly. */ most_recent_insert_iterator = _events.insert ( most_recent_insert_iterator, - new ControlEvent (when + 1, (*most_recent_insert_iterator)->value)); + new ControlEvent (when + 64, (*most_recent_insert_iterator)->value)); DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 added insert guard point @ %2 = %3\n", - this, when+1, + this, when + 64, (*most_recent_insert_iterator)->value)); } } @@ -632,15 +635,6 @@ ControlList::add (double when, double value, bool with_guards, bool with_initial * before it if needed then reset the value of the point. */ - if ((when > 0) && most_recent_insert_iterator != _events.begin ()) { - --most_recent_insert_iterator; - double last_when = (*most_recent_insert_iterator)->when; - ++most_recent_insert_iterator; - if (when - last_when > 64) { - add_guard_point (when - 64); - } - } - (*most_recent_insert_iterator)->value = value; /* if we modified the final value, then its as @@ -658,10 +652,35 @@ ControlList::add (double when, double value, bool with_guards, bool with_initial } else { DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert new point at %2 at iterator at %3\n", this, when, (*most_recent_insert_iterator)->when)); - - const bool done = maybe_insert_straight_line (when, value); + bool done = false; + /* check for possible straight line here until maybe_insert_straight_line () handles the insert iterator properly*/ + if (most_recent_insert_iterator != _events.begin ()) { + bool have_point2 = false; + --most_recent_insert_iterator; + const bool have_point1 = (*most_recent_insert_iterator)->value == value; + + if (most_recent_insert_iterator != _events.begin ()) { + --most_recent_insert_iterator; + have_point2 = (*most_recent_insert_iterator)->value == value; + ++most_recent_insert_iterator; + } + + if (have_point1 && have_point2) { + (*most_recent_insert_iterator)->when = when; + done = true; + } else { + ++most_recent_insert_iterator; + } + } + //done = maybe_insert_straight_line (when, value) || done; + /* if the transport is stopped, add guard points (?) */ + if (!done && !_in_write_pass && when > 64) { + add_guard_point (when - 64); + maybe_add_insert_guard (when); + } + if (with_guards) { - maybe_add_insert_guard(when); + maybe_add_insert_guard (when); } if (!done) { From 15336d06e41fed130f1a0db9eee07b74546c7d92 Mon Sep 17 00:00:00 2001 From: nick_m Date: Wed, 17 Jun 2015 00:39:20 +1000 Subject: [PATCH 04/19] Add undo for automation write. --- libs/ardour/automation_control.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 4ece790248..f2361c2b30 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -116,8 +116,16 @@ AutomationControl::set_automation_style (AutoStyle as) void AutomationControl::start_touch(double when) { - if (!_list) return; + if (!_list) { + return; + } + if (!touching()) { + + if (alist()->automation_state() == Write) { + _before = &alist ()->get_state (); + } + if (alist()->automation_state() == Touch) { /* subtle. aligns the user value with the playback */ set_value (get_value ()); @@ -137,13 +145,20 @@ AutomationControl::stop_touch(bool mark, double when) if (!_list) return; if (touching()) { set_touching (false); + + if (alist()->automation_state() == Write) { + _session.begin_reversible_command (string_compose (_("write %1 automation"), name ())); + _session.add_command (new MementoCommand (*alist ().get (), _before, &alist ()->get_state ())); + _session.commit_reversible_command (); + } + if (alist()->automation_state() == Touch) { alist()->stop_touch (mark, when); if (!_desc.toggled) { AutomationWatch::instance().remove_automation_watch (shared_from_this()); } - _session.begin_reversible_command (_("record automation controller")); + _session.begin_reversible_command (string_compose (_("touch %1 automation"), name ())); _session.add_command (new MementoCommand (*alist ().get (), _before, &alist ()->get_state ())); _session.commit_reversible_command (); } From 4c1d79af4a253ff8a031a7c07a6fdd8d92d0b0e3 Mon Sep 17 00:00:00 2001 From: nick_m Date: Wed, 17 Jun 2015 00:45:04 +1000 Subject: [PATCH 05/19] Unbreak region brush drag wrt undo, avoid some dangling commands in the gui - also allow moving of automation lines in internal mouse mode. - this is also a first pass at ensuring that if an operation does nothing, avoid an undo entry. --- gtk2_ardour/editor_drag.cc | 30 ++++---- gtk2_ardour/editor_mouse.cc | 11 ++- gtk2_ardour/editor_ops.cc | 140 ++++++++++++++++++++++++----------- gtk2_ardour/editor_timefx.cc | 2 + 4 files changed, 121 insertions(+), 62 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 229b1ae1a0..d3ed92a97c 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -619,6 +619,11 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) assert(_last_pointer_time_axis_view >= 0); _last_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second; } + + if (_brushing) { + /* cross track dragging seems broken here. disabled for now. */ + _y_constrained = true; + } } double @@ -1223,13 +1228,13 @@ void RegionMoveDrag::motion (GdkEvent* event, bool first_move) { if (_copy && first_move) { - - if (_x_constrained) { + if (_x_constrained && !_brushing) { _editor->begin_reversible_command (Operations::fixed_time_region_copy); - } else { + } else if (!_brushing) { _editor->begin_reversible_command (Operations::region_copy); + } else if (_brushing) { + _editor->begin_reversible_command (Operations::drag_region_brush); } - /* duplicate the regionview(s) and region(s) */ list new_regionviews; @@ -1287,14 +1292,14 @@ RegionMoveDrag::motion (GdkEvent* event, bool first_move) } } else if (!_copy && first_move) { - - if (_x_constrained) { + if (_x_constrained && !_brushing) { _editor->begin_reversible_command (_("fixed time region drag")); - } else { + } else if (!_brushing) { _editor->begin_reversible_command (Operations::region_drag); + } else if (_brushing) { + _editor->begin_reversible_command (Operations::drag_region_brush); } } - RegionMotionDrag::motion (event, first_move); } @@ -1502,12 +1507,6 @@ RegionMoveDrag::finished_no_copy ( set views_to_update; RouteTimeAxisView* new_time_axis_view = 0; - if (_brushing) { - /* all changes were made during motion event handlers */ - _editor->commit_reversible_command (); - return; - } - typedef map, RouteTimeAxisView*> PlaylistMapping; PlaylistMapping playlist_mapping; @@ -1621,7 +1620,6 @@ RegionMoveDrag::finished_no_copy ( } rv->region()->set_position (where); - _editor->session()->add_command (new StatefulDiffCommand (rv->region())); } @@ -1670,7 +1668,7 @@ RegionMoveDrag::finished_no_copy ( /* write commands for the accumulated diffs for all our modified playlists */ add_stateful_diff_commands_for_playlists (modified_playlists); - + /* applies to _brushing */ _editor->commit_reversible_command (); /* We have futzed with the layering of canvas items on our streamviews. diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 5c106785e2..8c5e6711f9 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -766,6 +766,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT return true; break; + case AutomationLineItem: + _drags->set (new LineDrag (this, item), event); + return true; + break; + case StreamItem: //in the past, we created a new midi region here, but perhaps that is best left to the Draw mode break; @@ -2200,7 +2205,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, framepos_t pos) // playlist is frozen, so we have to update manually XXX this is disgusting - playlist->RegionAdded (new_region); /* EMIT SIGNAL */ + //playlist->RegionAdded (new_region); /* EMIT SIGNAL */ } gint @@ -2262,8 +2267,6 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* } _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), true, false)); - - begin_reversible_command (Operations::drag_region_brush); } /** Start a grab where a time range is selected, track(s) are selected, and the @@ -2303,7 +2306,6 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event) /* A selection grab currently creates two undo/redo operations, one for creating the new region and another for moving it. */ - begin_reversible_command (Operations::selection_grab); boost::shared_ptr playlist = clicked_axisview->playlist(); @@ -2316,6 +2318,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* /*item*/, GdkEvent* event) if (latest_regionviews.empty()) { /* something went wrong */ + abort_reversible_command (); return; } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 5c45951e04..41b7bcc8eb 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -336,9 +336,9 @@ Editor::move_range_selection_start_or_end_to_region_boundary (bool move_end, boo return; } - begin_reversible_command (_("alter selection")); + begin_reversible_selection_op (_("alter selection")); selection->set_preserving_all_ranges (start, end); - commit_reversible_command (); + commit_reversible_selection_op (); } bool @@ -2172,10 +2172,7 @@ void Editor::remove_location_at_playhead_cursor () { if (_session) { - //set up for undo - begin_reversible_command (_("remove marker")); - XMLNode &before = _session->locations()->get_state(); bool removed = false; @@ -2191,6 +2188,7 @@ Editor::remove_location_at_playhead_cursor () //store undo if (removed) { + begin_reversible_command (_("remove marker")); XMLNode &after = _session->locations()->get_state(); _session->add_command(new MementoCommand(*(_session->locations()), &before, &after)); @@ -2238,8 +2236,6 @@ Editor::add_location_from_region () return; } - begin_reversible_command (_("add marker")); - XMLNode &before = _session->locations()->get_state(); string markername; @@ -2256,6 +2252,7 @@ Editor::add_location_from_region () return; } + begin_reversible_command (_("add marker")); // single range spanning all selected Location *location = new Location (*_session, selection->regions.start(), selection->regions.end_frame(), markername, Location::IsRangeMarker); _session->locations()->add (location, true); @@ -3302,6 +3299,7 @@ void Editor::region_fill_track () { RegionSelection rs = get_regions_from_selection_and_entered (); + bool commit = false; if (!_session || rs.empty()) { return; @@ -3318,21 +3316,27 @@ Editor::region_fill_track () boost::shared_ptr pl = region->playlist(); if (end <= region->last_frame()) { - return; + goto out; } double times = (double) (end - region->last_frame()) / (double) region->length(); if (times == 0) { - return; + goto out; } pl->clear_changes (); pl->add_region (RegionFactory::create (region, true), region->last_frame(), times); _session->add_command (new StatefulDiffCommand (pl)); + commit = true; } - commit_reversible_command (); +out: + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -3362,6 +3366,7 @@ Editor::region_fill_selection () framepos_t selection_length = end - start; float times = (float)selection_length / region->length(); + bool commit = false; begin_reversible_command (Operations::fill_selection); @@ -3376,9 +3381,14 @@ Editor::region_fill_selection () playlist->clear_changes (); playlist->add_region (RegionFactory::create (region, true), start, times); _session->add_command (new StatefulDiffCommand (playlist)); + commit = true; } - commit_reversible_command (); + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -3730,7 +3740,7 @@ void Editor::trim_to_region(bool forward) { RegionSelection rs = get_regions_from_selection_and_entered (); - + bool commit = false; begin_reversible_command (_("trim to region")); boost::shared_ptr next_region; @@ -3746,7 +3756,7 @@ Editor::trim_to_region(bool forward) AudioTimeAxisView* atav = dynamic_cast (&arv->get_time_axis_view()); if (!atav) { - return; + continue; } float speed = 1.0; @@ -3786,9 +3796,14 @@ Editor::trim_to_region(bool forward) } _session->add_command(new StatefulDiffCommand (region)); + commit = true; } - commit_reversible_command (); + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -3927,7 +3942,7 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) boost::shared_ptr playlist; if ((playlist = rtv->playlist()) == 0) { - return; + continue; } InterThreadInfo itt; @@ -5281,6 +5296,7 @@ void Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress) { RegionSelection rs = get_regions_from_selection_and_entered (); + bool commit = false; if (rs.empty()) { return; @@ -5331,7 +5347,6 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress } } - /* We might have removed regions, which alters other regions' layering_index, so we need to do a recursive diff here. */ @@ -5340,8 +5355,9 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress _session->add_commands (cmds); _session->add_command(new StatefulDiffCommand (playlist)); + commit = true; } else { - return; + goto out; } if (progress) { @@ -5352,8 +5368,12 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress r = tmp; ++n; } - - commit_reversible_command (); +out: + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -5643,6 +5663,7 @@ Editor::set_fade_length (bool in) framepos_t pos = get_preferred_edit_position(); framepos_t len; char const * cmd; + bool commit = false; if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) { /* edit point is outside the relevant region */ @@ -5671,7 +5692,7 @@ Editor::set_fade_length (bool in) AudioRegionView* tmp = dynamic_cast (*x); if (!tmp) { - return; + continue; } boost::shared_ptr alist; @@ -5690,12 +5711,16 @@ Editor::set_fade_length (bool in) tmp->audio_region()->set_fade_out_length (len); tmp->audio_region()->set_fade_out_active (true); } - XMLNode &after = alist->get_state(); _session->add_command(new MementoCommand(*alist, &before, &after)); + commit = true; } - commit_reversible_command (); + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -5706,14 +5731,14 @@ Editor::set_fade_in_shape (FadeShape shape) if (rs.empty()) { return; } - + bool commit = false; begin_reversible_command (_("set fade in shape")); for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); if (!tmp) { - return; + continue; } boost::shared_ptr alist = tmp->audio_region()->fade_in(); @@ -5723,10 +5748,14 @@ Editor::set_fade_in_shape (FadeShape shape) XMLNode &after = alist->get_state(); _session->add_command(new MementoCommand(*alist.get(), &before, &after)); + commit = true; } - commit_reversible_command (); - + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -5737,14 +5766,14 @@ Editor::set_fade_out_shape (FadeShape shape) if (rs.empty()) { return; } - + bool commit = false; begin_reversible_command (_("set fade out shape")); for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); if (!tmp) { - return; + continue; } boost::shared_ptr alist = tmp->audio_region()->fade_out(); @@ -5754,9 +5783,14 @@ Editor::set_fade_out_shape (FadeShape shape) XMLNode &after = alist->get_state(); _session->add_command(new MementoCommand(*alist.get(), &before, &after)); + commit = true; } - commit_reversible_command (); + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -5767,14 +5801,14 @@ Editor::set_fade_in_active (bool yn) if (rs.empty()) { return; } - + bool commit = false; begin_reversible_command (_("set fade in active")); for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); if (!tmp) { - return; + continue; } @@ -5783,9 +5817,14 @@ Editor::set_fade_in_active (bool yn) ar->clear_changes (); ar->set_fade_in_active (yn); _session->add_command (new StatefulDiffCommand (ar)); + commit = true; } - commit_reversible_command (); + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -5796,14 +5835,14 @@ Editor::set_fade_out_active (bool yn) if (rs.empty()) { return; } - + bool commit = false; begin_reversible_command (_("set fade out active")); for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); if (!tmp) { - return; + continue; } boost::shared_ptr ar (tmp->audio_region()); @@ -5811,9 +5850,14 @@ Editor::set_fade_out_active (bool yn) ar->clear_changes (); ar->set_fade_out_active (yn); _session->add_command(new StatefulDiffCommand (ar)); + commit = true; } - commit_reversible_command (); + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); + } } void @@ -5849,11 +5893,15 @@ Editor::toggle_region_fades (int dir) } /* XXX should this undo-able? */ + bool commit = false; + begin_reversible_command (_("toggle fade active")); for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { if ((ar = boost::dynamic_pointer_cast((*i)->region())) == 0) { continue; } + ar->clear_changes (); + if (dir == 1 || dir == 0) { ar->set_fade_in_active (!yn); } @@ -5861,6 +5909,14 @@ Editor::toggle_region_fades (int dir) if (dir == -1 || dir == 0) { ar->set_fade_out_active (!yn); } + _session->add_command(new StatefulDiffCommand (ar)); + commit = true; + } + + if (commit) { + commit_reversible_command (); + } else { + abort_reversible_command (); } } @@ -6958,12 +7014,11 @@ Editor::insert_time ( bool all_playlists, bool ignore_music_glue, bool markers_too, bool glued_markers_too, bool locked_markers_too, bool tempo_too ) { - bool commit = false; if (Config->get_edit_mode() == Lock) { return; } - + bool commit = false; begin_reversible_command (_("insert time")); TrackViewList ts = selection->tracks.filter_to_unique_playlists (); @@ -7016,7 +7071,6 @@ Editor::insert_time ( RouteTimeAxisView* rtav = dynamic_cast (*x); if (rtav) { rtav->route ()->shift (pos, frames); - commit = true; } } @@ -7055,6 +7109,7 @@ Editor::insert_time ( if (moved) { XMLNode& after (_session->locations()->get_state()); _session->add_command (new MementoCommand(*_session->locations(), &before, &after)); + commit = true; } } @@ -7064,6 +7119,8 @@ Editor::insert_time ( if (commit) { commit_reversible_command (); + } else { + abort_reversible_command (); } } void @@ -7131,13 +7188,11 @@ void Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, bool ignore_music_glue, bool markers_too, bool tempo_too) { - bool commit = false; - if (Config->get_edit_mode() == Lock) { error << (_("Cannot insert or delete time when in Lock edit.")) << endmsg; return; } - + bool commit = false; begin_reversible_command (_("cut time")); for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) { @@ -7164,7 +7219,6 @@ Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, RouteTimeAxisView* rtav = dynamic_cast (*x); if (rtav) { rtav->route ()->shift (pos, -frames); - commit = true; } } @@ -7233,6 +7287,8 @@ Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, if (commit) { commit_reversible_command (); + } else { + abort_reversible_command (); } } diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc index 2025ec70c3..5908e50249 100644 --- a/gtk2_ardour/editor_timefx.cc +++ b/gtk2_ardour/editor_timefx.cc @@ -133,6 +133,8 @@ Editor::pitch_shift (RegionSelection& regions, float fraction) if (ret == 0) { commit_reversible_command (); + } else { + abort_reversible_command (); } return ret; From d019ee836ca70965e6b981b6bde2a77ad11cb98a Mon Sep 17 00:00:00 2001 From: nick_m Date: Wed, 17 Jun 2015 05:44:00 +1000 Subject: [PATCH 06/19] Use a better pattern to avoid abort_reversible_command(). - also, duplicated regoins are now selected and some end-of sesion bugs fixed there. - should fix lack of tempomap undo in Editor::insert_time () --- gtk2_ardour/editor_ops.cc | 429 +++++++++++++++++++++++++------------- 1 file changed, 288 insertions(+), 141 deletions(-) diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 41b7bcc8eb..14c6f91237 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -400,8 +400,7 @@ Editor::nudge_forward (bool next, bool force_playhead) } else if (!force_playhead && !selection->markers.empty()) { bool is_start; - - begin_reversible_command (_("nudge location forward")); + bool in_command = false; for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) { @@ -432,13 +431,18 @@ Editor::nudge_forward (bool next, bool force_playhead) loc->set_end (max_framepos); } } + if (!in_command) { + begin_reversible_command (_("nudge location forward")); + in_command = true; + } XMLNode& after (loc->get_state()); _session->add_command (new MementoCommand(*loc, &before, &after)); } } - commit_reversible_command (); - + if (in_command) { + commit_reversible_command (); + } } else { distance = get_nudge_distance (playhead_cursor->current_frame (), next_distance); _session->request_locate (playhead_cursor->current_frame () + distance); @@ -485,8 +489,7 @@ Editor::nudge_backward (bool next, bool force_playhead) } else if (!force_playhead && !selection->markers.empty()) { bool is_start; - - begin_reversible_command (_("nudge location forward")); + bool in_command = false; for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) { @@ -519,13 +522,17 @@ Editor::nudge_backward (bool next, bool force_playhead) loc->set_end (loc->length()); } } - + if (!in_command) { + begin_reversible_command (_("nudge location forward")); + in_command = true; + } XMLNode& after (loc->get_state()); _session->add_command (new MementoCommand(*loc, &before, &after)); } } - - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } else { @@ -615,7 +622,8 @@ Editor::sequence_regions () if (!rs.empty()) { - begin_reversible_command (_("sequence regions")); + bool in_command = false; + for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { boost::shared_ptr r ((*i)->region()); @@ -635,13 +643,20 @@ Editor::sequence_regions () r->set_position(r_end_prev); } + if (!in_command) { + begin_reversible_command (_("sequence regions")); + in_command = true; + } _session->add_command (new StatefulDiffCommand (r)); r_end=r->position() + r->length(); iCount++; } - commit_reversible_command (); + + if (in_command) { + commit_reversible_command (); + } } } @@ -2191,7 +2206,6 @@ Editor::remove_location_at_playhead_cursor () begin_reversible_command (_("remove marker")); XMLNode &after = _session->locations()->get_state(); _session->add_command(new MementoCommand(*(_session->locations()), &before, &after)); - commit_reversible_command (); } } @@ -2206,8 +2220,7 @@ Editor::add_locations_from_region () if (rs.empty()) { return; } - - begin_reversible_command (selection->regions.size () > 1 ? _("add markers") : _("add marker")); + bool commit = false; XMLNode &before = _session->locations()->get_state(); @@ -2218,12 +2231,15 @@ Editor::add_locations_from_region () Location *location = new Location (*_session, region->position(), region->last_frame(), region->name(), Location::IsRangeMarker); _session->locations()->add (location, true); + commit = true; } - XMLNode &after = _session->locations()->get_state(); - _session->add_command (new MementoCommand(*(_session->locations()), &before, &after)); - - commit_reversible_command (); + if (commit) { + begin_reversible_command (selection->regions.size () > 1 ? _("add markers") : _("add marker")); + XMLNode &after = _session->locations()->get_state(); + _session->add_command (new MementoCommand(*(_session->locations()), &before, &after)); + commit_reversible_command (); + } } /** Add a single range marker around all selected regions */ @@ -2252,14 +2268,13 @@ Editor::add_location_from_region () return; } - begin_reversible_command (_("add marker")); // single range spanning all selected Location *location = new Location (*_session, selection->regions.start(), selection->regions.end_frame(), markername, Location::IsRangeMarker); _session->locations()->add (location, true); + begin_reversible_command (_("add marker")); XMLNode &after = _session->locations()->get_state(); _session->add_command (new MementoCommand(*(_session->locations()), &before, &after)); - commit_reversible_command (); } @@ -3261,8 +3276,7 @@ Editor::crop_region_to (framepos_t start, framepos_t end) framepos_t the_start; framepos_t the_end; framepos_t cnt; - - begin_reversible_command (_("trim to selection")); + bool in_command = false; for (vector >::iterator i = playlists.begin(); i != playlists.end(); ++i) { @@ -3287,27 +3301,32 @@ Editor::crop_region_to (framepos_t start, framepos_t end) the_end = min (end, the_end); cnt = the_end - the_start + 1; + if(!in_command) { + begin_reversible_command (_("trim to selection")); + in_command = true; + } region->clear_changes (); region->trim_to (the_start, cnt); _session->add_command (new StatefulDiffCommand (region)); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } void Editor::region_fill_track () { RegionSelection rs = get_regions_from_selection_and_entered (); - bool commit = false; if (!_session || rs.empty()) { return; } framepos_t const end = _session->current_end_frame (); - - begin_reversible_command (Operations::region_fill); + RegionSelection foo; + bool in_command = false; for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { @@ -3316,26 +3335,38 @@ Editor::region_fill_track () boost::shared_ptr pl = region->playlist(); if (end <= region->last_frame()) { - goto out; + continue; } double times = (double) (end - region->last_frame()) / (double) region->length(); if (times == 0) { - goto out; + continue; } + if (!in_command) { + begin_reversible_command (Operations::region_fill); + in_command = true; + } + TimeAxisView& tv = (*i)->get_time_axis_view(); + RouteTimeAxisView* rtv = dynamic_cast (&tv); + latest_regionviews.clear (); + sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view)); + pl->clear_changes (); pl->add_region (RegionFactory::create (region, true), region->last_frame(), times); _session->add_command (new StatefulDiffCommand (pl)); - commit = true; + + c.disconnect (); + + foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end()); } -out: - if (commit) { + if (in_command) { + if (!foo.empty()) { + selection->set (foo); + } commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -3366,11 +3397,10 @@ Editor::region_fill_selection () framepos_t selection_length = end - start; float times = (float)selection_length / region->length(); - bool commit = false; - - begin_reversible_command (Operations::fill_selection); + bool in_command = false; TrackViewList ts = selection->tracks.filter_to_unique_playlists (); + RegionSelection foo; for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) { @@ -3378,16 +3408,26 @@ Editor::region_fill_selection () continue; } + if (!in_command) { + begin_reversible_command (Operations::fill_selection); + in_command = true; + } + RouteTimeAxisView* rtv = dynamic_cast (*i); + latest_regionviews.clear (); + sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view)); + playlist->clear_changes (); playlist->add_region (RegionFactory::create (region, true), start, times); _session->add_command (new StatefulDiffCommand (playlist)); - commit = true; + c.disconnect (); + foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end()); } - if (commit) { + if (in_command) { + if (!foo.empty()) { + selection->set (foo); + } commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -3686,8 +3726,7 @@ void Editor::trim_region_to_location (const Location& loc, const char* str) { RegionSelection rs = get_regions_from_selection_and_entered (); - - begin_reversible_command (str); + bool in_command = false; for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { RegionView* rv = (*x); @@ -3718,10 +3757,17 @@ Editor::trim_region_to_location (const Location& loc, const char* str) rv->region()->clear_changes (); rv->region()->trim_to (start, (end - start)); + + if (!in_command) { + begin_reversible_command (str); + in_command = true; + } _session->add_command(new StatefulDiffCommand (rv->region())); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } void @@ -3740,8 +3786,7 @@ void Editor::trim_to_region(bool forward) { RegionSelection rs = get_regions_from_selection_and_entered (); - bool commit = false; - begin_reversible_command (_("trim to region")); + bool in_command = false; boost::shared_ptr next_region; @@ -3795,14 +3840,15 @@ Editor::trim_to_region(bool forward) arv->region_changed (ARDOUR::bounds_change); } + if (!in_command) { + begin_reversible_command (_("trim to region")); + in_command = true; + } _session->add_command(new StatefulDiffCommand (region)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -3928,8 +3974,7 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) framepos_t start = selection->time[clicked_selection].start; framepos_t end = selection->time[clicked_selection].end; framepos_t cnt = end - start + 1; - - begin_reversible_command (_("bounce range")); + bool in_command = false; for (TrackViewList::iterator i = views.begin(); i != views.end(); ++i) { @@ -3969,6 +4014,10 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) playlist->add_region (r, start); } + if (!in_command) { + begin_reversible_command (_("bounce range")); + in_command = true; + } vector cmds; playlist->rdiff (cmds); _session->add_commands (cmds); @@ -3976,7 +4025,9 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) _session->add_command (new StatefulDiffCommand (playlist)); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } /** Delete selected regions, automation points or a time range */ @@ -4330,8 +4381,6 @@ Editor::remove_selected_regions () return; } - begin_reversible_command (_("remove region")); - list > regions_to_remove; for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { @@ -4375,6 +4424,7 @@ Editor::remove_selected_regions () } vector >::iterator pl; + bool in_command = false; for (pl = playlists.begin(); pl != playlists.end(); ++pl) { (*pl)->thaw (); @@ -4382,6 +4432,11 @@ Editor::remove_selected_regions () /* We might have removed regions, which alters other regions' layering_index, so we need to do a recursive diff here. */ + + if (!in_command) { + begin_reversible_command (_("remove region")); + in_command = true; + } vector cmds; (*pl)->rdiff (cmds); _session->add_commands (cmds); @@ -4389,7 +4444,9 @@ Editor::remove_selected_regions () _session->add_command(new StatefulDiffCommand (*pl)); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } /** Cut, copy or clear selected regions. @@ -4725,6 +4782,10 @@ Editor::paste_internal (framepos_t position, float times) void Editor::duplicate_some_regions (RegionSelection& regions, float times) { + if (regions.empty ()) { + return; + } + boost::shared_ptr playlist; RegionSelection sel = regions; // clear (below) may clear the argument list if its the current region selection RegionSelection foo; @@ -4779,11 +4840,10 @@ Editor::duplicate_selection (float times) return; } - begin_reversible_command (_("duplicate selection")); - ri = new_regions.begin(); TrackViewList ts = selection->tracks.filter_to_unique_playlists (); + bool in_command = false; for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) { if ((playlist = (*i)->playlist()) == 0) { @@ -4797,6 +4857,11 @@ Editor::duplicate_selection (float times) end = selection->time.end_frame(); } playlist->duplicate (*ri, end, times); + + if (!in_command) { + begin_reversible_command (_("duplicate selection")); + in_command = true; + } _session->add_command (new StatefulDiffCommand (playlist)); ++ri; @@ -4805,7 +4870,9 @@ Editor::duplicate_selection (float times) } } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } /** Reset all selected points to the relevant default value */ @@ -4863,9 +4930,8 @@ Editor::nudge_track (bool use_edit, bool forwards) return; } - begin_reversible_command (_("nudge track")); - TrackViewList ts = selection->tracks.filter_to_unique_playlists (); + bool in_command = false; for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) { @@ -4878,6 +4944,10 @@ Editor::nudge_track (bool use_edit, bool forwards) playlist->nudge_after (start, distance, forwards); + if (!in_command) { + begin_reversible_command (_("nudge track")); + in_command = true; + } vector cmds; playlist->rdiff (cmds); @@ -4886,7 +4956,9 @@ Editor::nudge_track (bool use_edit, bool forwards) _session->add_command (new StatefulDiffCommand (playlist)); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } void @@ -4966,9 +5038,8 @@ Editor::normalize_region () } } - begin_reversible_command (_("normalize")); - list::const_iterator a = max_amps.begin (); + bool in_command = false; for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { AudioRegionView* const arv = dynamic_cast (*r); @@ -4981,12 +5052,19 @@ Editor::normalize_region () double const amp = dialog.normalize_individually() ? *a : max_amp; arv->audio_region()->normalize (amp, dialog.target ()); + + if (!in_command) { + begin_reversible_command (_("normalize")); + in_command = true; + } _session->add_command (new StatefulDiffCommand (arv->region())); ++a; } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } @@ -5003,7 +5081,7 @@ Editor::reset_region_scale_amplitude () return; } - begin_reversible_command ("reset gain"); + bool in_command = false; for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { AudioRegionView* const arv = dynamic_cast(*r); @@ -5011,10 +5089,17 @@ Editor::reset_region_scale_amplitude () continue; arv->region()->clear_changes (); arv->audio_region()->set_scale_amplitude (1.0f); + + if(!in_command) { + begin_reversible_command ("reset gain"); + in_command = true; + } _session->add_command (new StatefulDiffCommand (arv->region())); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } void @@ -5026,7 +5111,7 @@ Editor::adjust_region_gain (bool up) return; } - begin_reversible_command ("adjust region gain"); + bool in_command = false; for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { AudioRegionView* const arv = dynamic_cast(*r); @@ -5045,10 +5130,17 @@ Editor::adjust_region_gain (bool up) } arv->audio_region()->set_scale_amplitude (dB_to_coefficient (dB)); + + if (!in_command) { + begin_reversible_command ("adjust region gain"); + in_command = true; + } _session->add_command (new StatefulDiffCommand (arv->region())); } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } @@ -5120,7 +5212,7 @@ Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs) return; } - begin_reversible_command (op.name ()); + bool in_command = false; for (RegionSelection::const_iterator r = rs.begin(); r != rs.end(); ) { RegionSelection::const_iterator tmp = r; @@ -5131,6 +5223,10 @@ Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs) if (mrv) { Command* cmd = apply_midi_note_edit_op_to_region (op, *mrv); if (cmd) { + if (!in_command) { + begin_reversible_command (op.name ()); + in_command = true; + } (*cmd)(); _session->add_command (cmd); } @@ -5139,7 +5235,9 @@ Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs) r = tmp; } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } void @@ -5151,9 +5249,9 @@ Editor::fork_region () return; } - begin_reversible_command (_("Fork Region(s)")); - CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); + bool in_command = false; + gdk_flush (); for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { @@ -5167,7 +5265,11 @@ Editor::fork_region () boost::shared_ptr playlist = mrv->region()->playlist(); boost::shared_ptr new_source = _session->create_midi_source_by_stealing_name (mrv->midi_view()->track()); boost::shared_ptr newregion = mrv->midi_region()->clone (new_source); - + + if (!in_command) { + begin_reversible_command (_("Fork Region(s)")); + in_command = true; + } playlist->clear_changes (); playlist->replace_region (mrv->region(), newregion, mrv->region()->position()); _session->add_command(new StatefulDiffCommand (playlist)); @@ -5179,7 +5281,9 @@ Editor::fork_region () r = tmp; } - commit_reversible_command (); + if (in_command) { + commit_reversible_command (); + } } void @@ -5296,15 +5400,14 @@ void Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress) { RegionSelection rs = get_regions_from_selection_and_entered (); - bool commit = false; if (rs.empty()) { return; } - begin_reversible_command (command); - CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); + bool in_command = false; + gdk_flush (); int n = 0; @@ -5350,14 +5453,19 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress /* We might have removed regions, which alters other regions' layering_index, so we need to do a recursive diff here. */ + + if (!in_command) { + begin_reversible_command (command); + in_command = true; + } vector cmds; playlist->rdiff (cmds); _session->add_commands (cmds); _session->add_command(new StatefulDiffCommand (playlist)); - commit = true; + } else { - goto out; + continue; } if (progress) { @@ -5368,11 +5476,9 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress r = tmp; ++n; } -out: - if (commit) { + + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -5391,7 +5497,7 @@ Editor::reset_region_gain_envelopes () return; } - begin_reversible_command (_("reset region gain")); + bool in_command = false; for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { AudioRegionView* const arv = dynamic_cast(*i); @@ -5400,11 +5506,18 @@ Editor::reset_region_gain_envelopes () XMLNode& before (alist->get_state()); arv->audio_region()->set_default_envelope (); + + if (!in_command) { + begin_reversible_command (_("reset region gain")); + in_command = true; + } _session->add_command (new MementoCommand(*arv->audio_region()->envelope().get(), &before, &alist->get_state())); } } - - commit_reversible_command (); + + if (in_command) { + commit_reversible_command (); + } } void @@ -5444,18 +5557,25 @@ Editor::toggle_gain_envelope_active () return; } - begin_reversible_command (_("region gain envelope active")); - + bool in_command = false; + for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { AudioRegionView* const arv = dynamic_cast(*i); if (arv) { arv->region()->clear_changes (); arv->audio_region()->set_envelope_active (!arv->audio_region()->envelope_active()); + + if (!in_command) { + begin_reversible_command (_("region gain envelope active")); + in_command = true; + } _session->add_command (new StatefulDiffCommand (arv->region())); } } - - commit_reversible_command (); + + if (in_command) { + commit_reversible_command (); + } } void @@ -5663,7 +5783,6 @@ Editor::set_fade_length (bool in) framepos_t pos = get_preferred_edit_position(); framepos_t len; char const * cmd; - bool commit = false; if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) { /* edit point is outside the relevant region */ @@ -5686,7 +5805,7 @@ Editor::set_fade_length (bool in) cmd = _("set fade out length"); } - begin_reversible_command (cmd); + bool in_command = false; for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); @@ -5711,15 +5830,17 @@ Editor::set_fade_length (bool in) tmp->audio_region()->set_fade_out_length (len); tmp->audio_region()->set_fade_out_active (true); } + + if (!in_command) { + begin_reversible_command (cmd); + in_command = true; + } XMLNode &after = alist->get_state(); _session->add_command(new MementoCommand(*alist, &before, &after)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -5731,8 +5852,7 @@ Editor::set_fade_in_shape (FadeShape shape) if (rs.empty()) { return; } - bool commit = false; - begin_reversible_command (_("set fade in shape")); + bool in_command = false; for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); @@ -5746,15 +5866,16 @@ Editor::set_fade_in_shape (FadeShape shape) tmp->audio_region()->set_fade_in_shape (shape); + if (!in_command) { + begin_reversible_command (_("set fade in shape")); + in_command = true; + } XMLNode &after = alist->get_state(); _session->add_command(new MementoCommand(*alist.get(), &before, &after)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -5766,8 +5887,7 @@ Editor::set_fade_out_shape (FadeShape shape) if (rs.empty()) { return; } - bool commit = false; - begin_reversible_command (_("set fade out shape")); + bool in_command = false; for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); @@ -5781,15 +5901,16 @@ Editor::set_fade_out_shape (FadeShape shape) tmp->audio_region()->set_fade_out_shape (shape); + if(!in_command) { + begin_reversible_command (_("set fade out shape")); + in_command = true; + } XMLNode &after = alist->get_state(); _session->add_command(new MementoCommand(*alist.get(), &before, &after)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -5801,8 +5922,7 @@ Editor::set_fade_in_active (bool yn) if (rs.empty()) { return; } - bool commit = false; - begin_reversible_command (_("set fade in active")); + bool in_command = false; for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); @@ -5816,14 +5936,16 @@ Editor::set_fade_in_active (bool yn) ar->clear_changes (); ar->set_fade_in_active (yn); + + if (!in_command) { + begin_reversible_command (_("set fade in active")); + in_command = true; + } _session->add_command (new StatefulDiffCommand (ar)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -5835,8 +5957,7 @@ Editor::set_fade_out_active (bool yn) if (rs.empty()) { return; } - bool commit = false; - begin_reversible_command (_("set fade out active")); + bool in_command = false; for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { AudioRegionView* tmp = dynamic_cast (*x); @@ -5849,14 +5970,16 @@ Editor::set_fade_out_active (bool yn) ar->clear_changes (); ar->set_fade_out_active (yn); + + if (!in_command) { + begin_reversible_command (_("set fade out active")); + in_command = true; + } _session->add_command(new StatefulDiffCommand (ar)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -5893,8 +6016,7 @@ Editor::toggle_region_fades (int dir) } /* XXX should this undo-able? */ - bool commit = false; - begin_reversible_command (_("toggle fade active")); + bool in_command = false; for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { if ((ar = boost::dynamic_pointer_cast((*i)->region())) == 0) { @@ -5909,14 +6031,15 @@ Editor::toggle_region_fades (int dir) if (dir == -1 || dir == 0) { ar->set_fade_out_active (!yn); } + if (!in_command) { + begin_reversible_command (_("toggle fade active")); + in_command = true; + } _session->add_command(new StatefulDiffCommand (ar)); - commit = true; } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } @@ -7018,8 +7141,7 @@ Editor::insert_time ( if (Config->get_edit_mode() == Lock) { return; } - bool commit = false; - begin_reversible_command (_("insert time")); + bool in_command = false; TrackViewList ts = selection->tracks.filter_to_unique_playlists (); @@ -7059,17 +7181,24 @@ Editor::insert_time ( (*i)->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue); + if (!in_command) { + begin_reversible_command (_("insert time")); + in_command = true; + } vector cmds; (*i)->rdiff (cmds); _session->add_commands (cmds); _session->add_command (new StatefulDiffCommand (*i)); - commit = true; } /* automation */ RouteTimeAxisView* rtav = dynamic_cast (*x); if (rtav) { + if (!in_command) { + begin_reversible_command (_("insert time")); + in_command = true; + } rtav->route ()->shift (pos, frames); } } @@ -7107,20 +7236,28 @@ Editor::insert_time ( } if (moved) { + if (!in_command) { + begin_reversible_command (_("insert time")); + in_command = true; + } XMLNode& after (_session->locations()->get_state()); _session->add_command (new MementoCommand(*_session->locations(), &before, &after)); - commit = true; } } if (tempo_too) { + if (!in_command) { + begin_reversible_command (_("insert time")); + in_command = true; + } + XMLNode& before (_session->tempo_map().get_state()); _session->tempo_map().insert_time (pos, frames); + XMLNode& after (_session->tempo_map().get_state()); + _session->add_command (new MementoCommand(_session->tempo_map(), &before, &after)); } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } void @@ -7192,8 +7329,7 @@ Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, error << (_("Cannot insert or delete time when in Lock edit.")) << endmsg; return; } - bool commit = false; - begin_reversible_command (_("cut time")); + bool in_command = false; for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) { /* regions */ @@ -7209,15 +7345,22 @@ Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, pl->cut (rl); pl->shift (pos, -frames, true, ignore_music_glue); + if (!in_command) { + begin_reversible_command (_("cut time")); + in_command = true; + } XMLNode &after = pl->get_state(); _session->add_command (new MementoCommand (*pl, &before, &after)); - commit = true; } /* automation */ RouteTimeAxisView* rtav = dynamic_cast (*x); if (rtav) { + if (!in_command) { + begin_reversible_command (_("cut time")); + in_command = true; + } rtav->route ()->shift (pos, -frames); } } @@ -7269,9 +7412,12 @@ Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, } if (moved) { + if (!in_command) { + begin_reversible_command (_("cut time")); + in_command = true; + } XMLNode& after (_session->locations()->get_state()); _session->add_command (new MementoCommand(*_session->locations(), &before, &after)); - commit = true; } } @@ -7279,16 +7425,17 @@ Editor::cut_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, XMLNode& before (_session->tempo_map().get_state()); if (_session->tempo_map().cut_time (pos, frames) ) { + if (!in_command) { + begin_reversible_command (_("cut time")); + in_command = true; + } XMLNode& after (_session->tempo_map().get_state()); _session->add_command (new MementoCommand(_session->tempo_map(), &before, &after)); - commit = true; } } - if (commit) { + if (in_command) { commit_reversible_command (); - } else { - abort_reversible_command (); } } From 44790ebff017173ff6a593c1278bbe6cbab3fa4b Mon Sep 17 00:00:00 2001 From: nick_m Date: Wed, 17 Jun 2015 09:26:40 +1000 Subject: [PATCH 07/19] More _reversible_command() auditing in the gui. - try to keep begin/commit pairs in the same file where possible. --- gtk2_ardour/automation_line.cc | 3 --- gtk2_ardour/editor_drag.cc | 43 ++++++++++++++++++++++++---------- gtk2_ardour/midi_time_axis.cc | 5 ++-- gtk2_ardour/region_editor.cc | 33 +++++++++++++++++--------- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 069a823155..a354afeeb6 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -466,7 +466,6 @@ AutomationLine::string_to_fraction (string const & s) const void AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction) { - trackview.editor().begin_reversible_command (_("automation event move")); trackview.editor().session()->add_command ( new MementoCommand (memento_command_binder(), &get_state(), 0)); @@ -492,7 +491,6 @@ AutomationLine::start_drag_single (ControlPoint* cp, double x, float fraction) void AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction) { - trackview.editor().begin_reversible_command (_("automation range move")); trackview.editor().session()->add_command ( new MementoCommand (memento_command_binder (), &get_state(), 0)); @@ -512,7 +510,6 @@ AutomationLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction) void AutomationLine::start_drag_multiple (list cp, float fraction, XMLNode* state) { - trackview.editor().begin_reversible_command (_("automation range move")); trackview.editor().session()->add_command ( new MementoCommand (memento_command_binder(), state, 0)); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index d3ed92a97c..ab08f7f10b 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3479,7 +3479,7 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred) fade_length = pos - region->position(); } - _editor->begin_reversible_command (_("change fade in length")); + bool in_command = false; for (list::iterator i = _views.begin(); i != _views.end(); ++i) { @@ -3495,11 +3495,17 @@ FadeInDrag::finished (GdkEvent* event, bool movement_occurred) tmp->audio_region()->set_fade_in_length (fade_length); tmp->audio_region()->set_fade_in_active (true); + if (!in_command) { + _editor->begin_reversible_command (_("change fade in length")); + in_command = true; + } XMLNode &after = alist->get_state(); _editor->session()->add_command(new MementoCommand(*alist.get(), &before, &after)); } - _editor->commit_reversible_command (); + if (in_command) { + _editor->commit_reversible_command (); + } } void @@ -3598,7 +3604,7 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred) fade_length = region->last_frame() - pos; } - _editor->begin_reversible_command (_("change fade out length")); + bool in_command = false; for (list::iterator i = _views.begin(); i != _views.end(); ++i) { @@ -3614,11 +3620,17 @@ FadeOutDrag::finished (GdkEvent* event, bool movement_occurred) tmp->audio_region()->set_fade_out_length (fade_length); tmp->audio_region()->set_fade_out_active (true); + if (!in_command) { + _editor->begin_reversible_command (_("change fade out length")); + in_command = false; + } XMLNode &after = alist->get_state(); _editor->session()->add_command(new MementoCommand(*alist.get(), &before, &after)); } - _editor->commit_reversible_command (); + if (in_command) { + _editor->commit_reversible_command (); + } } void @@ -3952,8 +3964,8 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred) _editor->_dragging_edit_point = false; - _editor->begin_reversible_command ( _("move marker") ); XMLNode &before = _editor->session()->locations()->get_state(); + bool in_command = false; MarkerSelection::iterator i; CopiedLocationInfo::iterator x; @@ -3968,9 +3980,12 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred) if (location) { if (location->locked()) { - return; + continue; + } + if (!in_command) { + _editor->begin_reversible_command ( _("move marker") ); + in_command = true; } - if (location->is_mark()) { location->set_start (((*x).location)->start()); } else { @@ -3979,9 +3994,11 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred) } } - XMLNode &after = _editor->session()->locations()->get_state(); - _editor->session()->add_command(new MementoCommand(*(_editor->session()->locations()), &before, &after)); - _editor->commit_reversible_command (); + if (in_command) { + XMLNode &after = _editor->session()->locations()->get_state(); + _editor->session()->add_command(new MementoCommand(*(_editor->session()->locations()), &before, &after)); + _editor->commit_reversible_command (); + } } void @@ -4044,7 +4061,7 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) setup_snap_delta (pos); float const fraction = 1 - (_point->get_y() / _point->line().height()); - + _editor->begin_reversible_command (_("automation event move")); _point->line().start_drag_single (_point, _fixed_grab_x, fraction); show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction)); @@ -4190,7 +4207,7 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) _fixed_grab_y = cy; double fraction = 1.0 - (cy / _line->height()); - + _editor->begin_reversible_command (_("automation range move")); _line->start_drag_line (before, after, fraction); show_verbose_cursor_text (_line->get_verbose_cursor_string (fraction)); @@ -5583,7 +5600,7 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) if (_nothing_to_drag) { return; } - + _editor->begin_reversible_command (_("automation range move")); for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state); } diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc index be475216c1..e412b82c32 100644 --- a/gtk2_ardour/midi_time_axis.cc +++ b/gtk2_ardour/midi_time_axis.cc @@ -1509,8 +1509,9 @@ boost::shared_ptr MidiTimeAxisView::add_region (framepos_t pos, framecnt_t length, bool commit) { Editor* real_editor = dynamic_cast (&_editor); - - real_editor->begin_reversible_command (Operations::create_region); + if (commit) { + real_editor->begin_reversible_command (Operations::create_region); + } playlist()->clear_changes (); real_editor->snap_to (pos, RoundNearest); diff --git a/gtk2_ardour/region_editor.cc b/gtk2_ardour/region_editor.cc index 16888fb688..e41e012ce6 100644 --- a/gtk2_ardour/region_editor.cc +++ b/gtk2_ardour/region_editor.cc @@ -270,33 +270,41 @@ RegionEditor::connect_editor_events () void RegionEditor::position_clock_changed () { - PublicEditor::instance().begin_reversible_command (_("change region start position")); - + bool in_command = false; boost::shared_ptr pl = _region->playlist(); if (pl) { + PublicEditor::instance().begin_reversible_command (_("change region start position")); + in_command = true; + _region->clear_changes (); _region->set_position (position_clock.current_time()); _session->add_command(new StatefulDiffCommand (_region)); } - PublicEditor::instance().commit_reversible_command (); + if (in_command) { + PublicEditor::instance().commit_reversible_command (); + } } void RegionEditor::end_clock_changed () { - PublicEditor::instance().begin_reversible_command (_("change region end position")); - + bool in_command = false; boost::shared_ptr pl = _region->playlist(); if (pl) { + PublicEditor::instance().begin_reversible_command (_("change region end position")); + in_command = true; + _region->clear_changes (); _region->trim_end (end_clock.current_time()); _session->add_command(new StatefulDiffCommand (_region)); } - PublicEditor::instance().commit_reversible_command (); + if (in_command) { + PublicEditor::instance().commit_reversible_command (); + } end_clock.set (_region->position() + _region->length() - 1, true); } @@ -305,18 +313,21 @@ void RegionEditor::length_clock_changed () { framecnt_t frames = length_clock.current_time(); - - PublicEditor::instance().begin_reversible_command (_("change region length")); - + bool in_command = false; boost::shared_ptr pl = _region->playlist(); if (pl) { - _region->clear_changes (); + PublicEditor::instance().begin_reversible_command (_("change region length")); + in_command = true; + + _region->clear_changes (); _region->trim_end (_region->position() + frames - 1); _session->add_command(new StatefulDiffCommand (_region)); } - PublicEditor::instance().commit_reversible_command (); + if (in_command) { + PublicEditor::instance().commit_reversible_command (); + } length_clock.set (_region->length()); } From 80090f0f71256d65c876f83d3c6f3637cb9d44bb Mon Sep 17 00:00:00 2001 From: nick_m Date: Wed, 17 Jun 2015 22:19:21 +1000 Subject: [PATCH 08/19] Fix thinko in automation write undo. - also allow saved automation list state to be touch or off if actually in write mode. --- libs/ardour/automation_control.cc | 6 ++---- libs/ardour/automation_list.cc | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index f2361c2b30..bfb1046849 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -88,6 +88,8 @@ AutomationControl::set_automation_state (AutoState as) } if (as == Write) { + /* get state for undo */ + _before = &alist ()->get_state (); AutomationWatch::instance().add_automation_watch (shared_from_this()); } else if (as == Touch) { if (!touching()) { @@ -122,10 +124,6 @@ AutomationControl::start_touch(double when) if (!touching()) { - if (alist()->automation_state() == Write) { - _before = &alist ()->get_state (); - } - if (alist()->automation_state() == Touch) { /* subtle. aligns the user value with the playback */ set_value (get_value ()); diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc index 7f7599f8ca..706a3330a7 100644 --- a/libs/ardour/automation_list.cc +++ b/libs/ardour/automation_list.cc @@ -276,7 +276,11 @@ AutomationList::state (bool full) if (_state != Write) { root->add_property ("state", auto_state_to_string (_state)); } else { - root->add_property ("state", auto_state_to_string (Off)); + if (_events.empty ()) { + root->add_property ("state", auto_state_to_string (Off)); + } else { + root->add_property ("state", auto_state_to_string (Touch)); + } } } else { /* never save anything but Off for automation state to a template */ From 639750f815a856bd9a61355e0d8e331e0fe215b6 Mon Sep 17 00:00:00 2001 From: nick_m Date: Thu, 18 Jun 2015 03:48:39 +1000 Subject: [PATCH 09/19] Don't add history by clicking a control point, fix control point selection. - also make set_selected_control_point_from_click () return something useful. --- gtk2_ardour/editor_drag.cc | 16 +++++++++++----- gtk2_ardour/editor_drag.h | 1 + gtk2_ardour/editor_mouse.cc | 3 ++- gtk2_ardour/editor_selection.cc | 8 +++++++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index ab08f7f10b..9f52dea5b6 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4035,6 +4035,7 @@ ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i), _cumulative_x_drag (0), _cumulative_y_drag (0) + , _first_move (true) { if (_zero_gain_fraction < 0.0) { _zero_gain_fraction = gain_to_slider_position_with_max (dB_to_coefficient (0.0), Config->get_max_gain()); @@ -4061,9 +4062,6 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) setup_snap_delta (pos); float const fraction = 1 - (_point->get_y() / _point->line().height()); - _editor->begin_reversible_command (_("automation event move")); - _point->line().start_drag_single (_point, _fixed_grab_x, fraction); - show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction)); _pushing = Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::push_points_modifier ()); @@ -4123,6 +4121,12 @@ ControlPointDrag::motion (GdkEvent* event, bool) float const fraction = 1.0 - (cy / _point->line().height()); + if (_first_move) { + _editor->begin_reversible_command (_("automation event move")); + _point->line().start_drag_single (_point, _fixed_grab_x, fraction); + _first_move = false; + } + _point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_frames), fraction, false, _pushing, _final_index); show_verbose_cursor_text (_point->line().get_verbose_cursor_string (fraction)); @@ -4142,8 +4146,10 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred) motion (event, false); } - _point->line().end_drag (_pushing, _final_index); - _editor->commit_reversible_command (); + if (!_first_move) { + _point->line().end_drag (_pushing, _final_index); + _editor->commit_reversible_command (); + } } void diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 6fcd92751a..40525de80b 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -834,6 +834,7 @@ private: double _fixed_grab_y; double _cumulative_x_drag; double _cumulative_y_drag; + bool _first_move; bool _pushing; uint32_t _final_index; static double _zero_gain_fraction; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 8c5e6711f9..07931a5479 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -512,7 +512,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp break; case ControlPointItem: - set_selected_track_as_side_effect (op); + /* for object/track exclusivity, we don't call set_selected_track_as_side_effect (op); */ + if (eff_mouse_mode != MouseRange) { _mouse_changed_selection |= set_selected_control_point_from_click (press, op); } diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index b071ed6e1b..a04ea77f06 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -325,19 +325,23 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation if (!clicked_control_point) { return false; } + bool ret = false; switch (op) { case Selection::Set: if (press) { selection->set (clicked_control_point); + ret = true; } break; case Selection::Add: if (press) { selection->add (clicked_control_point); + ret = true; } break; case Selection::Toggle: + /* This is a bit of a hack; if we Primary-Click-Drag a control point (for push drag) we want the point we clicked on to be selected, otherwise we end up confusingly dragging an @@ -352,9 +356,11 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation */ selection->toggle (clicked_control_point); _control_point_toggled_on_press = true; + ret = true; } else if (!press && !_control_point_toggled_on_press) { /* This is the release, and the point wasn't toggled on the press, so do it now */ selection->toggle (clicked_control_point); + ret = true; } else { /* Reset our flag */ _control_point_toggled_on_press = false; @@ -365,7 +371,7 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation break; } - return true; + return ret; } void From 0280989276acefe43e1fc0f5617703afc72c0d62 Mon Sep 17 00:00:00 2001 From: nick_m Date: Thu, 18 Jun 2015 04:42:30 +1000 Subject: [PATCH 10/19] Single control points can now be dragged up and down properly. - preserves the zero notch, but doesn't mess up the cumulative drag. --- gtk2_ardour/editor_drag.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 9f52dea5b6..056deea3f5 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4091,11 +4091,6 @@ ControlPointDrag::motion (GdkEvent* event, bool) // positive side of zero double const zero_gain_y = (1.0 - _zero_gain_fraction) * _point->line().height() - .01; - // make sure we hit zero when passing through - if ((cy < zero_gain_y && (cy - dy) > zero_gain_y) || (cy > zero_gain_y && (cy - dy) < zero_gain_y)) { - cy = zero_gain_y; - } - if (_x_constrained) { cx = _fixed_grab_x; } @@ -4106,6 +4101,11 @@ ControlPointDrag::motion (GdkEvent* event, bool) _cumulative_x_drag = cx - _fixed_grab_x; _cumulative_y_drag = cy - _fixed_grab_y; + // make sure we hit zero when passing through + if ((cy < zero_gain_y && (cy - dy) > zero_gain_y) || (cy > zero_gain_y && (cy - dy) < zero_gain_y)) { + cy = zero_gain_y; + } + cx = max (0.0, cx); cy = max (0.0, cy); cy = min ((double) _point->line().height(), cy); From 16109ebcc86ecb891986b745ee79f47fbaa570f9 Mon Sep 17 00:00:00 2001 From: nick_m Date: Thu, 18 Jun 2015 06:27:37 +1000 Subject: [PATCH 11/19] Rework last commit, clicking on an automation line no longer adds history. - fixes a crash when clicking on automation lines repeatedly. --- gtk2_ardour/editor_drag.cc | 28 ++++++++++++---------------- gtk2_ardour/editor_drag.h | 3 ++- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 056deea3f5..8bd90ac976 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4035,7 +4035,6 @@ ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i), _cumulative_x_drag (0), _cumulative_y_drag (0) - , _first_move (true) { if (_zero_gain_fraction < 0.0) { _zero_gain_fraction = gain_to_slider_position_with_max (dB_to_coefficient (0.0), Config->get_max_gain()); @@ -4072,7 +4071,7 @@ ControlPointDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) } void -ControlPointDrag::motion (GdkEvent* event, bool) +ControlPointDrag::motion (GdkEvent* event, bool first_motion) { double dx = _drags->current_pointer_x() - last_pointer_x(); double dy = current_pointer_y() - last_pointer_y(); @@ -4121,10 +4120,9 @@ ControlPointDrag::motion (GdkEvent* event, bool) float const fraction = 1.0 - (cy / _point->line().height()); - if (_first_move) { + if (first_motion) { _editor->begin_reversible_command (_("automation event move")); _point->line().start_drag_single (_point, _fixed_grab_x, fraction); - _first_move = false; } _point->line().drag_motion (_editor->sample_to_pixel_unrounded (cx_frames), fraction, false, _pushing, _final_index); @@ -4144,9 +4142,6 @@ ControlPointDrag::finished (GdkEvent* event, bool movement_occurred) } else { motion (event, false); - } - - if (!_first_move) { _point->line().end_drag (_pushing, _final_index); _editor->commit_reversible_command (); } @@ -4174,6 +4169,8 @@ LineDrag::LineDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i) , _line (0) , _cumulative_y_drag (0) + , _before (0) + , _after (0) { DEBUG_TRACE (DEBUG::Drags, "New LineDrag\n"); } @@ -4197,10 +4194,7 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) framecnt_t const frame_within_region = (framecnt_t) floor (cx * _editor->samples_per_pixel); - uint32_t before; - uint32_t after; - - if (!_line->control_points_adjacent (frame_within_region, before, after)) { + if (!_line->control_points_adjacent (frame_within_region, _before, _after)) { /* no adjacent points */ return; } @@ -4213,14 +4207,12 @@ LineDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*cursor*/) _fixed_grab_y = cy; double fraction = 1.0 - (cy / _line->height()); - _editor->begin_reversible_command (_("automation range move")); - _line->start_drag_line (before, after, fraction); show_verbose_cursor_text (_line->get_verbose_cursor_string (fraction)); } void -LineDrag::motion (GdkEvent* event, bool) +LineDrag::motion (GdkEvent* event, bool first_move) { double dy = current_pointer_y() - last_pointer_y(); @@ -4238,6 +4230,11 @@ LineDrag::motion (GdkEvent* event, bool) double const fraction = 1.0 - (cy / _line->height()); uint32_t ignored; + if (first_move) { + _editor->begin_reversible_command (_("automation range move")); + _line->start_drag_line (_before, _after, fraction); + } + /* we are ignoring x position for this drag, so we can just pass in anything */ _line->drag_motion (0, fraction, true, false, ignored); @@ -4250,6 +4247,7 @@ LineDrag::finished (GdkEvent* event, bool movement_occured) if (movement_occured) { motion (event, false); _line->end_drag (false, 0); + _editor->commit_reversible_command (); } else { /* add a new control point on the line */ @@ -4262,8 +4260,6 @@ LineDrag::finished (GdkEvent* event, bool movement_occured) atv->add_automation_event (event, where, event->button.y, false); } } - - _editor->commit_reversible_command (); } void diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 40525de80b..ec0fed1312 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -834,7 +834,6 @@ private: double _fixed_grab_y; double _cumulative_x_drag; double _cumulative_y_drag; - bool _first_move; bool _pushing; uint32_t _final_index; static double _zero_gain_fraction; @@ -857,6 +856,8 @@ private: double _fixed_grab_x; double _fixed_grab_y; double _cumulative_y_drag; + uint32_t _before; + uint32_t _after; }; /** Transient feature line drags*/ From 6ecbeed8e82f594bf354d4f3974f601829b55002 Mon Sep 17 00:00:00 2001 From: nick_m Date: Thu, 18 Jun 2015 10:03:18 +1000 Subject: [PATCH 12/19] Fix ControlList::editor_add () wrt guard points. --- libs/evoral/src/ControlList.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index d592be3491..5118744c05 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -469,13 +469,18 @@ ControlList::editor_add (double when, double value, bool with_guard) } } + insert_position = when; + if (with_guard) { + if (when > 64) { + add_guard_point (when - 64); + } + maybe_add_insert_guard (when); + } + 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= %2\n", when, value)); _events.insert (i, new ControlEvent (when, value)); - if (with_guard) { - add_guard_point (when); - } mark_dirty (); From dcd3e3823c608a8c9aae352b9f03b222ba449f19 Mon Sep 17 00:00:00 2001 From: nick_m Date: Fri, 19 Jun 2015 00:02:09 +1000 Subject: [PATCH 13/19] Don't begin command on start_grab for AutomationRangeDrag and NoteResizeDrag - fixes a crash when clicking to resize without movement. - minor readability fix for _drag_had_movement --- gtk2_ardour/automation_line.cc | 2 +- gtk2_ardour/editor_drag.cc | 60 ++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index a354afeeb6..e3acc56b3b 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -675,6 +675,7 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool for (vector::iterator ccp = contiguous_points.begin(); ccp != contiguous_points.end(); ++ccp) { (*ccp)->compute_x_bounds (trackview.editor()); } + _drag_had_movement = true; } /* OK, now on to the stuff related to *this* motion event. First, for @@ -735,7 +736,6 @@ AutomationLine::drag_motion (double const x, float fraction, bool ignore_x, bool _drag_distance += dx; _drag_x += dx; _last_drag_fraction = fraction; - _drag_had_movement = true; did_push = with_push; return pair (_drag_x + dx, _last_drag_fraction + dy); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 8bd90ac976..1a5803d49b 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -2334,6 +2334,8 @@ RegionCreateDrag::aborted (bool) NoteResizeDrag::NoteResizeDrag (Editor* e, ArdourCanvas::Item* i) : Drag (e, i) , region (0) + , relative (false) + , at_front (true) , _snap_delta (0) { DEBUG_TRACE (DEBUG::Drags, "New NoteResizeDrag\n"); @@ -2370,37 +2372,36 @@ NoteResizeDrag::start_grab (GdkEvent* event, Gdk::Cursor* /*ignored*/) } else { relative = true; } - MidiRegionSelection& ms (_editor->get_selection().midi_regions); - if (ms.size() > 1) { /* has to be relative, may make no sense otherwise */ relative = true; } - /* select this note; if it is already selected, preserve the existing selection, otherwise make this note the only one selected. */ region->note_selected (cnote, cnote->selected ()); - - _editor->begin_reversible_command (_("resize notes")); - - for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) { - MidiRegionSelection::iterator next; - next = r; - ++next; - MidiRegionView* mrv = dynamic_cast(*r); - if (mrv) { - mrv->begin_resizing (at_front); - } - r = next; - } } void -NoteResizeDrag::motion (GdkEvent* event, bool /*first_move*/) +NoteResizeDrag::motion (GdkEvent* event, bool first_move) { MidiRegionSelection& ms (_editor->get_selection().midi_regions); + if (first_move) { + _editor->begin_reversible_command (_("resize notes")); + + for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ) { + MidiRegionSelection::iterator next; + next = r; + ++next; + MidiRegionView* mrv = dynamic_cast(*r); + if (mrv) { + mrv->begin_resizing (at_front); + } + r = next; + } + } + for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) { NoteBase* nb = reinterpret_cast (_item->get_data ("notebase")); assert (nb); @@ -2434,8 +2435,12 @@ NoteResizeDrag::motion (GdkEvent* event, bool /*first_move*/) } void -NoteResizeDrag::finished (GdkEvent* event, bool /*movement_occurred*/) +NoteResizeDrag::finished (GdkEvent* event, bool movement_occurred) { + if (!movement_occurred) { + return; + } + MidiRegionSelection& ms (_editor->get_selection().midi_regions); for (MidiRegionSelection::iterator r = ms.begin(); r != ms.end(); ++r) { NoteBase* nb = reinterpret_cast (_item->get_data ("notebase")); @@ -2458,9 +2463,11 @@ NoteResizeDrag::finished (GdkEvent* event, bool /*movement_occurred*/) } } } + if (apply_snap_delta) { sd = _snap_delta; } + mrv->commit_resizing (nb, at_front, _drags->current_pointer_x() - grab_x(), relative, sd, snap); } } @@ -5602,19 +5609,22 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) if (_nothing_to_drag) { return; } - _editor->begin_reversible_command (_("automation range move")); - for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { - i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state); - } } void -AutomationRangeDrag::motion (GdkEvent*, bool /*first_move*/) +AutomationRangeDrag::motion (GdkEvent*, bool first_move) { if (_nothing_to_drag) { return; } + if (first_move) { + _editor->begin_reversible_command (_("automation range move")); + for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { + i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state); + } + } + for (list::iterator l = _lines.begin(); l != _lines.end(); ++l) { float const f = y_fraction (l->line, current_pointer_y()); /* we are ignoring x position for this drag, so we can just pass in anything */ @@ -5625,9 +5635,9 @@ AutomationRangeDrag::motion (GdkEvent*, bool /*first_move*/) } void -AutomationRangeDrag::finished (GdkEvent* event, bool) +AutomationRangeDrag::finished (GdkEvent* event, bool motion_occurred) { - if (_nothing_to_drag) { + if (_nothing_to_drag || !motion_occurred) { return; } From 1768e9817e9da630c0fc5110a121e969ea47c639 Mon Sep 17 00:00:00 2001 From: nick_m Date: Fri, 19 Jun 2015 03:39:51 +1000 Subject: [PATCH 14/19] Fix another LineDrag click crash. --- gtk2_ardour/editor_drag.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 1a5803d49b..305e72e2aa 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4260,8 +4260,6 @@ LineDrag::finished (GdkEvent* event, bool movement_occured) AutomationTimeAxisView* atv; - _line->end_drag (false, 0); - if ((atv = dynamic_cast(_editor->clicked_axisview)) != 0) { framepos_t where = _editor->window_event_sample (event, 0, 0); atv->add_automation_event (event, where, event->button.y, false); From aa1cdd26ca2d741707f6df6bc3b477575ef67c25 Mon Sep 17 00:00:00 2001 From: nick_m Date: Fri, 19 Jun 2015 05:02:06 +1000 Subject: [PATCH 15/19] AudioRegionView now uses ControlList::editor_add(). --- gtk2_ardour/audio_region_view.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 2ea91ff62f..eae66dbdc5 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -1251,7 +1251,7 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b trackview.session()->add_command (new MementoCommand(*(audio_region().get()), ®ion_before, ®ion_after)); } - audio_region()->envelope()->add (fx, y, with_guard_points); + audio_region()->envelope()->editor_add (fx, y, with_guard_points); XMLNode &after = audio_region()->envelope()->get_state(); trackview.session()->add_command (new MementoCommand(*audio_region()->envelope().get(), &before, &after)); From 63269b306325a2beb1a7112a842cfb8b425f8da3 Mon Sep 17 00:00:00 2001 From: nick_m Date: Sun, 21 Jun 2015 05:27:45 +1000 Subject: [PATCH 16/19] Automation selection fixes. - display selected comtrol points in region gain lines - display selected points in internal edit mode - allow dragging of region gain lines in MouseContent mode --- gtk2_ardour/audio_streamview.cc | 12 ++++++++++++ gtk2_ardour/audio_streamview.h | 2 ++ gtk2_ardour/automation_line.cc | 3 ++- gtk2_ardour/editor_mouse.cc | 8 +++++++- gtk2_ardour/route_time_axis.cc | 5 +++++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index 7951848c59..ed7bfc238d 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -41,6 +41,7 @@ #include "tape_region_view.h" #include "audio_time_axis.h" #include "region_selection.h" +#include "region_gain_line.h" #include "selection.h" #include "public_editor.h" #include "ardour_ui.h" @@ -471,3 +472,14 @@ AudioStreamView::color_handler () } } } + +void +AudioStreamView::set_selected_points (PointSelection& points) +{ + for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) { + AudioRegionView* const arv = dynamic_cast(*i); + if (arv && arv->get_gain_line ()) { + arv->get_gain_line ()->set_selected_points (points); + } + } +} diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h index 8e9b095537..443a39063b 100644 --- a/gtk2_ardour/audio_streamview.h +++ b/gtk2_ardour/audio_streamview.h @@ -26,6 +26,7 @@ #include #include "ardour/location.h" +#include "point_selection.h" #include "editing.h" #include "streamview.h" @@ -61,6 +62,7 @@ class AudioStreamView : public StreamView std::pair, std::list > hide_xfades_with (boost::shared_ptr ar); RegionView* create_region_view (boost::shared_ptr, bool, bool); + void set_selected_points (PointSelection&); private: void setup_rec_box (); diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index e3acc56b3b..d0dc933759 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -948,7 +948,8 @@ AutomationLine::set_selected_points (PointSelection const & points) set_colors (); } -void AutomationLine::set_colors () +void +AutomationLine::set_colors () { set_line_color (ARDOUR_UI::config()->color ("automation line")); for (vector::iterator i = control_points.begin(); i != control_points.end(); ++i) { diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 07931a5479..26e8dd2872 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -446,7 +446,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp if (((mouse_mode != MouseObject) && (mouse_mode != MouseAudition || item_type != RegionItem) && (mouse_mode != MouseTimeFX || item_type != RegionItem) && - (mouse_mode != MouseDraw)) || + (mouse_mode != MouseDraw) && + (mouse_mode != MouseContent || item_type == RegionItem)) || ((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3)) { return; } @@ -762,6 +763,11 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } return true; + case GainLineItem: + _drags->set (new LineDrag (this, item), event); + return true; + break; + case ControlPointItem: _drags->set (new ControlPointDrag (this, item), event); return true; diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 7f112b9546..94ed2a86f0 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -59,6 +59,7 @@ #include "ardour_ui.h" #include "ardour_button.h" +#include "audio_streamview.h" #include "debug.h" #include "global_signals.h" #include "route_time_axis.h" @@ -1342,6 +1343,10 @@ RouteTimeAxisView::set_selected_points (PointSelection& points) for (Children::iterator i = children.begin(); i != children.end(); ++i) { (*i)->set_selected_points (points); } + AudioStreamView* asv = dynamic_cast(_view); + if (asv) { + asv->set_selected_points (points); + } } void From e0a076d2b674d608fc3afa49343af8274da6dd4d Mon Sep 17 00:00:00 2001 From: nick_m Date: Sun, 21 Jun 2015 22:14:03 +1000 Subject: [PATCH 17/19] Mkae automation line / gain line cursors consistent. --- gtk2_ardour/editor_canvas.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 66417923be..46167bb2f4 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -1223,7 +1223,7 @@ Editor::which_canvas_cursor(ItemType type) const cursor = _cursors->fader; break; case GainLineItem: - cursor = which_track_cursor (); + cursor = _cursors->cross_hair; break; case AutomationLineItem: cursor = _cursors->cross_hair; From d45a25e4a834e7f25217f811dedba005226385c8 Mon Sep 17 00:00:00 2001 From: nick_m Date: Mon, 22 Jun 2015 00:47:08 +1000 Subject: [PATCH 18/19] Clicking an automation track line without a move adds a point on the line. --- gtk2_ardour/editor_canvas_events.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 8af5389e70..9e9564594a 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -694,7 +694,7 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation } else { type = AutomationLineItem; } - + clicked_axisview = &al->trackview; return typed_event (item, event, type); } From d9c0aa4236796d981a5d939bbc5d0d5a2e1910fe Mon Sep 17 00:00:00 2001 From: nick_m Date: Mon, 22 Jun 2015 00:53:31 +1000 Subject: [PATCH 19/19] Amend last commit. --- gtk2_ardour/editor_canvas_events.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 9e9564594a..92ebbd976d 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -694,7 +694,12 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation } else { type = AutomationLineItem; } + + clicked_control_point = 0; clicked_axisview = &al->trackview; + clicked_routeview = dynamic_cast(clicked_axisview); + clicked_regionview = 0; + return typed_event (item, event, type); }