+
+PatchChangeDrag::PatchChangeDrag (Editor* e, CanvasPatchChange* i, MidiRegionView* r)
+ : Drag (e, i)
+ , _region_view (r)
+ , _patch_change (i)
+ , _cumulative_dx (0)
+{
+ DEBUG_TRACE (DEBUG::Drags, "New PatchChangeDrag\n");
+}
+
+void
+PatchChangeDrag::motion (GdkEvent* ev, bool)
+{
+ framepos_t f = adjusted_current_frame (ev);
+ boost::shared_ptr<Region> r = _region_view->region ();
+ f = max (f, r->position ());
+ f = min (f, r->last_frame ());
+
+ framecnt_t const dxf = f - grab_frame();
+ double const dxu = _editor->frame_to_unit (dxf);
+ _patch_change->move (dxu - _cumulative_dx, 0);
+ _cumulative_dx = dxu;
+}
+
+void
+PatchChangeDrag::finished (GdkEvent* ev, bool movement_occurred)
+{
+ if (!movement_occurred) {
+ return;
+ }
+
+ boost::shared_ptr<Region> r (_region_view->region ());
+
+ framepos_t f = adjusted_current_frame (ev);
+ f = max (f, r->position ());
+ f = min (f, r->last_frame ());
+
+ _region_view->move_patch_change (
+ *_patch_change,
+ _region_view->frames_to_beats (f - r->position() - r->start())
+ );
+}
+
+void
+PatchChangeDrag::aborted (bool)
+{
+ _patch_change->move (-_cumulative_dx, 0);
+}
+
+void
+PatchChangeDrag::setup_pointer_frame_offset ()
+{
+ boost::shared_ptr<Region> region = _region_view->region ();
+ _pointer_frame_offset = raw_grab_frame() - _region_view->beats_to_frames (_patch_change->patch()->time()) - region->position() + region->start();
+}
+