partial fix for Canvas Region DnD & comments

Fixes #6172 and #6176 for single region drags.

Further work is needed if multiple regions on different tracks are dragged over hidden tracks
(see inline comment).
This commit is contained in:
Robin Gareus 2015-03-24 15:21:33 +01:00
parent eff25b06f5
commit 92ba2d5780
1 changed files with 68 additions and 8 deletions

View File

@ -541,7 +541,7 @@ RegionDrag::find_time_axis_view (TimeAxisView* t) const
++i;
}
if (i == N) {
if (_time_axis_views[i] != t) {
return -1;
}
@ -573,6 +573,7 @@ RegionMotionDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
pair<TimeAxisView*, double> const tv = _editor->trackview_by_y_position (current_pointer_y ());
if (tv.first) {
_last_pointer_time_axis_view = find_time_axis_view (tv.first);
assert(_last_pointer_time_axis_view >= 0);
_last_pointer_layer = tv.first->layer_display() == Overlaid ? 0 : tv.second;
}
}
@ -650,6 +651,35 @@ RegionMotionDrag::y_movement_allowed (int delta_track, double delta_layer) const
for (list<DraggingView>::const_iterator i = _views.begin(); i != _views.end(); ++i) {
int n = i->time_axis_view + delta_track;
/* TODO: for i > 0, account for hidden tracks
*
* example. top-to-bottom:
* 2 Audio Tracks [one region each] 1 Bus 1 Audio Track.
* Hide the Bus. (looks like 3 audio tracks)
*
* select both region, grab the upper and move down 1 track
* -> delta_track = 1;
*
* real_delta_track=1 (for region on track1)
* real_delta_track=2 (for region on track2, skip the hidden bus)
* -> fail
*
* assuming it worked..
* Audio Track Audio Track[with region] hidden-Bus Audio Track[with region]
*
* selected both regions, grab the lower region and
* move up one track -> given delta == -2 (skip the bus)
*
* real_delta_track=-1
* real_delta_track=-2
*
* It gets worse if both regions have to ignore differen numbers of hidden tracks
* in between.
*
*
* Proposed solution: if i == 0, count number of hidden tracks crossed
* subtract that number for i > 0 AND also subtract hidden tracks crossed
*/
if (i->time_axis_view < 0) {
/* already in the drop zone */
if (delta_track >= 0) {
@ -676,7 +706,7 @@ RegionMotionDrag::y_movement_allowed (int delta_track, double delta_layer) const
}
RouteTimeAxisView const * to = dynamic_cast<RouteTimeAxisView const *> (_time_axis_views[n]);
if (to == 0 || !to->is_track() || to->track()->data_type() != i->view->region()->data_type()) {
if (to == 0 || to->hidden() || !to->is_track() || to->track()->data_type() != i->view->region()->data_type()) {
/* not a track, or the wrong type */
return false;
}
@ -740,21 +770,48 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
/* Here's the current pointer position in terms of time axis view and layer */
current_pointer_time_axis_view = find_time_axis_view (tv);
assert(current_pointer_time_axis_view >= 0);
double const current_pointer_layer = tv->layer_display() == Overlaid ? 0 : layer;
/* Work out the change in y */
if (_last_pointer_time_axis_view < 0) {
/* We can only move up, set delta to move up the correct number of
tracks from the bottom. This is necessary because steps may be
skipped if the lowest track is not a valid target, so e.g. delta
-2 may be the first valid value. */
delta_time_axis_view = current_pointer_time_axis_view - _time_axis_views.size();
/* Was in the drop-zone, now over a track.
* Hence it must be an upward move (from the bottom)
*
* track_index is still -1, so delta must be set to
* move up the correct number of tracks from the bottom.
*
* This is necessary because steps may be skipped if
* the bottom-most track is not a valid target,
*/
delta_time_axis_view = current_pointer_time_axis_view - _time_axis_views.size ();
} else {
delta_time_axis_view = current_pointer_time_axis_view - _last_pointer_time_axis_view;
}
/* TODO needs adjustment per DraggingView,
*
* e.g. select one region on the top-layer of a track
* and one region which is at the bottom-layer of another track
* drag both.
*
* Indicated drop-zones and layering is wrong.
* and may infer additional layers on the target-track
* (depending how many layers the original track had).
*
* Or select two regions (different layers) on a same track,
* move across a non-layer track.. -> layering info is lost.
* on drop either of the regions may be on top.
*
* Proposed solution: screw it :) well,
* don't use delta_layer, use an absolute value
* 1) remember DraggingView's layer as float 0..1 [current layer / all layers of source]
* 2) calculate current mouse pos, y-pos inside track divided by height of mouse-over track.
* 3) iterate over all DraggingView, find the one that is over the track with most layers
* 4) proportionally scale layer to layers available on target
*/
delta_layer = current_pointer_layer - _last_pointer_layer;
}
@ -859,6 +916,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
}
if (track_index < 0 || track_index >= (int) _time_axis_views.size()) {
// Velociraptor was here
goto dropzone;
}
@ -992,6 +1050,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
if (delta_time_axis_view < 0) {
/* was in the drop zone, moving up */
assert(current_pointer_time_axis_view >= 0);
_last_pointer_time_axis_view = current_pointer_time_axis_view;
} else {
/* was in the drop zone, moving down ... not possible */
@ -1001,7 +1060,8 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
/* last motion event was also over a time axis view */
_last_pointer_time_axis_view = current_pointer_time_axis_view;
_last_pointer_time_axis_view += delta_time_axis_view;
assert(_last_pointer_time_axis_view >= 0);
}
} else {