cont'd AutomationRangeDrag updates -- safety commit

This is work in progress towards fixing stacked region's region-gain
and multiple discontinuous regions spanning multiple tracks.

AutomationRangeDrag::setup() still does not collect all AutomationLine
points for certain overlap scenarios. There's more to come...
This commit is contained in:
Robin Gareus 2019-03-29 15:57:07 +01:00
parent 932892f794
commit d8571e2572
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 49 additions and 32 deletions

View File

@ -6223,10 +6223,10 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView
}
/** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list<RegionView*> const & v, list<AudioRange> const & r)
: Drag (editor, rv->get_canvas_group ())
AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list<RegionView*> const & v, list<AudioRange> const & r, double y_origin)
: Drag (editor, v.front()->get_canvas_group ())
, _ranges (r)
, _y_origin (rv->get_time_axis_view().y_position())
, _y_origin (y_origin)
, _nothing_to_drag (false)
, _integral (false)
{
@ -6234,11 +6234,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list<R
list<boost::shared_ptr<AutomationLine> > lines;
bool found_primary = false;
for (list<RegionView*>::const_iterator i = v.begin(); i != v.end(); ++i) {
if (*i == rv) {
found_primary = true;
}
if (AudioRegionView* audio_view = dynamic_cast<AudioRegionView*>(*i)) {
lines.push_back (audio_view->get_gain_line ());
} else if (AutomationRegionView* automation_view = dynamic_cast<AutomationRegionView*>(*i)) {
@ -6248,7 +6244,6 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list<R
error << _("Automation range drag created for invalid region type") << endmsg;
}
}
assert (found_primary);
setup (lines);
}

View File

@ -1244,7 +1244,7 @@ class AutomationRangeDrag : public Drag
{
public:
AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list<ARDOUR::AudioRange> const &);
AutomationRangeDrag (Editor *, RegionView *, std::list<RegionView*> const &, std::list<ARDOUR::AudioRange> const &);
AutomationRangeDrag (Editor *, std::list<RegionView*> const &, std::list<ARDOUR::AudioRange> const &, double y_origin);
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
void motion (GdkEvent *, bool);

View File

@ -37,6 +37,7 @@
#include "canvas/canvas.h"
#include "ardour/audioplaylist.h"
#include "ardour/audioregion.h"
#include "ardour/operations.h"
#include "ardour/playlist.h"
@ -1116,15 +1117,43 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
break;
case SelectionItem:
{
if (dynamic_cast<AudioRegionView*>(clicked_regionview) ||
dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
{
if (selection->time.empty ()) {
/* nothing to do */
return true;
}
pair<TimeAxisView*, int> tvp = trackview_by_y_position (event->button.y, false);
if (!tvp.first) {
/* clicked outside of a track */
return true;
}
/* handle automation lanes first */
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if (atv) {
/* smart "join" mode: drag automation */
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
return true;
}
if (dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
/* MIDI CC or similar -- TODO handle multiple? */
list<RegionView*> rvl;
rvl.push_back (clicked_regionview);
_drags->set (new AutomationRangeDrag (this, rvl, selection->time, clicked_regionview->get_time_axis_view().y_position()), event, _cursors->up_down);
return true;
}
/* collect all regions-views in the given range selection
* perhaps this should be a dedicated method:
* Editor::get_region_views_from_range_selection() ?
* except <RegionView*> c-pointer list is not very reliable.
*/
/* no shift+drag: only apply to clicked_regionview (if any) */
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) {
if (dynamic_cast<AudioRegionView*>(clicked_regionview) == 0) {
return true;
}
list<RegionView*> rvl;
rvl.push_back (clicked_regionview);
_drags->set (new AutomationRangeDrag (this, rvl, selection->time, clicked_regionview->get_time_axis_view().y_position()), event, _cursors->up_down);
return true;
}
/* collect all audio regions-views in the given range selection */
list<RegionView*> rvl;
TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
@ -1136,6 +1165,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
if (boost::dynamic_pointer_cast<AudioPlaylist> (playlist) == 0) {
continue;
}
for (list<AudioRange>::const_iterator j = selection->time.begin(); j != selection->time.end(); ++j) {
boost::shared_ptr<RegionList> rl = playlist->regions_touched (j->start, j->end);
for (RegionList::iterator ir = rl->begin(); ir != rl->end(); ++ir) {
@ -1146,23 +1178,13 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
}
}
}
_drags->set (new AutomationRangeDrag (this, clicked_regionview, rvl, selection->time),
event, _cursors->up_down);
} else {
double const y = event->button.y;
pair<TimeAxisView*, int> tvp = trackview_by_y_position (y, false);
if (tvp.first) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (tvp.first);
if (atv) {
/* smart "join" mode: drag automation */
_drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down);
}
/* region-gain drag */
if (!rvl.empty ()) {
_drags->set (new AutomationRangeDrag (this, rvl, selection->time, tvp.first->y_position()), event, _cursors->up_down);
}
return true;
break;
}
return true;
break;
}
case AutomationLineItem:
_drags->set (new LineDrag (this, item), event);