+
+NoteDrag::NoteDrag (Editor* e, ArdourCanvas::Item* i)
+ : Drag (e, i)
+{
+ ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
+ region = &cnote->region_view();
+}
+
+void
+NoteDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
+{
+ Drag::start_grab (event);
+
+ drag_delta_x = 0;
+ drag_delta_note = 0;
+
+ double event_x;
+ double event_y;
+
+ event_x = _current_pointer_x;
+ event_y = _current_pointer_y;
+
+ _item->property_parent().get_value()->w2i(event_x, event_y);
+
+ last_x = region->snap_to_pixel(event_x);
+ last_y = event_y;
+
+ ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
+ region->note_selected (cnote, true);
+}
+
+void
+NoteDrag::motion (GdkEvent* ev, bool)
+{
+ MidiStreamView* streamview = region->midi_stream_view();
+ double event_x;
+ double event_y;
+
+ event_x = _current_pointer_x;
+ event_y = _current_pointer_y;
+
+ _item->property_parent().get_value()->w2i(event_x, event_y);
+
+ event_x = region->snap_to_pixel(event_x);
+
+ double dx = event_x - last_x;
+ double dy = event_y - last_y;
+ last_x = event_x;
+
+ drag_delta_x += dx;
+
+ // Snap to note rows
+
+ if (abs (dy) < streamview->note_height()) {
+ dy = 0.0;
+ } else {
+ int8_t this_delta_note;
+ if (dy > 0) {
+ this_delta_note = (int8_t)ceil(dy / streamview->note_height() / 2.0);
+ } else {
+ this_delta_note = (int8_t)floor(dy / streamview->note_height() / 2.0);
+ }
+ drag_delta_note -= this_delta_note;
+ dy = streamview->note_height() * this_delta_note;
+ last_y = last_y + dy;
+ }
+
+ region->move_selection (dx, dy);
+}
+
+void
+NoteDrag::finished (GdkEvent* ev, bool moved)
+{
+ ArdourCanvas::CanvasNote* cnote = dynamic_cast<ArdourCanvas::CanvasNote*>(_item);
+
+ if (!moved) {
+ if (_editor->current_mouse_mode() == Editing::MouseObject) {
+
+ bool select_mod = (ev->motion.state & (Keyboard::PrimaryModifier | Keyboard::SecondaryModifier));
+
+ if (cnote->selected()) {
+ region->note_deselected (cnote, select_mod);
+ } else {
+ bool extend = Keyboard::modifier_state_equals (ev->button.state, Keyboard::TertiaryModifier);
+ bool add = Keyboard::modifier_state_equals (ev->button.state, Keyboard::PrimaryModifier);
+
+ if (!extend && !add && region->selection_size() > 1) {
+ region->unique_select(cnote);
+ } else {
+ region->note_selected (cnote, (extend ? true : add), extend);
+ }
+ }
+ }
+ } else {
+ region->note_dropped (cnote, drag_delta_x, drag_delta_note);
+ }
+}