X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_drag.cc;h=de1b66891f29ef5fd9a8af3998139167dbb7ba34;hb=11e907770a0a7bceea240de30517f2237e5fe128;hp=ee6332e065afe88f65b0b3c274c250ab9b114336;hpb=ed626628b54e67dd9621c08d82a42afaed00c7ac;p=ardour.git diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index ee6332e065..de1b66891f 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -29,10 +29,12 @@ #include "gtkmm2ext/utils.h" -#include "ardour/session.h" +#include "ardour/audioregion.h" #include "ardour/dB.h" -#include "ardour/region_factory.h" +#include "ardour/midi_region.h" #include "ardour/operations.h" +#include "ardour/region_factory.h" +#include "ardour/session.h" #include "editor.h" #include "i18n.h" @@ -66,14 +68,13 @@ using namespace ArdourCanvas; using Gtkmm2ext::Keyboard; -double const ControlPointDrag::_zero_gain_fraction = gain_to_slider_position (dB_to_coefficient (0.0)); +double ControlPointDrag::_zero_gain_fraction = -1.0; DragManager::DragManager (Editor* e) : _editor (e) , _ending (false) , _current_pointer_frame (0) { - } DragManager::~DragManager () @@ -410,20 +411,19 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, listvisible_order_range (&_visible_y_low, &_visible_y_high); - /* Make a list of non-hidden tracks to refer to during the drag */ + /* Make a list of tracks to refer to during the drag; we include hidden tracks, + as some of the regions we are dragging may be on such tracks. + */ TrackViewList track_views = _editor->track_views; track_views.sort (EditorOrderTimeAxisViewSorter ()); for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - if (!(*i)->hidden()) { - - _time_axis_views.push_back (*i); - - TimeAxisView::Children children_list = (*i)->get_child_list (); - for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { - _time_axis_views.push_back (j->get()); - } + _time_axis_views.push_back (*i); + + TimeAxisView::Children children_list = (*i)->get_child_list (); + for (TimeAxisView::Children::iterator j = children_list.begin(); j != children_list.end(); ++j) { + _time_axis_views.push_back (j->get()); } } @@ -450,7 +450,9 @@ RegionDrag::region_going_away (RegionView* v) } } -/** Given a non-hidden TimeAxisView, return the index of it into the _time_axis_views vector */ +/** Given a TimeAxisView, return the index of it into the _time_axis_views vector, + * or -1 if it is not found. + */ int RegionDrag::find_time_axis_view (TimeAxisView* t) const { @@ -634,49 +636,24 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) if (first_move) { - /* here we are calculating the y distance from the - top of the first track view to the top of the region - area of the track view that we're working on */ - - /* this x value is just a dummy value so that we have something - to pass to i2w () */ - - double ix1 = 0; - - /* distance from the top of this track view to the region area - of our track view is always 1 */ - - double iy1 = 1; - - /* convert to world coordinates, ie distance from the top of - the ruler section */ - - rv->get_canvas_frame()->i2w (ix1, iy1); - - /* compensate for the ruler section and the vertical scrollbar position */ - iy1 += _editor->get_trackview_group_vertical_offset (); - - // hide any dependent views - rv->get_time_axis_view().hide_dependent_views (*rv); - - /* - reparent to a non scrolling group so that we can keep the - region selection above all time axis views. - reparenting means we have to move the rv as the two - parent groups have different coordinates. + + /* Reparent to a non scrolling group so that we can keep the + region selection above all time axis views. + Reparenting means that we will have to move the region view + later, as the two parent groups have different coordinates. */ - - rv->get_canvas_group()->property_y() = iy1 - 1; + rv->get_canvas_group()->reparent (*(_editor->_region_motion_group)); - + rv->fake_set_opaque (true); + + if (!rv->get_time_axis_view().hidden()) { + /* the track that this region view is on is hidden, so hide the region too */ + rv->get_canvas_group()->hide (); + } } - /* Work out the change in y position of this region view */ - - double y_delta = 0; - /* If we have moved tracks, we'll fudge the layer delta so that the region gets moved back onto layer 0 on its new track; this avoids confusion when dragging regions from non-zero layers onto different @@ -687,33 +664,21 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) this_delta_layer = - i->layer; } - /* Move this region to layer 0 on its old track */ - StreamView* lv = _time_axis_views[i->time_axis_view]->view (); - if (lv->layer_display() == Stacked) { - y_delta -= (lv->layers() - i->layer - 1) * lv->child_height (); - } - - /* Now move it to its right layer on the current track */ - StreamView* cv = _time_axis_views[i->time_axis_view + delta_time_axis_view]->view (); - if (cv->layer_display() == Stacked) { - y_delta += (cv->layers() - (i->layer + this_delta_layer) - 1) * cv->child_height (); - } + /* The TimeAxisView that this region is now on */ + TimeAxisView* tv = _time_axis_views[i->time_axis_view + delta_time_axis_view]; + + /* Set height */ + rv->set_height (tv->view()->child_height ()); - /* Move tracks */ - if (delta_time_axis_view > 0) { - for (int j = 0; j < delta_time_axis_view; ++j) { - y_delta += _time_axis_views[i->time_axis_view + j]->current_height (); - } + /* Update show/hidden status as the region view may have come from a hidden track, + or have moved to one. + */ + if (tv->hidden ()) { + rv->get_canvas_group()->hide (); } else { - /* start by subtracting the height of the track above where we are now */ - for (int j = 1; j <= -delta_time_axis_view; ++j) { - y_delta -= _time_axis_views[i->time_axis_view - j]->current_height (); - } + rv->get_canvas_group()->show (); } - /* Set height */ - rv->set_height (_time_axis_views[i->time_axis_view + delta_time_axis_view]->view()->child_height ()); - /* Update the DraggingView */ i->time_axis_view += delta_time_axis_view; i->layer += this_delta_layer; @@ -721,7 +686,21 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move) if (_brushing) { _editor->mouse_brush_insert_region (rv, pending_region_position); } else { - rv->move (x_delta, y_delta); + double x = 0; + double y = 0; + + /* Get the y coordinate of the top of the track that this region is now on */ + tv->canvas_display()->i2w (x, y); + y += _editor->get_trackview_group_vertical_offset(); + + /* And adjust for the layer that it should be on */ + StreamView* cv = tv->view (); + if (cv->layer_display() == Stacked) { + y += (cv->layers() - i->layer - 1) * cv->child_height (); + } + + /* Now move the region view */ + rv->move (x_delta, y - rv->get_canvas_group()->property_y()); } } /* foreach region */ @@ -1310,11 +1289,6 @@ RegionSpliceDrag::motion (GdkEvent* event, bool) pair const tvp = _editor->trackview_by_y_position (_drags->current_pointer_y ()); RouteTimeAxisView* tv = dynamic_cast (tvp.first); - layer_t layer = tvp.second; - - if (tv && tv->layer_display() == Overlaid) { - layer = 0; - } /* The region motion is only processed if the pointer is over an audio track. @@ -2117,11 +2091,11 @@ CursorDrag::motion (GdkEvent* event, bool) /* zoom when we move the pointer up and down */ /* y range to operate over (pixels) */ - double const y_range = 256; + double const y_range = 512; /* we will multiply the grab zoom by a factor between scale_range and scale_range^-1 */ double const scale_range = 4; /* dead zone around the grab point in which to do no zooming (pixels) */ - double const dead_zone = 16; + double const dead_zone = 100; /* current dy */ double dy = _drags->current_pointer_y() - grab_y(); @@ -2742,7 +2716,7 @@ MarkerDrag::aborted (bool) } void -MarkerDrag::update_item (Location* location) +MarkerDrag::update_item (Location*) { /* noop */ } @@ -2752,6 +2726,10 @@ ControlPointDrag::ControlPointDrag (Editor* e, ArdourCanvas::Item* i) _cumulative_x_drag (0), _cumulative_y_drag (0) { + if (_zero_gain_fraction < 0.0) { + _zero_gain_fraction = gain_to_slider_position_with_max (dB_to_coefficient (0.0), Config->get_max_gain()); + } + DEBUG_TRACE (DEBUG::Drags, "New ControlPointDrag\n"); _point = reinterpret_cast (_item->get_data ("control_point")); @@ -3878,43 +3856,25 @@ NoteDrag::total_dx () const frameoffset_t const dx = _editor->unit_to_frame (_drags->current_pointer_x() - grab_x()); /* primary note time */ - frameoffset_t const n = _region->beats_to_frames (_primary->note()->time ()); + frameoffset_t const n = _region->source_beats_to_absolute_frames (_primary->note()->time ()); - /* new time of the primary note relative to the region position */ + /* new time of the primary note in session frames */ frameoffset_t st = n + dx; + framepos_t const rp = _region->region()->position (); + /* prevent the note being dragged earlier than the region's position */ - if (st < 0) { - st = 0; - } + st = max (st, rp); /* snap and return corresponding delta */ - return _region->snap_frame_to_frame (st) - n; + return _region->snap_frame_to_frame (st - rp) + rp - n; } -/** @return Current total drag y change in notes */ +/** @return Current total drag y change in note number */ int8_t NoteDrag::total_dy () const { - /* this is `backwards' to make increasing note number go in the right direction */ - double const dy = _drags->current_pointer_y() - grab_y(); - - /* dy in notes */ - int8_t ndy = 0; - - if (abs (dy) >= _note_height) { - if (dy > 0) { - ndy = (int8_t) ceil (dy / _note_height / 2.0); - } else { - ndy = (int8_t) floor (dy / _note_height / 2.0); - } - } - - /* more positive value = higher pitch and higher y-axis position on track, - which is the inverse of the X-centric geometric universe - */ - - return -ndy; + return ((int8_t) (grab_y() / _note_height)) - ((int8_t) (_drags->current_pointer_y() / _note_height)); } void @@ -3922,11 +3882,11 @@ NoteDrag::motion (GdkEvent *, bool) { /* Total change in x and y since the start of the drag */ frameoffset_t const dx = total_dx (); - int8_t const dy = -total_dy (); + int8_t const dy = total_dy (); /* Now work out what we have to do to the note canvas items to set this new drag delta */ double const tdx = _editor->frame_to_unit (dx) - _cumulative_dx; - double const tdy = dy * _note_height - _cumulative_dy; + double const tdy = -dy * _note_height - _cumulative_dy; if (tdx || tdy) { _cumulative_dx += tdx; @@ -3936,9 +3896,17 @@ NoteDrag::motion (GdkEvent *, bool) _region->move_selection (tdx, tdy, note_delta); + /* the new note value may be the same as the old one, but we + * don't know what that means because the selection may have + * involved more than one note and we might be doing something + * odd with them. so show the note value anyway, always. + */ + char buf[12]; - snprintf (buf, sizeof (buf), "%s (%d)", Evoral::midi_note_name (_primary->note()->note() + note_delta).c_str(), - (int) floor (_primary->note()->note() + note_delta)); + uint8_t new_note = min (max (_primary->note()->note() + note_delta, 0), 127); + + snprintf (buf, sizeof (buf), "%s (%d)", Evoral::midi_note_name (new_note).c_str(), + (int) floor (new_note)); show_verbose_cursor_text (buf); } @@ -4234,7 +4202,7 @@ PatchChangeDrag::finished (GdkEvent* ev, bool movement_occurred) _region_view->move_patch_change ( *_patch_change, - _region_view->frames_to_beats (f - r->position() - r->start()) + _region_view->region_frames_to_region_beats (f - r->position() - r->start()) ); } @@ -4248,6 +4216,6 @@ void PatchChangeDrag::setup_pointer_frame_offset () { boost::shared_ptr region = _region_view->region (); - _pointer_frame_offset = raw_grab_frame() - _region_view->beats_to_frames (_patch_change->patch()->time()) - region->position() + region->start(); + _pointer_frame_offset = raw_grab_frame() - _region_view->source_beats_to_absolute_frames (_patch_change->patch()->time()); }