add back-pointer to TempoMap from points, and push dirty=true into map
[ardour.git] / gtk2_ardour / midi_region_view.cc
index f9c088448ede5fc11560edcb477aac0fa2171555..a8124a9675196d2d714806ead6f2ba956fb7b62e 100644 (file)
@@ -956,7 +956,6 @@ MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, ui
 
        start_note_diff_command(_("add note"));
 
-       clear_editor_note_selection ();
        note_diff_add_note (new_note, true, false);
 
        apply_diff();
@@ -1094,6 +1093,7 @@ MidiRegionView::abort_command()
 {
        delete _note_diff_command;
        _note_diff_command = 0;
+       trackview.editor().abort_reversible_command();
        clear_editor_note_selection();
 }
 
@@ -1424,11 +1424,13 @@ MidiRegionView::display_sysexes()
                }
 
                // Show unless message is beyond the region bounds
-               if (time - _region->start() >= _region->length() || time < _region->start()) {
-                       sysex->hide();
-               } else {
-                       sysex->show();
-               }
+// XXX REQUIRES APPROPRIATE OPERATORS FOR Evoral::Beats and framepos? say what?
+#warning paul fix this
+//             if (time - _region->start() >= _region->length() || time < _region->start()) {
+//                     sysex->hide();
+//             } else {
+//                     sysex->show();
+//             }
        }
 }
 
@@ -2082,7 +2084,6 @@ MidiRegionView::change_patch_change (MidiModel::PatchChangePtr old_change, const
 void
 MidiRegionView::add_patch_change (framecnt_t t, Evoral::PatchChange<Evoral::Beats> const & patch)
 {
-       MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
        string name = _("add patch change");
 
        trackview.editor().begin_reversible_command (name);
@@ -2090,7 +2091,7 @@ MidiRegionView::add_patch_change (framecnt_t t, Evoral::PatchChange<Evoral::Beat
        c->add (MidiModel::PatchChangePtr (
                        new Evoral::PatchChange<Evoral::Beats> (
                                absolute_frames_to_source_beats (_region->position() + t),
-                               mtv->get_channel_for_add(), patch.program(), patch.bank()
+                               patch.channel(), patch.program(), patch.bank()
                                )
                        )
                );
@@ -2396,7 +2397,7 @@ MidiRegionView::note_selected (NoteBase* ev, bool add, bool extend)
        } else {
                /* find end of latest note selected, select all between that and the start of "ev" */
 
-               Evoral::Beats earliest = Evoral::MaxBeats;
+               Evoral::Beats earliest = std::numeric_limits<Evoral::Beats>::max();
                Evoral::Beats latest   = Evoral::Beats();
 
                for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
@@ -2552,7 +2553,7 @@ MidiRegionView::add_to_selection (NoteBase* ev)
 Evoral::Beats
 MidiRegionView::earliest_in_selection ()
 {
-       Evoral::Beats earliest = Evoral::MaxBeats;
+       Evoral::Beats earliest = std::numeric_limits<Evoral::Beats>::max();
 
        for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
                if ((*i)->note()->time() < earliest) {
@@ -2578,10 +2579,29 @@ MidiRegionView::move_selection(double dx_qn, double dy, double cumulative_dy)
                        to_play.push_back (n->note());
                }
                double const note_time_qn = session_relative_qn (n->note()->time().to_double());
-               double const dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn))
-                       - n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
+               double dx = 0.0;
+               if (midi_view()->note_mode() == Sustained) {
+                       dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn))
+                               - n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
+               } else {
+                       /* Hit::x0() is offset by _position.x, unlike Note::x0() */
+                       Hit* hit = dynamic_cast<Hit*>(n);
+                       if (hit) {
+                               dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn))
+                                       - n->item()->item_to_canvas (ArdourCanvas::Duple (((hit->x0() + hit->x1()) / 2.0) - hit->position().x, 0)).x;
+                       }
+               }
 
                (*i)->move_event(dx, dy);
+
+               /* update length */
+               if (midi_view()->note_mode() == Sustained) {
+                       Note* sus = dynamic_cast<Note*> (*i);
+                       double const len_dx = editor->sample_to_pixel_unrounded (
+                               tmap.frame_at_quarter_note (note_time_qn + dx_qn + n->note()->length().to_double()));
+
+                       sus->set_x1 (n->item()->canvas_to_item (ArdourCanvas::Duple (len_dx, 0)).x);
+               }
        }
 
        if (dy && !_selection.empty() && !_no_sound_notes && UIConfiguration::instance().get_sound_midi_notes()) {
@@ -2656,10 +2676,27 @@ MidiRegionView::move_copies (double dx_qn, double dy, double cumulative_dy)
                        to_play.push_back (n->note());
                }
                double const note_time_qn = session_relative_qn (n->note()->time().to_double());
-               double const dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn))
-                       - n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
+               double dx = 0.0;
+               if (midi_view()->note_mode() == Sustained) {
+                       dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn))
+                               - n->item()->item_to_canvas (ArdourCanvas::Duple (n->x0(), 0)).x;
+               } else {
+                       Hit* hit = dynamic_cast<Hit*>(n);
+                       if (hit) {
+                               dx = editor->sample_to_pixel_unrounded (tmap.frame_at_quarter_note (note_time_qn + dx_qn))
+                                       - n->item()->item_to_canvas (ArdourCanvas::Duple (((hit->x0() + hit->x1()) / 2.0) - hit->position().x, 0)).x;
+                       }
+               }
 
                (*i)->move_event(dx, dy);
+
+               if (midi_view()->note_mode() == Sustained) {
+                       Note* sus = dynamic_cast<Note*> (*i);
+                       double const len_dx = editor->sample_to_pixel_unrounded (
+                               tmap.frame_at_quarter_note (note_time_qn + dx_qn + n->note()->length().to_double()));
+
+                       sus->set_x1 (n->item()->canvas_to_item (ArdourCanvas::Duple (len_dx, 0)).x);
+               }
        }
 
        if (dy && !_copy_drag_events.empty() && !_no_sound_notes && UIConfiguration::instance().get_sound_midi_notes()) {
@@ -2720,7 +2757,7 @@ MidiRegionView::note_dropped(NoteBase *, double d_qn, int8_t dnote, bool copy)
 
                for (Selection::iterator i = _selection.begin(); i != _selection.end() ; ++i) {
 
-                       Evoral::Beats new_time = Evoral::Beats (max ((*i)->note()->time().to_double() + d_qn, midi_region()->start_beats()));
+                       Evoral::Beats new_time = Evoral::Beats ((*i)->note()->time().to_double() + d_qn);
 
                        if (new_time < 0) {
                                continue;
@@ -2759,7 +2796,7 @@ MidiRegionView::note_dropped(NoteBase *, double d_qn, int8_t dnote, bool copy)
                for (CopyDragEvents::iterator i = _copy_drag_events.begin(); i != _copy_drag_events.end() ; ++i) {
 
                        /* update time */
-                       Evoral::Beats new_time = Evoral::Beats (max ((*i)->note()->time().to_double() + d_qn, midi_region()->start_beats()));
+                       Evoral::Beats new_time = Evoral::Beats ((*i)->note()->time().to_double() + d_qn);
 
                        if (new_time < 0) {
                                continue;