- {
- if (dynamic_cast<AudioRegionView*>(clicked_regionview) ||
- dynamic_cast<AutomationRegionView*>(clicked_regionview)) {
- _drags->set (new AutomationRangeDrag (this, clicked_regionview, 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);
+ {
+ 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(),
+ clicked_regionview->get_time_axis_view().current_height()),
+ event, _cursors->up_down);
+ return true;
+ }
+
+ /* 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);
+ // TODO: handle layer_display() == Stacked
+ _drags->set (new AutomationRangeDrag (this, rvl, selection->time,
+ clicked_regionview->get_time_axis_view().y_position(),
+ clicked_regionview->get_time_axis_view().current_height()),
+ 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) {
+ RouteTimeAxisView* tatv;
+ boost::shared_ptr<Playlist> playlist;
+ if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) == 0) {
+ continue;
+ }
+ 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) {
+ RegionView* rv;
+ if ((rv = tatv->view()->find_view (*ir)) != 0) {
+ rvl.push_back (rv);
+ }
+ }
+ }
+ }
+ /* region-gain drag */
+ if (!rvl.empty ()) {
+ double y_pos = tvp.first->y_position();
+ double height = tvp.first->current_height();
+ StreamView* cv = tvp.first->view ();
+ if (cv->layer_display() == Stacked && cv->layers() > 1) {
+ height /= cv->layers();
+ double yy = event->button.y - _trackview_group->canvas_origin().y;
+ y_pos += floor ((yy - y_pos) / height) * height;